Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_build_resizeIndexObject.c287 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3 4#include <stdlib.h>5#include <string.h>6 7/* Wrapper for the static function under test (provided by the module) */8extern int test_resizeIndexObject(Parse *pParse, Index *pIdx, int N);9 10static const char *C_BIN   = "BINARY";11static const char *C_NOCASE= "NOCASE";12static const char *C_RTRIM = "RTRIM";13static const char *C_CUSTOM= "CUSTOM";14 15/* Unity fixtures */16void setUp(void) {17  /* no-op */18}19void tearDown(void) {20  /* no-op */21}22 23/* Helper to initialize an Index with given sizes and sample contents */24static void initIndexWithArrays(25  sqlite3 *db,26  Index *pIdx,27  int nCol,28  int nKeyCol29){30  memset(pIdx, 0, sizeof(*pIdx));31  pIdx->nColumn = (u16)nCol;32  pIdx->nKeyCol = (i16)nKeyCol;33  pIdx->isResized = 0;34 35  /* Allocate and populate arrays using the db allocator */36  const char **az = (const char**)sqlite3DbMallocZero(db, sizeof(char*)*nCol);37  LogEst *ar = (LogEst*)sqlite3DbMallocZero(db, sizeof(LogEst)*(nKeyCol+1));38  i16 *ac = (i16*)sqlite3DbMallocZero(db, sizeof(i16)*nCol);39  u8 *as = (u8*)sqlite3DbMallocZero(db, sizeof(u8)*nCol);40 41  /* Fill initial values deterministically */42  for(int i=0; i<nCol; i++){43    /* rotate through a few static collation strings */44    switch(i % 4){45      case 0: az[i] = C_BIN; break;46      case 1: az[i] = C_NOCASE; break;47      case 2: az[i] = C_RTRIM; break;48      default: az[i] = C_CUSTOM; break;49    }50    ac[i] = (i16)(10 + i);51    as[i] = (u8)(i & 1);52  }53  for(int i=0; i<=nKeyCol; i++){54    ar[i] = (LogEst)(100 + i);55  }56 57  pIdx->azColl = az;58  pIdx->aiRowLogEst = ar;59  pIdx->aiColumn = ac;60  pIdx->aSortOrder = as;61}62 63/* Helper to free initial arrays if they are still separate allocations */64static void freeInitialIndexArrays(sqlite3 *db, Index *pIdx,65                                   const char **azOrig,66                                   LogEst *arOrig,67                                   i16 *acOrig,68                                   u8 *asOrig){69  if(azOrig) sqlite3DbFree(db, (void*)azOrig);70  if(arOrig) sqlite3DbFree(db, (void*)arOrig);71  if(acOrig) sqlite3DbFree(db, (void*)acOrig);72  if(asOrig) sqlite3DbFree(db, (void*)asOrig);73}74 75/* Test 1: No-op when N <= nColumn */76void test_resizeIndexObject_noop_when_N_le_nColumn(void){77  sqlite3 *db = 0;78  Parse parse;79  memset(&parse, 0, sizeof(parse));80 81  TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));82  parse.db = db;83 84  Index idx;85  initIndexWithArrays(db, &idx, /*nCol*/3, /*nKeyCol*/3);86 87  /* Save original pointers and snapshot of contents */88  const char **azOrig = idx.azColl;89  LogEst *arOrig = idx.aiRowLogEst;90  i16 *acOrig = idx.aiColumn;91  u8 *asOrig = idx.aSortOrder;92 93  /* Keep copies of values for verification */94  const char *azSave[3] = { azOrig[0], azOrig[1], azOrig[2] };95  LogEst arSave[4] = { arOrig[0], arOrig[1], arOrig[2], arOrig[3] };96  i16 acSave[3] = { acOrig[0], acOrig[1], acOrig[2] };97  u8  asSave[3] = { asOrig[0], asOrig[1], asOrig[2] };98 99  int rc = test_resizeIndexObject(&parse, &idx, /*N*/3);100  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);101 102  /* Verify no changes */103  TEST_ASSERT_EQUAL_UINT16(3, idx.nColumn);104  TEST_ASSERT_EQUAL_INT(0, idx.isResized);105  TEST_ASSERT_EQUAL_PTR(azOrig, idx.azColl);106  TEST_ASSERT_EQUAL_PTR(arOrig, idx.aiRowLogEst);107  TEST_ASSERT_EQUAL_PTR(acOrig, idx.aiColumn);108  TEST_ASSERT_EQUAL_PTR(asOrig, idx.aSortOrder);109 110  TEST_ASSERT_EQUAL_PTR(azSave[0], idx.azColl[0]);111  TEST_ASSERT_EQUAL_PTR(azSave[1], idx.azColl[1]);112  TEST_ASSERT_EQUAL_PTR(azSave[2], idx.azColl[2]);113 114  TEST_ASSERT_EQUAL_INT(arSave[0], idx.aiRowLogEst[0]);115  TEST_ASSERT_EQUAL_INT(arSave[1], idx.aiRowLogEst[1]);116  TEST_ASSERT_EQUAL_INT(arSave[2], idx.aiRowLogEst[2]);117  TEST_ASSERT_EQUAL_INT(arSave[3], idx.aiRowLogEst[3]);118 119  TEST_ASSERT_EQUAL_INT(acSave[0], idx.aiColumn[0]);120  TEST_ASSERT_EQUAL_INT(acSave[1], idx.aiColumn[1]);121  TEST_ASSERT_EQUAL_INT(acSave[2], idx.aiColumn[2]);122 123  TEST_ASSERT_EQUAL_INT(asSave[0], idx.aSortOrder[0]);124  TEST_ASSERT_EQUAL_INT(asSave[1], idx.aSortOrder[1]);125  TEST_ASSERT_EQUAL_INT(asSave[2], idx.aSortOrder[2]);126 127  /* Cleanup */128  freeInitialIndexArrays(db, &idx, azOrig, arOrig, acOrig, asOrig);129  sqlite3_close(db);130}131 132/* Test 2: Grow to larger N, with nKeyCol == nColumn.133   Validate copy, zero-initialization, pointer layout and flags. */134void test_resizeIndexObject_grow_and_layout_and_zeroing(void){135  sqlite3 *db = 0;136  Parse parse;137  memset(&parse, 0, sizeof(parse));138 139  TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));140  parse.db = db;141 142  Index idx;143  initIndexWithArrays(db, &idx, /*nCol*/2, /*nKeyCol*/2);144 145  const char **azOrig = idx.azColl;146  LogEst *arOrig = idx.aiRowLogEst;147  i16 *acOrig = idx.aiColumn;148  u8 *asOrig = idx.aSortOrder;149 150  /* Save value snapshots */151  const char *azSave[2] = { azOrig[0], azOrig[1] };152  LogEst arSave[3] = { arOrig[0], arOrig[1], arOrig[2] };153  i16 acSave[2] = { acOrig[0], acOrig[1] };154  u8  asSave[2] = { asOrig[0], asOrig[1] };155 156  int N = 5; /* Ensure N > nColumn and N > nKeyCol+1 to check zeroing */157  int rc = test_resizeIndexObject(&parse, &idx, N);158  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);159 160  /* Flags and sizes */161  TEST_ASSERT_EQUAL_UINT16(N, idx.nColumn);162  TEST_ASSERT_EQUAL_INT(1, idx.isResized);163 164  /* Pointers should change from originals */165  TEST_ASSERT_NOT_EQUAL_PTR(azOrig, idx.azColl);166  TEST_ASSERT_NOT_EQUAL_PTR(arOrig, idx.aiRowLogEst);167  TEST_ASSERT_NOT_EQUAL_PTR(acOrig, idx.aiColumn);168  TEST_ASSERT_NOT_EQUAL_PTR(asOrig, idx.aSortOrder);169 170  /* Verify exact contiguous layout as implemented */171  char *base = (char*)idx.azColl;172  TEST_ASSERT_EQUAL_PTR(base + (ptrdiff_t)(sizeof(char*)*N), (char*)idx.aiRowLogEst);173  TEST_ASSERT_EQUAL_PTR(base + (ptrdiff_t)(sizeof(char*)*N + sizeof(LogEst)*N),174                       (char*)idx.aiColumn);175  TEST_ASSERT_EQUAL_PTR(base + (ptrdiff_t)(sizeof(char*)*N + sizeof(LogEst)*N + sizeof(i16)*N),176                       (char*)idx.aSortOrder);177 178  /* Verify preserved values */179  TEST_ASSERT_EQUAL_PTR(azSave[0], idx.azColl[0]);180  TEST_ASSERT_EQUAL_PTR(azSave[1], idx.azColl[1]);181 182  TEST_ASSERT_EQUAL_INT(arSave[0], idx.aiRowLogEst[0]);183  TEST_ASSERT_EQUAL_INT(arSave[1], idx.aiRowLogEst[1]);184  TEST_ASSERT_EQUAL_INT(arSave[2], idx.aiRowLogEst[2]);185 186  TEST_ASSERT_EQUAL_INT(acSave[0], idx.aiColumn[0]);187  TEST_ASSERT_EQUAL_INT(acSave[1], idx.aiColumn[1]);188 189  TEST_ASSERT_EQUAL_INT(asSave[0], idx.aSortOrder[0]);190  TEST_ASSERT_EQUAL_INT(asSave[1], idx.aSortOrder[1]);191 192  /* Verify zero-initialization of new slots:193     - azColl[2..4] should be NULL194     - aiRowLogEst[3..4] should be 0195     - aiColumn[2..4] should be 0196     - aSortOrder[2..4] should be 0197  */198  for(int i=2; i<N; i++){199    TEST_ASSERT_NULL(idx.azColl[i]);200    TEST_ASSERT_EQUAL_INT(0, idx.aiColumn[i]);201    TEST_ASSERT_EQUAL_INT(0, idx.aSortOrder[i]);202  }203  for(int i=3; i<N; i++){204    TEST_ASSERT_EQUAL_INT(0, idx.aiRowLogEst[i]);205  }206 207  /* Cleanup:208     - Free original separate allocations209     - Free the single contiguous block now referenced by idx.azColl210  */211  freeInitialIndexArrays(db, &idx, azOrig, arOrig, acOrig, asOrig);212  sqlite3DbFree(db, (void*)idx.azColl);213  sqlite3_close(db);214}215 216/* Test 3: Grow when nKeyCol < nColumn, ensuring aiRowLogEst copies nKeyCol+1217   elements and remaining slots are zeroed. */218void test_resizeIndexObject_grow_with_fewer_keycols(void){219  sqlite3 *db = 0;220  Parse parse;221  memset(&parse, 0, sizeof(parse));222 223  TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));224  parse.db = db;225 226  /* nColumn = 3, nKeyCol = 2 */227  Index idx;228  initIndexWithArrays(db, &idx, /*nCol*/3, /*nKeyCol*/2);229 230  const char **azOrig = idx.azColl;231  LogEst *arOrig = idx.aiRowLogEst;232  i16 *acOrig = idx.aiColumn;233  u8 *asOrig = idx.aSortOrder;234 235  /* Save original values */236  const char *azSave[3] = { azOrig[0], azOrig[1], azOrig[2] };237  LogEst arSave[3] = { arOrig[0], arOrig[1], arOrig[2] }; /* nKeyCol+1 == 3 */238  i16 acSave[3] = { acOrig[0], acOrig[1], acOrig[2] };239  u8  asSave[3] = { asOrig[0], asOrig[1], asOrig[2] };240 241  int N = 4; /* Ensure N > nColumn and N >= nKeyCol+1 */242  int rc = test_resizeIndexObject(&parse, &idx, N);243  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);244 245  TEST_ASSERT_EQUAL_UINT16(N, idx.nColumn);246  TEST_ASSERT_EQUAL_INT(1, idx.isResized);247 248  /* Check preserved values */249  TEST_ASSERT_EQUAL_PTR(azSave[0], idx.azColl[0]);250  TEST_ASSERT_EQUAL_PTR(azSave[1], idx.azColl[1]);251  TEST_ASSERT_EQUAL_PTR(azSave[2], idx.azColl[2]);252 253  TEST_ASSERT_EQUAL_INT(arSave[0], idx.aiRowLogEst[0]);254  TEST_ASSERT_EQUAL_INT(arSave[1], idx.aiRowLogEst[1]);255  TEST_ASSERT_EQUAL_INT(arSave[2], idx.aiRowLogEst[2]);256 257  TEST_ASSERT_EQUAL_INT(acSave[0], idx.aiColumn[0]);258  TEST_ASSERT_EQUAL_INT(acSave[1], idx.aiColumn[1]);259  TEST_ASSERT_EQUAL_INT(acSave[2], idx.aiColumn[2]);260 261  TEST_ASSERT_EQUAL_INT(asSave[0], idx.aSortOrder[0]);262  TEST_ASSERT_EQUAL_INT(asSave[1], idx.aSortOrder[1]);263  TEST_ASSERT_EQUAL_INT(asSave[2], idx.aSortOrder[2]);264 265  /* Zero-initialization for new slots (index 3) */266  TEST_ASSERT_NULL(idx.azColl[3]);267  TEST_ASSERT_EQUAL_INT(0, idx.aiColumn[3]);268  TEST_ASSERT_EQUAL_INT(0, idx.aSortOrder[3]);269 270  /* aiRowLogEst has size N; slots beyond nKeyCol+1 (i.e., index >= 3) should be 0 */271  for(int i=3; i<N; i++){272    TEST_ASSERT_EQUAL_INT(0, idx.aiRowLogEst[i]);273  }274 275  /* Free allocations */276  freeInitialIndexArrays(db, &idx, azOrig, arOrig, acOrig, asOrig);277  sqlite3DbFree(db, (void*)idx.azColl);278  sqlite3_close(db);279}280 281int main(void){282  UNITY_BEGIN();283  RUN_TEST(test_resizeIndexObject_noop_when_N_le_nColumn);284  RUN_TEST(test_resizeIndexObject_grow_and_layout_and_zeroing);285  RUN_TEST(test_resizeIndexObject_grow_with_fewer_keycols);286  return UNITY_END();287}