File size: 4,316 Bytes
7510827 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
#include "sqliteInt.h"
#include "unity.h"
#include <stdlib.h>
#include <string.h>
/* Global test database connection */
static sqlite3 *gDb = NULL;
/* Wrapper provided by the module for testing the static function */
extern void test_renameTestSchema(
Parse *pParse,
const char *zDb,
int bTemp,
const char *zWhen,
int bNoDQS
);
/* Provide sqlite_rename_test function so nested parses compile and run */
static void xRenameTestFunc(sqlite3_context *ctx, int argc, sqlite3_value **argv){
/* This function is used by nested parse SQL: return NULL to satisfy "=NULL" */
SQLITE_USE(argc);
SQLITE_USE(argv);
sqlite3_result_null(ctx);
}
/* Helper: initialize a fresh Parse object bound to gDb */
static void initParse(Parse *p){
memset(p, 0, sizeof(*p));
p->db = gDb;
}
/* Helper: cleanup VDBE and error message in Parse to avoid leaks */
static void cleanupParse(Parse *p){
if( p->pVdbe ){
sqlite3VdbeDelete(p->pVdbe);
p->pVdbe = 0;
}
if( p->zErrMsg ){
sqlite3DbFree(p->db, p->zErrMsg);
p->zErrMsg = 0;
}
}
void setUp(void) {
int rc = sqlite3_open(":memory:", &gDb);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
/* Register sqlite_rename_test(name in SQL) with 6 args */
rc = sqlite3_create_function(gDb, "sqlite_rename_test", 6,
SQLITE_UTF8, 0,
xRenameTestFunc, 0, 0);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
}
void tearDown(void) {
if( gDb ){
int rc = sqlite3_close(gDb);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
gDb = NULL;
}
}
/* Basic sanity: sets colNamesSet, creates a VDBE, and emits some code */
void test_renameTestSchema_sets_colNamesSet_and_creates_vdbe(void){
Parse p;
initParse(&p);
test_renameTestSchema(&p, "main", 0, "during rename", 0);
/* Verify colNamesSet is set */
TEST_ASSERT_EQUAL_INT(1, p.colNamesSet);
/* Verify a VDBE was created and has some ops */
TEST_ASSERT_NOT_NULL(p.pVdbe);
int nOp = sqlite3VdbeCurrentAddr(p.pVdbe);
TEST_ASSERT_TRUE(nOp > 0);
cleanupParse(&p);
}
/* bTemp affects the number of nested parses: 0 => two queries, 1 => one query */
void test_renameTestSchema_bTemp_affects_instruction_count(void){
Parse p1, p2;
initParse(&p1);
initParse(&p2);
/* One nested parse (temp db only) */
test_renameTestSchema(&p1, "temp", 1, "phase A", 0);
TEST_ASSERT_EQUAL_INT(1, p1.colNamesSet);
TEST_ASSERT_NOT_NULL(p1.pVdbe);
int nOp1 = sqlite3VdbeCurrentAddr(p1.pVdbe);
TEST_ASSERT_TRUE(nOp1 > 0);
/* Two nested parses (main + temp) */
test_renameTestSchema(&p2, "main", 0, "phase B", 0);
TEST_ASSERT_EQUAL_INT(1, p2.colNamesSet);
TEST_ASSERT_NOT_NULL(p2.pVdbe);
int nOp2 = sqlite3VdbeCurrentAddr(p2.pVdbe);
TEST_ASSERT_TRUE(nOp2 > 0);
/* Expect more ops when bTemp==0 due to the extra nested SELECT */
TEST_ASSERT_TRUE(nOp2 > nOp1);
cleanupParse(&p1);
cleanupParse(&p2);
}
/* Using "temp" db name with bTemp==1 should still function correctly */
void test_renameTestSchema_temp_db_only(void){
Parse p;
initParse(&p);
test_renameTestSchema(&p, "temp", 1, "temp-only", 1 /* bNoDQS */);
TEST_ASSERT_EQUAL_INT(1, p.colNamesSet);
TEST_ASSERT_NOT_NULL(p.pVdbe);
int nOp = sqlite3VdbeCurrentAddr(p.pVdbe);
TEST_ASSERT_TRUE(nOp > 0);
cleanupParse(&p);
}
/* Ensure NULL zWhen and varying bNoDQS do not crash and still generate code */
void test_renameTestSchema_null_when_and_noDQS_variations(void){
Parse pA, pB;
initParse(&pA);
initParse(&pB);
/* zWhen NULL, bNoDQS = 0 */
test_renameTestSchema(&pA, "main", 0, NULL, 0);
TEST_ASSERT_EQUAL_INT(1, pA.colNamesSet);
TEST_ASSERT_NOT_NULL(pA.pVdbe);
int nOpA = sqlite3VdbeCurrentAddr(pA.pVdbe);
TEST_ASSERT_TRUE(nOpA > 0);
/* zWhen NULL, bNoDQS = 1 */
test_renameTestSchema(&pB, "main", 0, NULL, 1);
TEST_ASSERT_EQUAL_INT(1, pB.colNamesSet);
TEST_ASSERT_NOT_NULL(pB.pVdbe);
int nOpB = sqlite3VdbeCurrentAddr(pB.pVdbe);
TEST_ASSERT_TRUE(nOpB > 0);
cleanupParse(&pA);
cleanupParse(&pB);
}
int main(void) {
UNITY_BEGIN();
RUN_TEST(test_renameTestSchema_sets_colNamesSet_and_creates_vdbe);
RUN_TEST(test_renameTestSchema_bTemp_affects_instruction_count);
RUN_TEST(test_renameTestSchema_temp_db_only);
RUN_TEST(test_renameTestSchema_null_when_and_noDQS_variations);
return UNITY_END();
} |