AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5 6static sqlite3 *gDb = NULL;7static Parse gParse;8 9/* Helpers to build expression trees */10static Expr *exprNewOp(int op){11 Expr *p = (Expr*)sqlite3DbMallocZero(gDb, sizeof(Expr));12 if( p ){13 p->op = (u8)op;14 }15 return p;16}17 18static Expr *exprMakeInt(i64 v){19 Expr *p = exprNewOp(TK_INTEGER);20 if( p ){21 p->flags |= EP_IntValue;22 p->u.iValue = v;23 }24 return p;25}26 27static Expr *exprMakeNull(void){28 Expr *p = exprNewOp(TK_NULL);29 return p;30}31 32static Expr *exprMakeColumn(int iTable, int iColumn){33 Expr *p = exprNewOp(TK_COLUMN);34 if( p ){35 p->iTable = iTable;36 p->iColumn = iColumn;37 }38 return p;39}40 41static Expr *exprMakeUnary(int op, Expr *pLeft){42 Expr *p = exprNewOp(op);43 if( p ){44 p->pLeft = pLeft;45 }46 return p;47}48 49static Expr *exprMakeBinary(int op, Expr *pLeft, Expr *pRight){50 Expr *p = exprNewOp(op);51 if( p ){52 p->pLeft = pLeft;53 p->pRight = pRight;54 }55 return p;56}57 58static ExprList *exprListNewN(int n){59 ExprList *pList = (ExprList*)sqlite3DbMallocZero(gDb, sizeof(ExprList));60 if( pList ){61 pList->nExpr = (i16)n;62 pList->nAlloc = (i16)n;63 pList->a = (struct ExprList_item*)sqlite3DbMallocZero(gDb, sizeof(struct ExprList_item)*n);64 if( pList->a==0 ){65 sqlite3DbFree(gDb, pList);66 return 0;67 }68 }69 return pList;70}71 72static Expr *exprMakeIif(Expr *pCond, Expr *pThen, Expr *pElse /* may be NULL */){73 int nArg = pElse ? 3 : 2;74 Expr *p = exprNewOp(TK_FUNCTION);75 if( p==0 ) return 0;76 p->u.zToken = sqlite3DbStrDup(gDb, "iif");77 ExprList *pList = exprListNewN(nArg);78 if( pList==0 ) return p; /* Leak small amount on OOM; tests won't continue */79 pList->a[0].pExpr = pCond;80 pList->a[1].pExpr = pThen;81 if( nArg==3 ) pList->a[2].pExpr = pElse;82 p->x.pList = pList;83 return p;84}85 86static void exprFree(Expr *p){87 sqlite3ExprDelete(gDb, p);88}89 90void setUp(void) {91 memset(&gParse, 0, sizeof(gParse));92 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &gDb));93 gParse.db = gDb;94}95 96void tearDown(void) {97 if( gDb ){98 sqlite3_close(gDb);99 gDb = NULL;100 }101 memset(&gParse, 0, sizeof(gParse));102}103 104/* 1) Identical expressions: x==5 implies x==5 */105void test_sqlite3ExprImpliesExpr_identical_eq(void){106 Expr *x1 = exprMakeColumn(1, 1);107 Expr *x2 = exprMakeColumn(1, 1);108 Expr *c5a = exprMakeInt(5);109 Expr *c5b = exprMakeInt(5);110 Expr *e1 = exprMakeBinary(TK_EQ, x1, c5a);111 Expr *e2 = exprMakeBinary(TK_EQ, x2, c5b);112 113 int rc = sqlite3ExprImpliesExpr(&gParse, e1, e2, 0);114 TEST_ASSERT_TRUE(rc==1);115 116 exprFree(e1);117 exprFree(e2);118}119 120/* 2) OR case: x==21 implies (x==21 OR y==43) */121void test_sqlite3ExprImpliesExpr_or_true(void){122 Expr *xL = exprMakeColumn(1, 1);123 Expr *xR = exprMakeColumn(1, 1);124 Expr *y = exprMakeColumn(1, 2);125 Expr *c21a = exprMakeInt(21);126 Expr *c21b = exprMakeInt(21);127 Expr *c43 = exprMakeInt(43);128 129 Expr *e1 = exprMakeBinary(TK_EQ, xL, c21a); /* x==21 */130 Expr *left = exprMakeBinary(TK_EQ, xR, c21b); /* x==21 */131 Expr *right = exprMakeBinary(TK_EQ, y, c43); /* y==43 */132 Expr *e2 = exprMakeBinary(TK_OR, left, right); /* (x==21 OR y==43) */133 134 int rc = sqlite3ExprImpliesExpr(&gParse, e1, e2, 0);135 TEST_ASSERT_TRUE(rc==1);136 137 exprFree(e1);138 exprFree(e2);139}140 141/* 3) NOT NULL from inequality: x!=123 implies x IS NOT NULL */142void test_sqlite3ExprImpliesExpr_ne_implies_notnull(void){143 Expr *x1 = exprMakeColumn(3, 5);144 Expr *x2 = exprMakeColumn(3, 5);145 Expr *c123 = exprMakeInt(123);146 Expr *e1 = exprMakeBinary(TK_NE, x1, c123); /* x!=123 */147 Expr *nn = exprMakeUnary(TK_NOTNULL, x2); /* x IS NOT NULL */148 149 int rc = sqlite3ExprImpliesExpr(&gParse, e1, nn, 0);150 TEST_ASSERT_TRUE(rc==1);151 152 exprFree(e1);153 exprFree(nn);154}155 156/* 4) NOT NULL from arithmetic: x+1 implies x IS NOT NULL */157void test_sqlite3ExprImpliesExpr_plus_implies_notnull(void){158 Expr *x1 = exprMakeColumn(7, 2);159 Expr *x2 = exprMakeColumn(7, 2);160 Expr *c1 = exprMakeInt(1);161 Expr *e1 = exprMakeBinary(TK_PLUS, x1, c1); /* x+1 */162 Expr *nn = exprMakeUnary(TK_NOTNULL, x2); /* x IS NOT NULL */163 164 int rc = sqlite3ExprImpliesExpr(&gParse, e1, nn, 0);165 TEST_ASSERT_TRUE(rc==1);166 167 exprFree(e1);168 exprFree(nn);169}170 171/* 5) iif(x,y) implies x */172void test_sqlite3ExprImpliesExpr_iif_two_args(void){173 Expr *x = exprMakeColumn(9, 1);174 Expr *xCopy = exprMakeColumn(9, 1);175 Expr *y = exprMakeColumn(9, 2);176 Expr *iif = exprMakeIif(x, y, NULL);177 178 int rc = sqlite3ExprImpliesExpr(&gParse, iif, xCopy, 0);179 TEST_ASSERT_TRUE(rc==1);180 181 exprFree(iif);182 exprFree(xCopy);183}184 185/* 6) iif(x,y,0) implies x */186void test_sqlite3ExprImpliesExpr_iif_three_args_zero(void){187 Expr *x = exprMakeColumn(10, 3);188 Expr *xCopy = exprMakeColumn(10, 3);189 Expr *y = exprMakeColumn(10, 4);190 Expr *zero = exprMakeInt(0);191 Expr *iif = exprMakeIif(x, y, zero);192 193 int rc = sqlite3ExprImpliesExpr(&gParse, iif, xCopy, 0);194 TEST_ASSERT_TRUE(rc==1);195 196 exprFree(iif);197 exprFree(xCopy);198}199 200/* 7) Non-implication: x>0 does not imply x==5 */201void test_sqlite3ExprImpliesExpr_gt_not_imply_eq(void){202 Expr *x1 = exprMakeColumn(2, 1);203 Expr *x2 = exprMakeColumn(2, 1);204 Expr *c0 = exprMakeInt(0);205 Expr *c5 = exprMakeInt(5);206 Expr *e1 = exprMakeBinary(TK_GT, x1, c0); /* x>0 */207 Expr *e2 = exprMakeBinary(TK_EQ, x2, c5); /* x==5 */208 209 int rc = sqlite3ExprImpliesExpr(&gParse, e1, e2, 0);210 TEST_ASSERT_TRUE(rc==0);211 212 exprFree(e1);213 exprFree(e2);214}215 216/* 8) iTab substitution: pE2 column iTable<0 matches via iTab */217void test_sqlite3ExprImpliesExpr_iTab_substitution(void){218 int iTab = 42;219 /* e1: (col[42,0] == 5) */220 Expr *c1 = exprMakeColumn(iTab, 0);221 Expr *v5a = exprMakeInt(5);222 Expr *e1 = exprMakeBinary(TK_EQ, c1, v5a);223 224 /* e2: (col[-1,0] == 5) */225 Expr *c2 = exprMakeColumn(-1, 0);226 Expr *v5b = exprMakeInt(5);227 Expr *e2 = exprMakeBinary(TK_EQ, c2, v5b);228 229 int rc = sqlite3ExprImpliesExpr(&gParse, e1, e2, iTab);230 TEST_ASSERT_TRUE(rc==1);231 232 exprFree(e1);233 exprFree(e2);234}235 236/* 9) NULL does not imply x IS NOT NULL */237void test_sqlite3ExprImpliesExpr_null_not_imply_notnull(void){238 Expr *nullExpr = exprMakeNull();239 Expr *x = exprMakeColumn(5, 7);240 Expr *nn = exprMakeUnary(TK_NOTNULL, x);241 242 int rc = sqlite3ExprImpliesExpr(&gParse, nullExpr, nn, 0);243 TEST_ASSERT_TRUE(rc==0);244 245 exprFree(nullExpr);246 exprFree(nn);247}248 249/* 10) Different column inequality should not imply x IS NOT NULL */250void test_sqlite3ExprImpliesExpr_ne_different_column_not_imply_x_notnull(void){251 Expr *x = exprMakeColumn(1, 1);252 Expr *y = exprMakeColumn(1, 2);253 Expr *c7 = exprMakeInt(7);254 Expr *e1 = exprMakeBinary(TK_NE, y, c7); /* y!=7 */255 Expr *e2 = exprMakeUnary(TK_NOTNULL, x); /* x IS NOT NULL */256 257 int rc = sqlite3ExprImpliesExpr(&gParse, e1, e2, 0);258 TEST_ASSERT_TRUE(rc==0);259 260 exprFree(e1);261 exprFree(e2);262}263 264int main(void) {265 UNITY_BEGIN();266 RUN_TEST(test_sqlite3ExprImpliesExpr_identical_eq);267 RUN_TEST(test_sqlite3ExprImpliesExpr_or_true);268 RUN_TEST(test_sqlite3ExprImpliesExpr_ne_implies_notnull);269 RUN_TEST(test_sqlite3ExprImpliesExpr_plus_implies_notnull);270 RUN_TEST(test_sqlite3ExprImpliesExpr_iif_two_args);271 RUN_TEST(test_sqlite3ExprImpliesExpr_iif_three_args_zero);272 RUN_TEST(test_sqlite3ExprImpliesExpr_gt_not_imply_eq);273 RUN_TEST(test_sqlite3ExprImpliesExpr_iTab_substitution);274 RUN_TEST(test_sqlite3ExprImpliesExpr_null_not_imply_notnull);275 RUN_TEST(test_sqlite3ExprImpliesExpr_ne_different_column_not_imply_x_notnull);276 return UNITY_END();277}