sqlite / tests /tests_alter_renameParseCleanup.c
AryaWu's picture
Upload folder using huggingface_hub
7510827 verified
#include "sqliteInt.h"
#include "unity.h"
#include <string.h>
/* The wrapper for the static function under test (provided in the module). */
extern void test_renameParseCleanup(Parse *pParse);
static void init_parse_with_allocs(sqlite3 *db, Parse *pParse){
memset(pParse, 0, sizeof(*pParse));
pParse->db = db;
/* Create a VDBE so that finalize is exercised. */
pParse->pVdbe = sqlite3VdbeCreate(db);
/* Allocate a new Table */
pParse->pNewTable = (Table*)sqlite3DbMallocZero(db, sizeof(Table));
/* Allocate a linked list of Index objects */
Index *pIdx1 = (Index*)sqlite3DbMallocZero(db, sizeof(Index));
Index *pIdx2 = (Index*)sqlite3DbMallocZero(db, sizeof(Index));
if( pIdx1 ) pIdx1->pNext = pIdx2;
pParse->pNewIndex = pIdx1;
/* Allocate a Trigger */
pParse->pNewTrigger = (Trigger*)sqlite3DbMallocZero(db, sizeof(Trigger));
/* Allocate an error message */
pParse->zErrMsg = sqlite3DbStrDup(db, "unit-test-error");
/* Allocate a linked list of RenameToken */
RenameToken *t1 = (RenameToken*)sqlite3DbMallocZero(db, sizeof(RenameToken));
RenameToken *t2 = (RenameToken*)sqlite3DbMallocZero(db, sizeof(RenameToken));
if( t1 ) t1->pNext = t2;
pParse->pRename = t1;
}
void setUp(void) {
/* No-op */
}
void tearDown(void) {
/* No-op */
}
static void assert_parse_pointers_cleared(Parse *p){
TEST_ASSERT_NULL(p->pVdbe);
TEST_ASSERT_NULL(p->pNewTable);
TEST_ASSERT_NULL(p->pNewIndex);
TEST_ASSERT_NULL(p->pNewTrigger);
TEST_ASSERT_NULL(p->zErrMsg);
TEST_ASSERT_NULL(p->pRename);
}
/* Test that renameParseCleanup frees all populated fields and resets them. */
void test_renameParseCleanup_clears_all_fields(void){
sqlite3 *db = 0;
int rc = sqlite3_open(":memory:", &db);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
TEST_ASSERT_NOT_NULL(db);
Parse p;
init_parse_with_allocs(db, &p);
test_renameParseCleanup(&p);
/* After cleanup, all relevant pointers should be NULL. */
assert_parse_pointers_cleared(&p);
/* Database should be cleanly closable (VDBE finalized). */
rc = sqlite3_close(db);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
}
/* Test that renameParseCleanup is safe when all fields are NULL. */
void test_renameParseCleanup_handles_null_fields(void){
sqlite3 *db = 0;
int rc = sqlite3_open(":memory:", &db);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
TEST_ASSERT_NOT_NULL(db);
Parse p;
memset(&p, 0, sizeof(p));
p.db = db;
/* Everything NULL already */
test_renameParseCleanup(&p);
/* Still NULL after cleanup */
assert_parse_pointers_cleared(&p);
rc = sqlite3_close(db);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
}
/* Test with longer lists of Index and RenameToken to ensure full traversal/free. */
void test_renameParseCleanup_multiple_indexes_and_tokens(void){
sqlite3 *db = 0;
int rc = sqlite3_open(":memory:", &db);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
TEST_ASSERT_NOT_NULL(db);
Parse p;
memset(&p, 0, sizeof(p));
p.db = db;
/* Create a VDBE */
p.pVdbe = sqlite3VdbeCreate(db);
/* Create 3 Index nodes */
Index *i1 = (Index*)sqlite3DbMallocZero(db, sizeof(Index));
Index *i2 = (Index*)sqlite3DbMallocZero(db, sizeof(Index));
Index *i3 = (Index*)sqlite3DbMallocZero(db, sizeof(Index));
if( i1 ) i1->pNext = i2;
if( i2 ) i2->pNext = i3;
p.pNewIndex = i1;
/* Create 3 RenameToken nodes */
RenameToken *t1 = (RenameToken*)sqlite3DbMallocZero(db, sizeof(RenameToken));
RenameToken *t2 = (RenameToken*)sqlite3DbMallocZero(db, sizeof(RenameToken));
RenameToken *t3 = (RenameToken*)sqlite3DbMallocZero(db, sizeof(RenameToken));
if( t1 ) t1->pNext = t2;
if( t2 ) t2->pNext = t3;
p.pRename = t1;
/* Also set a table, trigger, and error message */
p.pNewTable = (Table*)sqlite3DbMallocZero(db, sizeof(Table));
p.pNewTrigger = (Trigger*)sqlite3DbMallocZero(db, sizeof(Trigger));
p.zErrMsg = sqlite3DbStrDup(db, "err");
test_renameParseCleanup(&p);
/* Ensure all pointers are cleared */
assert_parse_pointers_cleared(&p);
rc = sqlite3_close(db);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
}
/* Test idempotency: calling cleanup twice should be safe and keep pointers NULL. */
void test_renameParseCleanup_idempotent_double_call(void){
sqlite3 *db = 0;
int rc = sqlite3_open(":memory:", &db);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
TEST_ASSERT_NOT_NULL(db);
Parse p;
init_parse_with_allocs(db, &p);
/* First cleanup */
test_renameParseCleanup(&p);
assert_parse_pointers_cleared(&p);
/* Second cleanup - should be a no-op and not crash */
test_renameParseCleanup(&p);
assert_parse_pointers_cleared(&p);
rc = sqlite3_close(db);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
}
int main(void){
UNITY_BEGIN();
RUN_TEST(test_renameParseCleanup_clears_all_fields);
RUN_TEST(test_renameParseCleanup_handles_null_fields);
RUN_TEST(test_renameParseCleanup_multiple_indexes_and_tokens);
RUN_TEST(test_renameParseCleanup_idempotent_double_call);
return UNITY_END();
}