AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* External wrapper provided in the module */7extern int test_sqlite3InRhsIsConstant(Parse *pParse, Expr *pIn);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: initialize an in-memory sqlite3 database and Parse */18static void initParse(Parse *pParse, sqlite3 **ppDb){19 sqlite3 *db = 0;20 int rc = sqlite3_open(":memory:", &db);21 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);22 memset(pParse, 0, sizeof(*pParse));23 pParse->db = db;24 *ppDb = db;25}26 27/* Helper: make an identifier expression (non-constant) */28static Expr* makeIdExpr(sqlite3 *db, const char *zName){29 Token t;30 t.z = (char*)zName;31 t.n = (int)strlen(zName);32 return sqlite3Expr(db, TK_ID, &t);33}34 35/* Helper: make a variable expression (e.g., "?") (non-constant) */36static Expr* makeVariableExpr(sqlite3 *db, const char *zVar){37 Token t;38 t.z = (char*)zVar;39 t.n = (int)strlen(zVar);40 return sqlite3Expr(db, TK_VARIABLE, &t);41}42 43/* Helper: make a function expression with given args */44static Expr* makeFunctionExpr(Parse *pParse, const char *zName, ExprList *pArgs){45 Token t;46 t.z = (char*)zName;47 t.n = (int)strlen(zName);48 return sqlite3ExprFunction(pParse, pArgs, &t);49}50 51/* Helper: build an IN expression: lhs IN (list...) */52static Expr* makeInExpr(Parse *pParse, Expr *pLHS, ExprList *pList){53 Expr *pIn = sqlite3PExpr(pParse, TK_IN, pLHS, 0);54 TEST_ASSERT_NOT_NULL(pIn);55 /* RHS is a list, not a sub-select */56 pIn->x.pList = pList;57 return pIn;58}59 60/* Test: RHS is all constants -> true */61void test_sqlite3InRhsIsConstant_all_constants(void){62 Parse parse;63 sqlite3 *db = NULL;64 initParse(&parse, &db);65 66 ExprList *pList = 0;67 pList = sqlite3ExprListAppend(&parse, pList, sqlite3ExprInteger(db, 1));68 pList = sqlite3ExprListAppend(&parse, pList, sqlite3ExprInteger(db, 2));69 pList = sqlite3ExprListAppend(&parse, pList, sqlite3ExprInteger(db, 3));70 71 Expr *pLHS = sqlite3ExprInteger(db, 99);72 Expr *pIn = makeInExpr(&parse, pLHS, pList);73 74 int res = test_sqlite3InRhsIsConstant(&parse, pIn);75 TEST_ASSERT_NOT_EQUAL(0, res);76 77 sqlite3ExprDelete(db, pIn); /* also frees pList and children */78 sqlite3_close(db);79}80 81/* Test: RHS contains an identifier (non-constant) -> false */82void test_sqlite3InRhsIsConstant_with_identifier_in_list(void){83 Parse parse;84 sqlite3 *db = NULL;85 initParse(&parse, &db);86 87 ExprList *pList = 0;88 pList = sqlite3ExprListAppend(&parse, pList, sqlite3ExprInteger(db, 1));89 pList = sqlite3ExprListAppend(&parse, pList, makeIdExpr(db, "x")); /* non-constant */90 pList = sqlite3ExprListAppend(&parse, pList, sqlite3ExprInteger(db, 3));91 92 Expr *pLHS = sqlite3ExprInteger(db, 0);93 Expr *pIn = makeInExpr(&parse, pLHS, pList);94 95 int res = test_sqlite3InRhsIsConstant(&parse, pIn);96 TEST_ASSERT_EQUAL_INT(0, res);97 98 sqlite3ExprDelete(db, pIn);99 sqlite3_close(db);100}101 102/* Test: RHS contains a function call; pParse==NULL -> considered non-constant */103void test_sqlite3InRhsIsConstant_function_with_NULL_Parse(void){104 Parse parse;105 sqlite3 *db = NULL;106 initParse(&parse, &db);107 108 /* Build abs(1) */109 ExprList *fnArgs = 0;110 fnArgs = sqlite3ExprListAppend(&parse, fnArgs, sqlite3ExprInteger(db, 1));111 Expr *pFn = makeFunctionExpr(&parse, "abs", fnArgs);112 113 ExprList *pList = 0;114 pList = sqlite3ExprListAppend(&parse, pList, pFn);115 116 Expr *pLHS = sqlite3ExprInteger(db, 5);117 Expr *pIn = makeInExpr(&parse, pLHS, pList);118 119 int res = test_sqlite3InRhsIsConstant(NULL, pIn); /* NULL Parse forces function -> non-constant */120 TEST_ASSERT_EQUAL_INT(0, res);121 122 sqlite3ExprDelete(db, pIn);123 sqlite3_close(db);124}125 126/* Test: Non-constant LHS should not affect result; RHS all constants -> true */127void test_sqlite3InRhsIsConstant_ignores_LHS_nonconstant(void){128 Parse parse;129 sqlite3 *db = NULL;130 initParse(&parse, &db);131 132 ExprList *pList = 0;133 pList = sqlite3ExprListAppend(&parse, pList, sqlite3ExprInteger(db, 10));134 pList = sqlite3ExprListAppend(&parse, pList, sqlite3ExprInteger(db, 20));135 136 Expr *pLHS = makeIdExpr(db, "y"); /* non-constant LHS */137 Expr *pIn = makeInExpr(&parse, pLHS, pList);138 139 int res = test_sqlite3InRhsIsConstant(&parse, pIn);140 TEST_ASSERT_NOT_EQUAL(0, res);141 142 sqlite3ExprDelete(db, pIn);143 sqlite3_close(db);144}145 146/* Test: RHS contains constant compound expression (1+2) -> true */147void test_sqlite3InRhsIsConstant_constant_compound_expressions(void){148 Parse parse;149 sqlite3 *db = NULL;150 initParse(&parse, &db);151 152 Expr *pPlus = sqlite3PExpr(&parse, TK_PLUS,153 sqlite3ExprInteger(db, 1),154 sqlite3ExprInteger(db, 2));155 TEST_ASSERT_NOT_NULL(pPlus);156 157 ExprList *pList = 0;158 pList = sqlite3ExprListAppend(&parse, pList, pPlus);159 pList = sqlite3ExprListAppend(&parse, pList, sqlite3ExprInteger(db, 3));160 161 Expr *pLHS = sqlite3ExprInteger(db, 0);162 Expr *pIn = makeInExpr(&parse, pLHS, pList);163 164 int res = test_sqlite3InRhsIsConstant(&parse, pIn);165 TEST_ASSERT_NOT_EQUAL(0, res);166 167 sqlite3ExprDelete(db, pIn);168 sqlite3_close(db);169}170 171/* Test: RHS contains a variable parameter '?' -> false */172void test_sqlite3InRhsIsConstant_with_bind_parameter(void){173 Parse parse;174 sqlite3 *db = NULL;175 initParse(&parse, &db);176 177 ExprList *pList = 0;178 pList = sqlite3ExprListAppend(&parse, pList, sqlite3ExprInteger(db, 1));179 pList = sqlite3ExprListAppend(&parse, pList, makeVariableExpr(db, "?"));180 181 Expr *pLHS = sqlite3ExprInteger(db, 0);182 Expr *pIn = makeInExpr(&parse, pLHS, pList);183 184 int res = test_sqlite3InRhsIsConstant(&parse, pIn);185 TEST_ASSERT_EQUAL_INT(0, res);186 187 sqlite3ExprDelete(db, pIn);188 sqlite3_close(db);189}190 191int main(void){192 UNITY_BEGIN();193 RUN_TEST(test_sqlite3InRhsIsConstant_all_constants);194 RUN_TEST(test_sqlite3InRhsIsConstant_with_identifier_in_list);195 RUN_TEST(test_sqlite3InRhsIsConstant_function_with_NULL_Parse);196 RUN_TEST(test_sqlite3InRhsIsConstant_ignores_LHS_nonconstant);197 RUN_TEST(test_sqlite3InRhsIsConstant_constant_compound_expressions);198 RUN_TEST(test_sqlite3InRhsIsConstant_with_bind_parameter);199 return UNITY_END();200}