AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Wrapper for the static function under test (provided in expr.c) */7int test_exprIsConst(Parse *pParse, Expr *p, int initFlag);8 9static sqlite3 *gDb = NULL;10static Parse gParse;11 12void setUp(void) {13 int rc = sqlite3_open(":memory:", &gDb);14 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);15 memset(&gParse, 0, sizeof(gParse));16 gParse.db = gDb;17}18 19void tearDown(void) {20 if (gDb) {21 sqlite3_close(gDb);22 gDb = NULL;23 }24}25 26/* Helper: create integer literal Expr */27static Expr* make_int_expr(void){28 Expr *p = sqlite3ExprAlloc(gDb, TK_INTEGER, 0, 0);29 TEST_ASSERT_NOT_NULL(p);30 return p;31}32 33/* Helper: create column Expr */34static Expr* make_column_expr(void){35 Expr *p = sqlite3ExprAlloc(gDb, TK_COLUMN, 0, 0);36 TEST_ASSERT_NOT_NULL(p);37 return p;38}39 40/* Helper: create TK_ID Expr with given token string */41static Expr* make_id_expr(const char *z){42 Expr *p = sqlite3Expr(gDb, TK_ID, z);43 TEST_ASSERT_NOT_NULL(p);44 return p;45}46 47/* Helper: create TK_VARIABLE Expr with given token string (e.g., "?1") */48static Expr* make_var_expr(const char *z){49 Expr *p = sqlite3Expr(gDb, TK_VARIABLE, z);50 TEST_ASSERT_NOT_NULL(p);51 return p;52}53 54/* Helper: create function call Expr: name(arg) or name() if arg==NULL */55static Expr* make_func_expr(const char *zName, Expr *pArg){56 Token t;57 ExprList *pList = NULL;58 if( pArg ){59 pList = sqlite3ExprListAppend(&gParse, NULL, pArg);60 TEST_ASSERT_NOT_NULL(pList);61 }62 t.z = (char*)zName;63 t.n = (int)strlen(zName);64 Expr *pFunc = sqlite3ExprFunction(&gParse, pList, &t, ENC(gDb));65 TEST_ASSERT_NOT_NULL(pFunc);66 return pFunc;67}68 69/* 1) Literal constant returns initFlag (non-zero) */70void test_exprIsConst_literal_returns_initFlag(void){71 Expr *p = make_int_expr();72 int rc = test_exprIsConst(&gParse, p, 1);73 TEST_ASSERT_EQUAL_INT(1, rc);74 sqlite3ExprDelete(gDb, p);75}76 77/* 2) Column expression is not constant (returns 0) */78void test_exprIsConst_column_not_constant(void){79 Expr *p = make_column_expr();80 int rc = test_exprIsConst(&gParse, p, 1);81 TEST_ASSERT_EQUAL_INT(0, rc);82 sqlite3ExprDelete(gDb, p);83}84 85/* 3) Outer join term (EP_OuterON) disqualifies for flag==2 */86void test_exprIsConst_outer_on_disqualifies_when_flag2(void){87 Expr *p = make_int_expr(); /* literal but mark as OuterON */88 ExprSetProperty(p, EP_OuterON);89 int rc = test_exprIsConst(&gParse, p, 2);90 TEST_ASSERT_EQUAL_INT(0, rc);91 sqlite3ExprDelete(gDb, p);92}93 94/* 4) Function with constant args is constant with initFlag==4 */95void test_exprIsConst_function_constargs_constant_with_flag4(void){96 Expr *arg = make_int_expr();97 Expr *func = make_func_expr("abs", arg);98 int rc = test_exprIsConst(&gParse, func, 4);99 TEST_ASSERT_EQUAL_INT(4, rc);100 sqlite3ExprDelete(gDb, func);101}102 103/* 5) Function with column arg is not constant with initFlag==4 */104void test_exprIsConst_function_with_column_arg_not_constant_under_flag4(void){105 Expr *arg = make_column_expr();106 Expr *func = make_func_expr("abs", arg);107 int rc = test_exprIsConst(&gParse, func, 4);108 TEST_ASSERT_EQUAL_INT(0, rc);109 sqlite3ExprDelete(gDb, func);110}111 112/* 6) Variable is converted to NULL and allowed when initFlag==5 */113void test_exprIsConst_variable_converted_to_null_when_flag5(void){114 Expr *p = make_var_expr("?1");115 int rc = test_exprIsConst(&gParse, p, 5);116 TEST_ASSERT_EQUAL_INT(5, rc);117 TEST_ASSERT_EQUAL_INT(TK_NULL, p->op);118 sqlite3ExprDelete(gDb, p);119}120 121/* 7) Variable disallowed when initFlag==4 (returns 0) */122void test_exprIsConst_variable_disallowed_when_flag4(void){123 Expr *p = make_var_expr("?1");124 int rc = test_exprIsConst(&gParse, p, 4);125 TEST_ASSERT_EQUAL_INT(0, rc);126 sqlite3ExprDelete(gDb, p);127}128 129/* 8) ID 'true' is converted to TK_TRUEFALSE and considered constant */130void test_exprIsConst_id_true_converted_to_truefalse(void){131 Expr *p = make_id_expr("true");132 TEST_ASSERT_EQUAL_INT(TK_ID, p->op);133 int rc = test_exprIsConst(&gParse, p, 1);134 TEST_ASSERT_EQUAL_INT(1, rc);135 TEST_ASSERT_EQUAL_INT(TK_TRUEFALSE, p->op);136 sqlite3ExprDelete(gDb, p);137}138 139/* 9) Column with EP_FixedCol property is considered constant (unless flag==2) */140void test_exprIsConst_column_with_fixedcol_property_considered_constant(void){141 Expr *p = make_column_expr();142 ExprSetProperty(p, EP_FixedCol);143 int rc = test_exprIsConst(&gParse, p, 1);144 TEST_ASSERT_EQUAL_INT(1, rc);145 sqlite3ExprDelete(gDb, p);146}147 148/* 10) TK_RAISE is not constant */149void test_exprIsConst_raise_node_not_constant(void){150 Expr *p = sqlite3ExprAlloc(gDb, TK_RAISE, 0, 0);151 TEST_ASSERT_NOT_NULL(p);152 int rc = test_exprIsConst(&gParse, p, 1);153 TEST_ASSERT_EQUAL_INT(0, rc);154 sqlite3ExprDelete(gDb, p);155}156 157/* 11) Window function is not constant even under flag 4 */158void test_exprIsConst_window_function_not_constant_under_flag4(void){159 Expr *arg = make_int_expr();160 Expr *func = make_func_expr("abs", arg);161 ExprSetProperty(func, EP_WinFunc);162 int rc = test_exprIsConst(&gParse, func, 4);163 TEST_ASSERT_EQUAL_INT(0, rc);164 sqlite3ExprDelete(gDb, func);165}166 167/* 12) Under flag 5, functions get EP_FromDDL set when treated constant */168void test_exprIsConst_flag5_sets_FromDDL_on_functions(void){169 Expr *arg = make_int_expr();170 Expr *func = make_func_expr("abs", arg);171 int rc = test_exprIsConst(&gParse, func, 5);172 TEST_ASSERT_EQUAL_INT(5, rc);173 TEST_ASSERT_TRUE( ExprHasProperty(func, EP_FromDDL) );174 sqlite3ExprDelete(gDb, func);175}176 177int main(void) {178 UNITY_BEGIN();179 RUN_TEST(test_exprIsConst_literal_returns_initFlag);180 RUN_TEST(test_exprIsConst_column_not_constant);181 RUN_TEST(test_exprIsConst_outer_on_disqualifies_when_flag2);182 RUN_TEST(test_exprIsConst_function_constargs_constant_with_flag4);183 RUN_TEST(test_exprIsConst_function_with_column_arg_not_constant_under_flag4);184 RUN_TEST(test_exprIsConst_variable_converted_to_null_when_flag5);185 RUN_TEST(test_exprIsConst_variable_disallowed_when_flag4);186 RUN_TEST(test_exprIsConst_id_true_converted_to_truefalse);187 RUN_TEST(test_exprIsConst_column_with_fixedcol_property_considered_constant);188 RUN_TEST(test_exprIsConst_raise_node_not_constant);189 RUN_TEST(test_exprIsConst_window_function_not_constant_under_flag4);190 RUN_TEST(test_exprIsConst_flag5_sets_FromDDL_on_functions);191 return UNITY_END();192}