Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_expr_sqlite3FindInIndex.c136 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Helper: create an integer constant expression with given string value */7static Expr* makeIntExpr(sqlite3 *db, const char *z){8  return sqlite3Expr(db, TK_INTEGER, z);9}10 11/* Helper: build an ExprList of integer constants from an array of string literals */12static ExprList* makeIntList(Parse *pParse, const char **vals, int n){13  ExprList *pList = 0;14  for(int i=0; i<n; i++){15    Expr *pItem = makeIntExpr(pParse->db, vals[i]);16    pList = sqlite3ExprListAppend(pParse, pList, pItem);17  }18  return pList;19}20 21/* Helper: build an IN expression with a scalar LHS and list RHS */22static Expr* makeInExprWithList(Parse *pParse, const char *lhsVal, const char **rhsVals, int nRhs){23  Expr *pLhs = makeIntExpr(pParse->db, lhsVal);24  Expr *pIn  = sqlite3ExprAlloc(pParse->db, TK_IN, 0, 0);25  pIn->pLeft = pLhs;26  pIn->x.pList = makeIntList(pParse, rhsVals, nRhs);27  /* Ensure the x union is interpreted as list (not select). Leaving flags as 0 is fine. */28  return pIn;29}30 31void setUp(void) {32  /* Setup code here, or leave empty */33}34 35void tearDown(void) {36  /* Cleanup code here, or leave empty */37}38 39/* Test: NOOP path when RHS is a list with <=2 entries and NOOP_OK is set. */40void test_sqlite3FindInIndex_noop_for_small_list_membership(void){41  sqlite3 *db = 0;42  TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));43 44  Parse pParse; memset(&pParse, 0, sizeof(pParse));45  pParse.db = db;46 47  const char *rhsVals[] = { "2", "3" };48  Expr *pIn = makeInExprWithList(&pParse, "1", rhsVals, 2);49 50  int aiMap[1] = { -1 };51  int prNull = 0xdeadbeef; /* should remain unchanged for NOOP */52  int iTab = -999;53  int inFlags = IN_INDEX_MEMBERSHIP | IN_INDEX_NOOP_OK;54 55  int nTab0 = pParse.nTab;56  int eType = sqlite3FindInIndex(&pParse, pIn, (u32)inFlags, &prNull, aiMap, &iTab);57 58  TEST_ASSERT_EQUAL_INT(IN_INDEX_NOOP, eType);59  TEST_ASSERT_EQUAL_INT(-1, iTab);60  TEST_ASSERT_EQUAL_INT(nTab0, pParse.nTab); /* allocation backed out */61  TEST_ASSERT_EQUAL_INT(0, aiMap[0]); /* default mapping applied */62  TEST_ASSERT_EQUAL_INT(0xdeadbeef, prNull); /* unchanged */63 64  sqlite3ExprDelete(db, pIn);65  sqlite3_close(db);66}67 68/* Test: EPH path for list RHS with membership (no NOOP_OK) should allocate a has-null register. */69void test_sqlite3FindInIndex_eph_membership_sets_hasnull_and_tab(void){70  sqlite3 *db = 0;71  TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));72 73  Parse pParse; memset(&pParse, 0, sizeof(pParse));74  pParse.db = db;75 76  const char *rhsVals[] = { "5", "6", "7" };77  Expr *pIn = makeInExprWithList(&pParse, "1", rhsVals, 3);78 79  int aiMap[1] = { -1 };80  int prNull = 0;81  int iTab = -999;82  int inFlags = IN_INDEX_MEMBERSHIP; /* NOOP_OK not set */83 84  int nTab0 = pParse.nTab;85  int nMem0 = pParse.nMem;86  int eType = sqlite3FindInIndex(&pParse, pIn, (u32)inFlags, &prNull, aiMap, &iTab);87 88  TEST_ASSERT_EQUAL_INT(IN_INDEX_EPH, eType);89  TEST_ASSERT_EQUAL_INT(nTab0, iTab);      /* first allocated cursor index */90  TEST_ASSERT_EQUAL_INT(nTab0 + 1, pParse.nTab); /* one cursor consumed */91  TEST_ASSERT_GREATER_THAN_INT(0, prNull); /* register allocated */92  TEST_ASSERT_EQUAL_INT(nMem0 + 1, pParse.nMem); /* one reg allocated */93  TEST_ASSERT_EQUAL_INT(0, aiMap[0]);94 95  sqlite3ExprDelete(db, pIn);96  sqlite3_close(db);97}98 99/* Test: EPH path for list RHS with IN_INDEX_LOOP should NOT allocate has-null register. */100void test_sqlite3FindInIndex_eph_loop_no_hasnull(void){101  sqlite3 *db = 0;102  TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));103 104  Parse pParse; memset(&pParse, 0, sizeof(pParse));105  pParse.db = db;106 107  const char *rhsVals[] = { "10", "20", "30" };108  Expr *pIn = makeInExprWithList(&pParse, "1", rhsVals, 3);109 110  int aiMap[1] = { -1 };111  int prNull = 12345; /* should remain unchanged */112  int iTab = -999;113  int inFlags = IN_INDEX_LOOP; /* Iterate over RHS members */114 115  int nTab0 = pParse.nTab;116  int nMem0 = pParse.nMem;117  int eType = sqlite3FindInIndex(&pParse, pIn, (u32)inFlags, &prNull, aiMap, &iTab);118 119  TEST_ASSERT_EQUAL_INT(IN_INDEX_EPH, eType);120  TEST_ASSERT_EQUAL_INT(nTab0, iTab);121  TEST_ASSERT_EQUAL_INT(nTab0 + 1, pParse.nTab);122  TEST_ASSERT_EQUAL_INT(12345, prNull); /* unchanged because LOOP path */123  TEST_ASSERT_EQUAL_INT(nMem0, pParse.nMem); /* no reg allocated for has-null */124  TEST_ASSERT_EQUAL_INT(0, aiMap[0]);125 126  sqlite3ExprDelete(db, pIn);127  sqlite3_close(db);128}129 130int main(void) {131  UNITY_BEGIN();132  RUN_TEST(test_sqlite3FindInIndex_noop_for_small_list_membership);133  RUN_TEST(test_sqlite3FindInIndex_eph_membership_sets_hasnull_and_tab);134  RUN_TEST(test_sqlite3FindInIndex_eph_loop_no_hasnull);135  return UNITY_END();136}