AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* External wrapper for the static function under test */7extern int test_impliesNotNullRow(Walker *pWalker, Expr *pExpr);8 9/* Helpers to build expressions */10 11static Expr *newExpr(sqlite3 *db, int op){12 Expr *p = (Expr*)sqlite3DbMallocZero(db, sizeof(Expr));13 TEST_ASSERT_NOT_NULL_MESSAGE(p, "sqlite3DbMallocZero Expr failed");14 p->op = (u8)op;15 return p;16}17 18static Expr *newColumnExpr(sqlite3 *db, int iTable){19 Expr *p = newExpr(db, TK_COLUMN);20 p->iTable = iTable;21 return p;22}23 24static Expr *newBinaryExpr(sqlite3 *db, int op, Expr *pLeft, Expr *pRight){25 Expr *p = newExpr(db, op);26 p->pLeft = pLeft;27 p->pRight = pRight;28 return p;29}30 31static ExprList *newExprList(sqlite3 *db, int n){32 ExprList *pList = (ExprList*)sqlite3DbMallocZero(db, sizeof(ExprList));33 TEST_ASSERT_NOT_NULL_MESSAGE(pList, "sqlite3DbMallocZero ExprList failed");34 if( n>0 ){35 pList->nExpr = n;36 pList->nAlloc = n;37 pList->a = (struct ExprList_item*)sqlite3DbMallocZero(38 db, sizeof(struct ExprList_item)*n);39 TEST_ASSERT_NOT_NULL_MESSAGE(pList->a, "sqlite3DbMallocZero ExprList_item failed");40 }41 return pList;42}43 44static Expr *newInExpr(sqlite3 *db, Expr *pLhs, int nList){45 Expr *p = newExpr(db, TK_IN);46 p->pLeft = pLhs;47 p->x.pList = newExprList(db, nList);48 /* No need to populate list expressions for the function under test,49 it only checks that nExpr>0 and then walks pLeft. But allocate 1+ safely. */50 if( nList>0 ){51 /* Provide a dummy expression in the list to satisfy ALWAYS(nExpr>0) */52 p->x.pList->a[0].pExpr = newExpr(db, TK_INTEGER);53 }54 return p;55}56 57static Expr *newBetweenExpr(sqlite3 *db, Expr *pX, Expr *pY, Expr *pZ){58 Expr *p = newExpr(db, TK_BETWEEN);59 p->pLeft = pX;60 p->x.pList = newExprList(db, 2);61 p->x.pList->a[0].pExpr = pY;62 p->x.pList->a[1].pExpr = pZ;63 return p;64}65 66static void freeExpr(sqlite3 *db, Expr *p){67 sqlite3ExprDelete(db, p);68}69 70/* Unity fixtures */71void setUp(void) {72 /* no-op */73}74void tearDown(void) {75 /* no-op */76}77 78/* Tests */79 80static Walker newWalker(int iCur, int mWFlags){81 Walker w;82 memset(&w, 0, sizeof(w));83 w.xExprCallback = test_impliesNotNullRow;84 w.eCode = 0;85 w.u.iCur = iCur;86 w.mWFlags = mWFlags;87 return w;88}89 90void test_impliesNotNullRow_column_match_sets_eCode_and_aborts(void){91 sqlite3 *db = 0;92 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));93 Expr *pCol = newColumnExpr(db, 2);94 Walker w = newWalker(2, 0);95 96 int rc = test_impliesNotNullRow(&w, pCol);97 98 TEST_ASSERT_EQUAL_INT(WRC_Abort, rc);99 TEST_ASSERT_EQUAL_INT(1, w.eCode);100 101 freeExpr(db, pCol);102 sqlite3_close(db);103}104 105void test_impliesNotNullRow_column_nomatch_prunes_no_eCode(void){106 sqlite3 *db = 0;107 sqlite3_open(":memory:", &db);108 Expr *pCol = newColumnExpr(db, 3);109 Walker w = newWalker(2, 0);110 111 int rc = test_impliesNotNullRow(&w, pCol);112 113 TEST_ASSERT_EQUAL_INT(WRC_Prune, rc);114 TEST_ASSERT_EQUAL_INT(0, w.eCode);115 116 freeExpr(db, pCol);117 sqlite3_close(db);118}119 120void test_impliesNotNullRow_outerON_prunes_and_ignores_column(void){121 sqlite3 *db = 0;122 sqlite3_open(":memory:", &db);123 Expr *pCol = newColumnExpr(db, 5);124 pCol->flags |= EP_OuterON; /* Outer join ON-clause marker */125 Walker w = newWalker(5, 0);126 127 int rc = test_impliesNotNullRow(&w, pCol);128 129 TEST_ASSERT_EQUAL_INT(WRC_Prune, rc);130 TEST_ASSERT_EQUAL_INT(0, w.eCode);131 132 freeExpr(db, pCol);133 sqlite3_close(db);134}135 136void test_impliesNotNullRow_innerON_with_mWFlags_prunes_and_ignores_column(void){137 sqlite3 *db = 0;138 sqlite3_open(":memory:", &db);139 Expr *pCol = newColumnExpr(db, 7);140 pCol->flags |= EP_InnerON; /* Inner join ON-clause marker */141 Walker w = newWalker(7, 1); /* non-zero mWFlags simulating RIGHT/FULL JOIN processing */142 143 int rc = test_impliesNotNullRow(&w, pCol);144 145 TEST_ASSERT_EQUAL_INT(WRC_Prune, rc);146 TEST_ASSERT_EQUAL_INT(0, w.eCode);147 148 freeExpr(db, pCol);149 sqlite3_close(db);150}151 152void test_impliesNotNullRow_or_both_children_imply_sets_eCode(void){153 sqlite3 *db = 0;154 sqlite3_open(":memory:", &db);155 Expr *pL = newColumnExpr(db, 4);156 Expr *pR = newColumnExpr(db, 4);157 Expr *pOr = newBinaryExpr(db, TK_OR, pL, pR);158 Walker w = newWalker(4, 0);159 160 int rc = test_impliesNotNullRow(&w, pOr);161 162 TEST_ASSERT_EQUAL_INT(WRC_Prune, rc);163 TEST_ASSERT_EQUAL_INT(1, w.eCode);164 165 freeExpr(db, pOr);166 sqlite3_close(db);167}168 169void test_impliesNotNullRow_or_only_one_child_implies_leaves_eCode_zero(void){170 sqlite3 *db = 0;171 sqlite3_open(":memory:", &db);172 Expr *pL = newColumnExpr(db, 10); /* matches */173 Expr *pR = newColumnExpr(db, 99); /* does not match */174 Expr *pOr = newBinaryExpr(db, TK_OR, pL, pR);175 Walker w = newWalker(10, 0);176 177 int rc = test_impliesNotNullRow(&w, pOr);178 179 TEST_ASSERT_EQUAL_INT(WRC_Prune, rc);180 TEST_ASSERT_EQUAL_INT(0, w.eCode);181 182 freeExpr(db, pOr);183 sqlite3_close(db);184}185 186void test_impliesNotNullRow_and_both_children_imply_sets_eCode(void){187 sqlite3 *db = 0;188 sqlite3_open(":memory:", &db);189 Expr *pL = newColumnExpr(db, 8);190 Expr *pR = newColumnExpr(db, 8);191 Expr *pAnd = newBinaryExpr(db, TK_AND, pL, pR);192 Walker w = newWalker(8, 0);193 194 int rc = test_impliesNotNullRow(&w, pAnd);195 196 TEST_ASSERT_EQUAL_INT(WRC_Prune, rc);197 TEST_ASSERT_EQUAL_INT(1, w.eCode);198 199 freeExpr(db, pAnd);200 sqlite3_close(db);201}202 203void test_impliesNotNullRow_in_checks_left_operand_and_sets_eCode(void){204 sqlite3 *db = 0;205 sqlite3_open(":memory:", &db);206 Expr *pLhs = newColumnExpr(db, 12);207 Expr *pIn = newInExpr(db, pLhs, 1); /* non-empty list */208 Walker w = newWalker(12, 0);209 210 int rc = test_impliesNotNullRow(&w, pIn);211 212 TEST_ASSERT_EQUAL_INT(WRC_Prune, rc);213 TEST_ASSERT_EQUAL_INT(1, w.eCode);214 215 freeExpr(db, pIn);216 sqlite3_close(db);217}218 219void test_impliesNotNullRow_between_left_implies_sets_eCode(void){220 sqlite3 *db = 0;221 sqlite3_open(":memory:", &db);222 Expr *pX = newColumnExpr(db, 15); /* matches */223 Expr *pY = newColumnExpr(db, 99);224 Expr *pZ = newColumnExpr(db, 99);225 Expr *pBetween = newBetweenExpr(db, pX, pY, pZ);226 Walker w = newWalker(15, 0);227 228 int rc = test_impliesNotNullRow(&w, pBetween);229 230 TEST_ASSERT_EQUAL_INT(WRC_Prune, rc);231 TEST_ASSERT_EQUAL_INT(1, w.eCode);232 233 freeExpr(db, pBetween);234 sqlite3_close(db);235}236 237void test_impliesNotNullRow_between_left_not_imply_but_both_bounds_imply_sets_eCode(void){238 sqlite3 *db = 0;239 sqlite3_open(":memory:", &db);240 Expr *pX = newColumnExpr(db, 100); /* does not match */241 Expr *pY = newColumnExpr(db, 20); /* match */242 Expr *pZ = newColumnExpr(db, 20); /* match */243 Expr *pBetween = newBetweenExpr(db, pX, pY, pZ);244 Walker w = newWalker(20, 0);245 246 int rc = test_impliesNotNullRow(&w, pBetween);247 248 TEST_ASSERT_EQUAL_INT(WRC_Prune, rc);249 TEST_ASSERT_EQUAL_INT(1, w.eCode);250 251 freeExpr(db, pBetween);252 sqlite3_close(db);253}254 255void test_impliesNotNullRow_between_left_not_imply_and_one_bound_not_imply_leaves_eCode_zero(void){256 sqlite3 *db = 0;257 sqlite3_open(":memory:", &db);258 Expr *pX = newColumnExpr(db, 200); /* does not match */259 Expr *pY = newColumnExpr(db, 30); /* match */260 Expr *pZ = newColumnExpr(db, 300); /* no match */261 Expr *pBetween = newBetweenExpr(db, pX, pY, pZ);262 Walker w = newWalker(30, 0);263 264 int rc = test_impliesNotNullRow(&w, pBetween);265 266 TEST_ASSERT_EQUAL_INT(WRC_Prune, rc);267 TEST_ASSERT_EQUAL_INT(0, w.eCode);268 269 freeExpr(db, pBetween);270 sqlite3_close(db);271}272 273void test_impliesNotNullRow_function_prunes(void){274 sqlite3 *db = 0;275 sqlite3_open(":memory:", &db);276 Expr *pFunc = newExpr(db, TK_FUNCTION);277 Walker w = newWalker(1, 0);278 279 int rc = test_impliesNotNullRow(&w, pFunc);280 281 TEST_ASSERT_EQUAL_INT(WRC_Prune, rc);282 TEST_ASSERT_EQUAL_INT(0, w.eCode);283 284 freeExpr(db, pFunc);285 sqlite3_close(db);286}287 288void test_impliesNotNullRow_default_continues_on_integer(void){289 sqlite3 *db = 0;290 sqlite3_open(":memory:", &db);291 Expr *pInt = newExpr(db, TK_INTEGER);292 Walker w = newWalker(1, 0);293 294 int rc = test_impliesNotNullRow(&w, pInt);295 296 TEST_ASSERT_EQUAL_INT(WRC_Continue, rc);297 TEST_ASSERT_EQUAL_INT(0, w.eCode);298 299 freeExpr(db, pInt);300 sqlite3_close(db);301}302 303/* Unity runner */304int main(void){305 UNITY_BEGIN();306 RUN_TEST(test_impliesNotNullRow_column_match_sets_eCode_and_aborts);307 RUN_TEST(test_impliesNotNullRow_column_nomatch_prunes_no_eCode);308 RUN_TEST(test_impliesNotNullRow_outerON_prunes_and_ignores_column);309 RUN_TEST(test_impliesNotNullRow_innerON_with_mWFlags_prunes_and_ignores_column);310 RUN_TEST(test_impliesNotNullRow_or_both_children_imply_sets_eCode);311 RUN_TEST(test_impliesNotNullRow_or_only_one_child_implies_leaves_eCode_zero);312 RUN_TEST(test_impliesNotNullRow_and_both_children_imply_sets_eCode);313 RUN_TEST(test_impliesNotNullRow_in_checks_left_operand_and_sets_eCode);314 RUN_TEST(test_impliesNotNullRow_between_left_implies_sets_eCode);315 RUN_TEST(test_impliesNotNullRow_between_left_not_imply_but_both_bounds_imply_sets_eCode);316 RUN_TEST(test_impliesNotNullRow_between_left_not_imply_and_one_bound_not_imply_leaves_eCode_zero);317 RUN_TEST(test_impliesNotNullRow_function_prunes);318 RUN_TEST(test_impliesNotNullRow_default_continues_on_integer);319 return UNITY_END();320}