Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_delete_sqlite3GenerateIndexKey.c240 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4 5/* Unity setup/teardown */6void setUp(void) { }7void tearDown(void) { }8 9/* Helper: open a test database */10static sqlite3* openTestDb(void){11  sqlite3 *db = 0;12  int rc = sqlite3_open(":memory:", &db);13  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);14  TEST_ASSERT_NOT_NULL(db);15  return db;16}17 18/* Helper: create and bind a VDBE to a Parse */19static Vdbe* makeVdbe(sqlite3 *db, Parse *pParse){20  memset(pParse, 0, sizeof(*pParse));21  pParse->db = db;22  Vdbe *v = sqlite3VdbeCreate(db);23  TEST_ASSERT_NOT_NULL(v);24  pParse->pVdbe = v;25  return v;26}27 28/* Helper: create a minimal Table with nCol columns */29static Table* makeTable(sqlite3 *db, int nCol){30  Table *pTab = (Table*)sqlite3DbMallocZero(db, sizeof(Table));31  TEST_ASSERT_NOT_NULL(pTab);32  pTab->nCol = nCol;33  pTab->tabFlags = 0;34  pTab->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nCol);35  TEST_ASSERT_NOT_NULL(pTab->aCol);36  /* Column details are not needed for OP_Column generation here */37  return pTab;38}39 40/* Helper: create an Index with given column list on pTab */41static Index* makeIndex(sqlite3 *db, Table *pTab, int nColumn, int nKeyCol,42                        int uniqNotNull, const int *aiCols){43  Index *pIdx = (Index*)sqlite3DbMallocZero(db, sizeof(Index));44  TEST_ASSERT_NOT_NULL(pIdx);45  pIdx->pTable = pTab;46  pIdx->nColumn = (i16)nColumn;47  pIdx->nKeyCol = (i16)nKeyCol;48  pIdx->uniqNotNull = (u8)(uniqNotNull ? 1 : 0);49  pIdx->aiColumn = (i16*)sqlite3DbMallocZero(db, sizeof(i16)*nColumn);50  TEST_ASSERT_NOT_NULL(pIdx->aiColumn);51  for(int i=0;i<nColumn;i++){52    pIdx->aiColumn[i] = (i16)aiCols[i];53  }54  /* pPartIdxWhere left NULL unless explicitly set in test */55  return pIdx;56}57 58/* Helper: free Index (optionally also free the attached Table) */59static void freeIndexAndMaybeTable(sqlite3 *db, Index *pIdx, int freeTable){60  if( pIdx ){61    Table *pTab = pIdx->pTable;62    if( pIdx->aiColumn ) sqlite3DbFree(db, pIdx->aiColumn);63    sqlite3DbFree(db, pIdx);64    if( freeTable && pTab ){65      if( pTab->aCol ) sqlite3DbFree(db, pTab->aCol);66      sqlite3DbFree(db, pTab);67    }68  }69}70 71/* Helper: count number of occurrences of a specific opcode */72static int countOpcode(Vdbe *v, int opcode){73  int n = sqlite3VdbeCurrentAddr(v);74  int cnt = 0;75  for(int i=0; i<n; i++){76    VdbeOp *op = sqlite3VdbeGetOp(v, i);77    if( op && op->opcode==opcode ) cnt++;78  }79  return cnt;80}81 82/* Test 1: Basic generation with OP_MakeRecord and full column load */83void test_sqlite3GenerateIndexKey_basic_make_record(void){84  sqlite3 *db = openTestDb();85  Parse parse;86  Vdbe *v = makeVdbe(db, &parse);87 88  Table *pTab = makeTable(db, 3);89  int cols[] = {0,1,2};90  Index *pIdx = makeIndex(db, pTab, 3, 3, 0, cols);91 92  int regOut = 7;93  int regBase = sqlite3GenerateIndexKey(&parse, pIdx, 2, regOut, 0, NULL, NULL, 0);94 95  TEST_ASSERT_TRUE(regBase > 0);96  TEST_ASSERT_EQUAL_INT(3, countOpcode(v, OP_Column));97 98  int nOp = sqlite3VdbeCurrentAddr(v);99  TEST_ASSERT_TRUE(nOp > 0);100  VdbeOp *last = sqlite3VdbeGetOp(v, nOp-1);101  TEST_ASSERT_NOT_NULL(last);102  TEST_ASSERT_EQUAL_INT(OP_MakeRecord, last->opcode);103  TEST_ASSERT_EQUAL_INT(regBase, last->p1);104  TEST_ASSERT_EQUAL_INT(3, last->p2);105  TEST_ASSERT_EQUAL_INT(regOut, last->p3);106 107  sqlite3VdbeDelete(v);108  freeIndexAndMaybeTable(db, pIdx, 1);109  sqlite3_close(db);110}111 112/* Test 2: prefixOnly with uniqNotNull==true limits to nKeyCol columns */113void test_sqlite3GenerateIndexKey_prefixOnly_uniqNotNull(void){114  sqlite3 *db = openTestDb();115  Parse parse;116  Vdbe *v = makeVdbe(db, &parse);117 118  Table *pTab = makeTable(db, 3);119  int cols[] = {0,1,2};120  Index *pIdx = makeIndex(db, pTab, 3, 2, 1, cols); /* uniqNotNull=1, nKeyCol=2 */121 122  int regOut = 3;123  int regBase = sqlite3GenerateIndexKey(&parse, pIdx, 1, regOut, 1, NULL, NULL, 0);124 125  TEST_ASSERT_TRUE(regBase > 0);126  TEST_ASSERT_EQUAL_INT(2, countOpcode(v, OP_Column));127 128  int nOp = sqlite3VdbeCurrentAddr(v);129  VdbeOp *last = sqlite3VdbeGetOp(v, nOp-1);130  TEST_ASSERT_NOT_NULL(last);131  TEST_ASSERT_EQUAL_INT(OP_MakeRecord, last->opcode);132  TEST_ASSERT_EQUAL_INT(2, last->p2);133  TEST_ASSERT_EQUAL_INT(regOut, last->p3);134 135  sqlite3VdbeDelete(v);136  freeIndexAndMaybeTable(db, pIdx, 1);137  sqlite3_close(db);138}139 140/* Test 3: No OP_MakeRecord when regOut==0 */141void test_sqlite3GenerateIndexKey_no_make_record_when_regOut_zero(void){142  sqlite3 *db = openTestDb();143  Parse parse;144  Vdbe *v = makeVdbe(db, &parse);145 146  Table *pTab = makeTable(db, 2);147  int cols[] = {0,1};148  Index *pIdx = makeIndex(db, pTab, 2, 2, 0, cols);149 150  (void)sqlite3GenerateIndexKey(&parse, pIdx, 0, 0, 0, NULL, NULL, 0);151 152  TEST_ASSERT_EQUAL_INT(0, countOpcode(v, OP_MakeRecord));153  TEST_ASSERT_EQUAL_INT(2, countOpcode(v, OP_Column));154 155  sqlite3VdbeDelete(v);156  freeIndexAndMaybeTable(db, pIdx, 1);157  sqlite3_close(db);158}159 160/* Test 4: pPrior optimization skips identical columns when regPrior==regBase */161void test_sqlite3GenerateIndexKey_skip_with_pPrior_same_columns(void){162  sqlite3 *db = openTestDb();163  Parse parse;164  Vdbe *v = makeVdbe(db, &parse);165 166  Table *pTab = makeTable(db, 3);167  int cols[] = {0,1,2};168  Index *pPrior = makeIndex(db, pTab, 3, 3, 0, cols);169  Index *pIdx   = makeIndex(db, pTab, 3, 3, 0, cols); /* identical columns */170 171  /* Ensure regPrior matches the expected first temp register base (likely 1) */172  int regPrior = 1;173  (void)sqlite3GenerateIndexKey(&parse, pIdx, 0, 0, 0, NULL, pPrior, regPrior);174 175  /* All columns should be skipped because pPrior matches and regPrior==regBase */176  TEST_ASSERT_EQUAL_INT(0, countOpcode(v, OP_Column));177  TEST_ASSERT_EQUAL_INT(0, countOpcode(v, OP_MakeRecord));178 179  sqlite3VdbeDelete(v);180  /* Free both indices; table only once */181  freeIndexAndMaybeTable(db, pPrior, 0);182  freeIndexAndMaybeTable(db, pIdx, 1);183  sqlite3_close(db);184}185 186/* Test 5: pPrior ignored when regPrior != regBase (all columns loaded) */187void test_sqlite3GenerateIndexKey_pPrior_ignored_when_reg_base_differs(void){188  sqlite3 *db = openTestDb();189  Parse parse;190  Vdbe *v = makeVdbe(db, &parse);191 192  Table *pTab = makeTable(db, 3);193  int cols[] = {0,1,2};194  Index *pPrior = makeIndex(db, pTab, 3, 3, 0, cols);195  Index *pIdx   = makeIndex(db, pTab, 3, 3, 0, cols);196 197  int regPrior = 999; /* Mismatch forces pPrior to be ignored */198  (void)sqlite3GenerateIndexKey(&parse, pIdx, 0, 0, 0, NULL, pPrior, regPrior);199 200  TEST_ASSERT_EQUAL_INT(3, countOpcode(v, OP_Column));201  TEST_ASSERT_EQUAL_INT(0, countOpcode(v, OP_MakeRecord));202 203  sqlite3VdbeDelete(v);204  freeIndexAndMaybeTable(db, pPrior, 0);205  freeIndexAndMaybeTable(db, pIdx, 1);206  sqlite3_close(db);207}208 209/* Test 6: piPartIdxLabel set to 0 when pPartIdxWhere==NULL */210void test_sqlite3GenerateIndexKey_piPartIdxLabel_zero_when_no_partial_index(void){211  sqlite3 *db = openTestDb();212  Parse parse;213  Vdbe *v = makeVdbe(db, &parse);214 215  Table *pTab = makeTable(db, 1);216  int cols[] = {0};217  Index *pIdx = makeIndex(db, pTab, 1, 1, 0, cols);218  /* Ensure no partial-index WHERE is set */219  TEST_ASSERT_NULL(pIdx->pPartIdxWhere);220 221  int label = -1;222  (void)sqlite3GenerateIndexKey(&parse, pIdx, 0, 0, 0, &label, NULL, 0);223 224  TEST_ASSERT_EQUAL_INT(0, label);225 226  sqlite3VdbeDelete(v);227  freeIndexAndMaybeTable(db, pIdx, 1);228  sqlite3_close(db);229}230 231int main(void){232  UNITY_BEGIN();233  RUN_TEST(test_sqlite3GenerateIndexKey_basic_make_record);234  RUN_TEST(test_sqlite3GenerateIndexKey_prefixOnly_uniqNotNull);235  RUN_TEST(test_sqlite3GenerateIndexKey_no_make_record_when_regOut_zero);236  RUN_TEST(test_sqlite3GenerateIndexKey_skip_with_pPrior_same_columns);237  RUN_TEST(test_sqlite3GenerateIndexKey_pPrior_ignored_when_reg_base_differs);238  RUN_TEST(test_sqlite3GenerateIndexKey_piPartIdxLabel_zero_when_no_partial_index);239  return UNITY_END();240}