sqlite / tests /tests_alter_renameResolveTrigger.c
AryaWu's picture
Upload folder using huggingface_hub
7510827 verified
#include "sqliteInt.h"
#include "unity.h"
#include <stdlib.h>
#include <string.h>
/* Wrapper for the static function under test (provided in build as per instructions) */
extern int test_renameResolveTrigger(Parse *pParse);
/* Helpers */
static void execSQL(sqlite3 *db, const char *sql){
int rc = sqlite3_exec(db, sql, 0, 0, 0);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
}
static void initParseAndTriggerWithTable(sqlite3 **pDb, Parse *pParse, Trigger **ppTrig, const char *zTable){
sqlite3 *db = 0;
int rc = sqlite3_open(":memory:", &db);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
/* Ensure a simple table exists */
char sql[256];
sqlite3_snprintf(sizeof(sql), sql, "CREATE TABLE %s(a, b);", zTable);
execSQL(db, sql);
memset(pParse, 0, sizeof(*pParse));
pParse->db = db;
Trigger *pTrig = (Trigger*)sqlite3DbMallocZero(db, sizeof(Trigger));
TEST_ASSERT_NOT_NULL(pTrig);
Table *pTab = sqlite3FindTable(db, zTable, "main");
TEST_ASSERT_NOT_NULL(pTab);
pTrig->pTabSchema = pTab->pSchema;
pTrig->table = sqlite3DbStrDup(db, zTable);
TEST_ASSERT_NOT_NULL(pTrig->table);
pTrig->op = TK_DELETE; /* default op; individual tests may override */
pTrig->pWhen = 0;
pTrig->step_list = 0;
pParse->pNewTrigger = pTrig;
*pDb = db;
*ppTrig = pTrig;
}
static Token makeToken(const char *z){
Token t;
t.z = z;
t.n = (int)strlen(z);
return t;
}
void setUp(void) {
/* Empty setup */
}
void tearDown(void) {
/* Empty teardown */
}
/* Test 1: Basic successful resolution for a simple trigger with no WHEN and no steps */
void test_renameResolveTrigger_basic_ok(void){
sqlite3 *db = 0;
Parse sParse;
Trigger *pTrig = 0;
initParseAndTriggerWithTable(&db, &sParse, &pTrig, "t1");
/* Change op to check that eTriggerOp is set */
pTrig->op = TK_INSERT;
int rc = test_renameResolveTrigger(&sParse);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
TEST_ASSERT_NOT_NULL(sParse.pTriggerTab);
TEST_ASSERT_EQUAL_INT(TK_INSERT, sParse.eTriggerOp);
/* Cleanup */
sqlite3DbFree(db, pTrig->table);
sqlite3DbFree(db, pTrig);
sqlite3_close(db);
}
/* Test 2: WHEN clause is a constant expression -> success */
void test_renameResolveTrigger_when_constant_ok(void){
sqlite3 *db = 0;
Parse sParse;
Trigger *pTrig = 0;
initParseAndTriggerWithTable(&db, &sParse, &pTrig, "t1");
/* WHEN 1 */
Token t1 = makeToken("1");
pTrig->pWhen = sqlite3ExprAlloc(db, TK_INTEGER, &t1, 0);
TEST_ASSERT_NOT_NULL(pTrig->pWhen);
int rc = test_renameResolveTrigger(&sParse);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
/* Cleanup */
sqlite3ExprDelete(db, pTrig->pWhen);
sqlite3DbFree(db, pTrig->table);
sqlite3DbFree(db, pTrig);
sqlite3_close(db);
}
/* Test 3: WHEN clause references a non-existent column -> expect error */
void test_renameResolveTrigger_when_bad_column_error(void){
sqlite3 *db = 0;
Parse sParse;
Trigger *pTrig = 0;
initParseAndTriggerWithTable(&db, &sParse, &pTrig, "t1");
/* WHEN nosuchcol */
Token tBad = makeToken("nosuchcol");
pTrig->pWhen = sqlite3ExprAlloc(db, TK_ID, &tBad, 0);
TEST_ASSERT_NOT_NULL(pTrig->pWhen);
int rc = test_renameResolveTrigger(&sParse);
TEST_ASSERT_NOT_EQUAL_INT(SQLITE_OK, rc);
/* Cleanup */
sqlite3ExprDelete(db, pTrig->pWhen);
sqlite3DbFree(db, pTrig->table);
sqlite3DbFree(db, pTrig);
sqlite3_close(db);
}
/* Test 4: Trigger step contains a minimal SELECT -> success */
void test_renameResolveTrigger_step_with_select_ok(void){
sqlite3 *db = 0;
Parse sParse;
Trigger *pTrig = 0;
initParseAndTriggerWithTable(&db, &sParse, &pTrig, "t1");
TriggerStep *pStep = (TriggerStep*)sqlite3DbMallocZero(db, sizeof(TriggerStep));
TEST_ASSERT_NOT_NULL(pStep);
/* Minimal select */
pStep->pSelect = sqlite3SelectNew(&sParse, 0, 0, 0, 0, 0, 0, 0, 0);
TEST_ASSERT_NOT_NULL(pStep->pSelect);
pTrig->step_list = pStep;
int rc = test_renameResolveTrigger(&sParse);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
/* Cleanup */
sqlite3SelectDelete(db, pStep->pSelect);
sqlite3DbFree(db, pStep);
sqlite3DbFree(db, pTrig->table);
sqlite3DbFree(db, pTrig);
sqlite3_close(db);
}
/* Test 5: Trigger step contains a SrcList referencing existing table and a WHERE that resolves -> success */
void test_renameResolveTrigger_step_with_src_and_where_ok(void){
sqlite3 *db = 0;
Parse sParse;
Trigger *pTrig = 0;
initParseAndTriggerWithTable(&db, &sParse, &pTrig, "t1");
TriggerStep *pStep = (TriggerStep*)sqlite3DbMallocZero(db, sizeof(TriggerStep));
TEST_ASSERT_NOT_NULL(pStep);
/* Build a minimal SrcList with one term "t1" (in "main") */
SrcList *pSrc = (SrcList*)sqlite3DbMallocZero(db, sizeof(SrcList));
TEST_ASSERT_NOT_NULL(pSrc);
pSrc->nSrc = 1;
pSrc->a[0].zName = sqlite3DbStrDup(db, "t1");
TEST_ASSERT_NOT_NULL(pSrc->a[0].zName);
pSrc->a[0].zDatabase = sqlite3DbStrDup(db, "main");
TEST_ASSERT_NOT_NULL(pSrc->a[0].zDatabase);
pStep->pSrc = pSrc;
/* WHERE a (column of t1) */
Token tA = makeToken("a");
pStep->pWhere = sqlite3ExprAlloc(db, TK_ID, &tA, 0);
TEST_ASSERT_NOT_NULL(pStep->pWhere);
pTrig->step_list = pStep;
int rc = test_renameResolveTrigger(&sParse);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
/* Cleanup original (the function deletes its duplicate internally) */
sqlite3ExprDelete(db, pStep->pWhere);
sqlite3SrcListDelete(db, pStep->pSrc);
sqlite3DbFree(db, pStep);
sqlite3DbFree(db, pTrig->table);
sqlite3DbFree(db, pTrig);
sqlite3_close(db);
}
int main(void){
UNITY_BEGIN();
RUN_TEST(test_renameResolveTrigger_basic_ok);
RUN_TEST(test_renameResolveTrigger_when_constant_ok);
RUN_TEST(test_renameResolveTrigger_when_bad_column_error);
RUN_TEST(test_renameResolveTrigger_step_with_select_ok);
RUN_TEST(test_renameResolveTrigger_step_with_src_and_where_ok);
return UNITY_END();
}