AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Prototypes for the wrapper added in the source */7int test_exprIdxCover(Walker *pWalker, Expr *pExpr);8 9void setUp(void) {10 /* Setup code here, or leave empty */11}12 13void tearDown(void) {14 /* Cleanup code here, or leave empty */15}16 17/* Helper to initialize an Index and IdxCover with specified columns and cursor */18static void initIndexAndCover(Index *pIdx, struct IdxCover *pCov, int iCur, i16 *aiCols, int nCols){19 memset(pIdx, 0, sizeof(*pIdx));20 pIdx->nColumn = (i16)nCols;21 pIdx->aiColumn = aiCols;22 memset(pCov, 0, sizeof(*pCov));23 pCov->pIdx = pIdx;24 pCov->iCur = iCur;25}26 27/* Helper to create a TK_COLUMN Expr */28static void initColumnExpr(Expr *pExpr, int iTable, int iColumn){29 memset(pExpr, 0, sizeof(*pExpr));30 pExpr->op = TK_COLUMN;31 pExpr->iTable = iTable;32 pExpr->iColumn = iColumn;33}34 35/* Non-column expression helper */36static void initNonColumnExpr(Expr *pExpr){37 memset(pExpr, 0, sizeof(*pExpr));38 pExpr->op = TK_INTEGER; /* Any non-TK_COLUMN op */39}40 41void test_exprIdxCover_returns_continue_when_column_covered(void) {42 /* Index covers columns {0,1,2}; expression references column 1 on matching cursor */43 i16 aiCols[3] = {0, 1, 2};44 Index idx;45 struct IdxCover cov;46 Walker w;47 Expr e;48 49 initIndexAndCover(&idx, &cov, /*iCur*/7, aiCols, 3);50 memset(&w, 0, sizeof(w));51 w.u.pIdxCover = &cov;52 w.eCode = 0;53 54 initColumnExpr(&e, /*iTable*/7, /*iColumn*/1);55 56 int rc = test_exprIdxCover(&w, &e);57 TEST_ASSERT_EQUAL_INT(WRC_Continue, rc);58 TEST_ASSERT_EQUAL_UINT8(0, w.eCode);59}60 61void test_exprIdxCover_sets_eCode_and_aborts_when_column_not_in_index(void) {62 /* Index covers columns {0,1,2}; expression references column 3 on matching cursor */63 i16 aiCols[3] = {0, 1, 2};64 Index idx;65 struct IdxCover cov;66 Walker w;67 Expr e;68 69 initIndexAndCover(&idx, &cov, /*iCur*/5, aiCols, 3);70 memset(&w, 0, sizeof(w));71 w.u.pIdxCover = &cov;72 w.eCode = 0;73 74 initColumnExpr(&e, /*iTable*/5, /*iColumn*/3);75 76 int rc = test_exprIdxCover(&w, &e);77 TEST_ASSERT_EQUAL_INT(WRC_Abort, rc);78 TEST_ASSERT_EQUAL_UINT8(1, w.eCode);79}80 81void test_exprIdxCover_returns_continue_when_not_TK_COLUMN(void) {82 /* Non-column expression should not change eCode and should continue */83 i16 aiCols[2] = {0, 2};84 Index idx;85 struct IdxCover cov;86 Walker w;87 Expr e;88 89 initIndexAndCover(&idx, &cov, /*iCur*/2, aiCols, 2);90 memset(&w, 0, sizeof(w));91 w.u.pIdxCover = &cov;92 w.eCode = 0;93 94 initNonColumnExpr(&e);95 e.iTable = 2; /* Values should not matter for non-column */96 e.iColumn = 2;97 98 int rc = test_exprIdxCover(&w, &e);99 TEST_ASSERT_EQUAL_INT(WRC_Continue, rc);100 TEST_ASSERT_EQUAL_UINT8(0, w.eCode);101}102 103void test_exprIdxCover_returns_continue_when_iTable_differs(void) {104 /* Column not covered, but iTable != iCur; should not abort or set eCode */105 i16 aiCols[2] = {0, 1};106 Index idx;107 struct IdxCover cov;108 Walker w;109 Expr e;110 111 initIndexAndCover(&idx, &cov, /*iCur*/10, aiCols, 2);112 memset(&w, 0, sizeof(w));113 w.u.pIdxCover = &cov;114 w.eCode = 0;115 116 initColumnExpr(&e, /*iTable*/11, /*iColumn*/99); /* Not covered, but different cursor */117 118 int rc = test_exprIdxCover(&w, &e);119 TEST_ASSERT_EQUAL_INT(WRC_Continue, rc);120 TEST_ASSERT_EQUAL_UINT8(0, w.eCode);121}122 123void test_exprIdxCover_overwrites_eCode_to_1_on_abort(void) {124 /* Start with a non-zero eCode; ensure it becomes exactly 1 when aborting */125 i16 aiCols[1] = {0};126 Index idx;127 struct IdxCover cov;128 Walker w;129 Expr e;130 131 initIndexAndCover(&idx, &cov, /*iCur*/3, aiCols, 1);132 memset(&w, 0, sizeof(w));133 w.u.pIdxCover = &cov;134 w.eCode = 77; /* Non-zero initial value */135 136 initColumnExpr(&e, /*iTable*/3, /*iColumn*/5); /* Not covered */137 138 int rc = test_exprIdxCover(&w, &e);139 TEST_ASSERT_EQUAL_INT(WRC_Abort, rc);140 TEST_ASSERT_EQUAL_UINT8(1, w.eCode);141}142 143int main(void) {144 UNITY_BEGIN();145 RUN_TEST(test_exprIdxCover_returns_continue_when_column_covered);146 RUN_TEST(test_exprIdxCover_sets_eCode_and_aborts_when_column_not_in_index);147 RUN_TEST(test_exprIdxCover_returns_continue_when_not_TK_COLUMN);148 RUN_TEST(test_exprIdxCover_returns_continue_when_iTable_differs);149 RUN_TEST(test_exprIdxCover_overwrites_eCode_to_1_on_abort);150 return UNITY_END();151}