AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Global DB handle for use in tests */7static sqlite3 *gDb = NULL;8 9/* Wrapper prototype for the static function under test (provided by build) */10int test_fixExprCb(Walker *p, Expr *pExpr);11 12void setUp(void) {13 int rc = sqlite3_open(":memory:", &gDb);14 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);15 TEST_ASSERT_NOT_NULL(gDb);16}17 18void tearDown(void) {19 if (gDb) {20 sqlite3_close(gDb);21 gDb = NULL;22 }23}24 25/* Helper: initialize a Parse and DbFixer for a given database index and type */26static void initParseAndFixer(Parse *pParse, DbFixer *pFix, int iDb, const char *zType){27 memset(pParse, 0, sizeof(*pParse));28 pParse->db = gDb;29 sqlite3FixInit(pFix, pParse, iDb, zType, 0);30}31 32/* Non-TEMP, non-variable: EP_FromDDL must be set, return WRC_Continue */33void test_fixExprCb_non_temp_non_variable_sets_FromDDL(void) {34 Parse parse;35 DbFixer fixer;36 Expr e;37 int rc;38 39 initParseAndFixer(&parse, &fixer, 0 /* main DB */, "view");40 memset(&e, 0, sizeof(e));41 e.op = TK_INTEGER;42 43 rc = test_fixExprCb(&fixer.w, &e);44 TEST_ASSERT_EQUAL_INT(WRC_Continue, rc);45 TEST_ASSERT_NOT_EQUAL(0, (e.flags & EP_FromDDL));46 TEST_ASSERT_NULL(parse.zErrMsg);47}48 49/* TEMP, non-variable: EP_FromDDL must NOT be set, return WRC_Continue */50void test_fixExprCb_temp_non_variable_no_FromDDL(void) {51 Parse parse;52 DbFixer fixer;53 Expr e;54 int rc;55 56 initParseAndFixer(&parse, &fixer, 1 /* TEMP DB */, "view");57 memset(&e, 0, sizeof(e));58 e.op = TK_INTEGER;59 60 rc = test_fixExprCb(&fixer.w, &e);61 TEST_ASSERT_EQUAL_INT(WRC_Continue, rc);62 TEST_ASSERT_EQUAL_INT(0, (e.flags & EP_FromDDL));63 TEST_ASSERT_NULL(parse.zErrMsg);64}65 66/* Non-TEMP, variable, init.busy==0: error and WRC_Abort, EP_FromDDL set, op unchanged */67void test_fixExprCb_non_temp_variable_not_busy_aborts_with_error(void) {68 Parse parse;69 DbFixer fixer;70 Expr e;71 int rc;72 73 initParseAndFixer(&parse, &fixer, 0 /* main DB */, "view");74 gDb->init.busy = 0;75 memset(&e, 0, sizeof(e));76 e.op = TK_VARIABLE;77 78 rc = test_fixExprCb(&fixer.w, &e);79 TEST_ASSERT_EQUAL_INT(WRC_Abort, rc);80 TEST_ASSERT_NOT_EQUAL(0, (e.flags & EP_FromDDL));81 TEST_ASSERT_EQUAL_INT(TK_VARIABLE, e.op);82 TEST_ASSERT_NOT_NULL(parse.zErrMsg);83 TEST_ASSERT_NOT_NULL(strstr(parse.zErrMsg, "view cannot use variables"));84 85 sqlite3DbFree(gDb, parse.zErrMsg);86 parse.zErrMsg = 0;87}88 89/* Non-TEMP, variable, init.busy==1: continue, op rewritten to TK_NULL, no error */90void test_fixExprCb_non_temp_variable_busy_rewrites_to_NULL(void) {91 Parse parse;92 DbFixer fixer;93 Expr e;94 int rc;95 96 initParseAndFixer(&parse, &fixer, 0 /* main DB */, "view");97 gDb->init.busy = 1;98 memset(&e, 0, sizeof(e));99 e.op = TK_VARIABLE;100 101 rc = test_fixExprCb(&fixer.w, &e);102 TEST_ASSERT_EQUAL_INT(WRC_Continue, rc);103 TEST_ASSERT_NOT_EQUAL(0, (e.flags & EP_FromDDL));104 TEST_ASSERT_EQUAL_INT(TK_NULL, e.op);105 TEST_ASSERT_NULL(parse.zErrMsg);106 107 gDb->init.busy = 0; /* restore */108}109 110/* TEMP, variable, init.busy==0: error and WRC_Abort, EP_FromDDL not set, op unchanged */111void test_fixExprCb_temp_variable_not_busy_aborts_with_error(void) {112 Parse parse;113 DbFixer fixer;114 Expr e;115 int rc;116 117 initParseAndFixer(&parse, &fixer, 1 /* TEMP DB */, "trigger");118 gDb->init.busy = 0;119 memset(&e, 0, sizeof(e));120 e.op = TK_VARIABLE;121 122 rc = test_fixExprCb(&fixer.w, &e);123 TEST_ASSERT_EQUAL_INT(WRC_Abort, rc);124 TEST_ASSERT_EQUAL_INT(0, (e.flags & EP_FromDDL));125 TEST_ASSERT_EQUAL_INT(TK_VARIABLE, e.op);126 TEST_ASSERT_NOT_NULL(parse.zErrMsg);127 TEST_ASSERT_NOT_NULL(strstr(parse.zErrMsg, "trigger cannot use variables"));128 129 sqlite3DbFree(gDb, parse.zErrMsg);130 parse.zErrMsg = 0;131}132 133/* TEMP, variable, init.busy==1: continue, op rewritten to TK_NULL, EP_FromDDL not set */134void test_fixExprCb_temp_variable_busy_rewrites_to_NULL(void) {135 Parse parse;136 DbFixer fixer;137 Expr e;138 int rc;139 140 initParseAndFixer(&parse, &fixer, 1 /* TEMP DB */, "index");141 gDb->init.busy = 1;142 memset(&e, 0, sizeof(e));143 e.op = TK_VARIABLE;144 145 rc = test_fixExprCb(&fixer.w, &e);146 TEST_ASSERT_EQUAL_INT(WRC_Continue, rc);147 TEST_ASSERT_EQUAL_INT(0, (e.flags & EP_FromDDL));148 TEST_ASSERT_EQUAL_INT(TK_NULL, e.op);149 TEST_ASSERT_NULL(parse.zErrMsg);150 151 gDb->init.busy = 0; /* restore */152}153 154int main(void) {155 UNITY_BEGIN();156 RUN_TEST(test_fixExprCb_non_temp_non_variable_sets_FromDDL);157 RUN_TEST(test_fixExprCb_temp_non_variable_no_FromDDL);158 RUN_TEST(test_fixExprCb_non_temp_variable_not_busy_aborts_with_error);159 RUN_TEST(test_fixExprCb_non_temp_variable_busy_rewrites_to_NULL);160 RUN_TEST(test_fixExprCb_temp_variable_not_busy_aborts_with_error);161 RUN_TEST(test_fixExprCb_temp_variable_busy_rewrites_to_NULL);162 return UNITY_END();163}