sqlite / tests /tests_alter_renameColumnElistNames.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 provided by the module under test */
extern void test_renameColumnElistNames(
Parse *pParse,
RenameCtx *pCtx,
const ExprList *pEList,
const char *zOld
);
/* Helper to open a database and initialize a Parse object */
static void openDbAndInitParse(sqlite3 **ppDb, Parse *pParse){
sqlite3 *db = 0;
int rc = sqlite3_open(":memory:", &db);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
memset(pParse, 0, sizeof(*pParse));
pParse->db = db;
*ppDb = db;
}
/* Helper to create an identifier expression */
static Expr* makeIdExpr(sqlite3 *db, const char *z){
Token t;
t.z = z;
t.n = (int)strlen(z);
return sqlite3ExprAlloc(db, TK_ID, &t, 0);
}
/* Helper to append an expression with a specific alias name (zAlias) to an ExprList.
Returns the zEName pointer assigned inside the list (owned by db). */
static const char* appendExprWithAlias(Parse *pParse, ExprList **ppList, const char *zExpr, const char *zAlias){
ExprList *pList = *ppList;
Expr *pExpr = makeIdExpr(pParse->db, zExpr ? zExpr : "x");
pList = sqlite3ExprListAppend(pParse, pList, pExpr);
TEST_ASSERT_NOT_NULL(pList);
Token aliasTok;
aliasTok.z = zAlias;
aliasTok.n = (int)strlen(zAlias);
sqlite3ExprListSetName(pParse, pList, &aliasTok, 1);
*ppList = pList;
/* Return the actual stored alias pointer */
return pList->a[pList->nExpr-1].zEName;
}
/* Helper to map a zEName pointer to a token for rename machinery */
static void mapNameToken(Parse *pParse, const char *zName, const char *zTok){
Token t;
t.z = zTok;
t.n = (int)strlen(zTok);
sqlite3RenameTokenMap(pParse, (void*)zName, &t);
}
void setUp(void) {
/* Setup code here, or leave empty */
}
void tearDown(void) {
/* Cleanup code here, or leave empty */
}
/* Test: pEList is NULL -> no crash, no tokens added */
void test_renameColumnElistNames_null_list(void){
sqlite3 *db = 0;
Parse sParse;
openDbAndInitParse(&db, &sParse);
RenameCtx ctx;
memset(&ctx, 0, sizeof(ctx));
/* Ensure ctx has pParse for any allocations */
ctx.pParse = &sParse;
test_renameColumnElistNames(&sParse, &ctx, NULL, "x");
TEST_ASSERT_EQUAL_INT(0, ctx.nList);
sqlite3_close(db);
}
/* Test: No names match zOld -> no tokens added */
void test_renameColumnElistNames_no_matches(void){
sqlite3 *db = 0;
Parse sParse;
openDbAndInitParse(&db, &sParse);
ExprList *pList = NULL;
const char *zA = appendExprWithAlias(&sParse, &pList, "col1", "A");
const char *zB = appendExprWithAlias(&sParse, &pList, "col2", "B");
const char *zC = appendExprWithAlias(&sParse, &pList, "col3", "C");
/* Map tokens (though they won't be used since names do not match) */
mapNameToken(&sParse, zA, "TOK_A");
mapNameToken(&sParse, zB, "TOK_B");
mapNameToken(&sParse, zC, "TOK_C");
RenameCtx ctx;
memset(&ctx, 0, sizeof(ctx));
ctx.pParse = &sParse;
test_renameColumnElistNames(&sParse, &ctx, pList, "Z"); /* no matches expected */
TEST_ASSERT_EQUAL_INT(0, ctx.nList);
sqlite3ExprListDelete(sParse.db, pList);
sqlite3_close(db);
}
/* Test: Single match; case-insensitive */
void test_renameColumnElistNames_single_match_case_insensitive(void){
sqlite3 *db = 0;
Parse sParse;
openDbAndInitParse(&db, &sParse);
ExprList *pList = NULL;
const char *zFoo = appendExprWithAlias(&sParse, &pList, "col1", "Foo");
const char *zBar = appendExprWithAlias(&sParse, &pList, "col2", "Bar");
mapNameToken(&sParse, zFoo, "TOK_FOO");
mapNameToken(&sParse, zBar, "TOK_BAR");
RenameCtx ctx;
memset(&ctx, 0, sizeof(ctx));
ctx.pParse = &sParse;
test_renameColumnElistNames(&sParse, &ctx, pList, "fOO"); /* should match "Foo" */
TEST_ASSERT_EQUAL_INT(1, ctx.nList);
TEST_ASSERT_NOT_NULL(ctx.aList);
TEST_ASSERT_TRUE(ctx.aList[0].n > 0);
/* cleanup */
sqlite3DbFree(sParse.db, ctx.aList);
sqlite3ExprListDelete(sParse.db, pList);
sqlite3_close(db);
}
/* Test: Multiple matches, including different cases */
void test_renameColumnElistNames_multiple_matches(void){
sqlite3 *db = 0;
Parse sParse;
openDbAndInitParse(&db, &sParse);
ExprList *pList = NULL;
const char *zX1 = appendExprWithAlias(&sParse, &pList, "c1", "x");
const char *zX2 = appendExprWithAlias(&sParse, &pList, "c2", "X");
const char *zY = appendExprWithAlias(&sParse, &pList, "c3", "y");
const char *zX3 = appendExprWithAlias(&sParse, &pList, "c4", "x");
mapNameToken(&sParse, zX1, "TOK_X1");
mapNameToken(&sParse, zX2, "TOK_X2");
mapNameToken(&sParse, zY, "TOK_Y");
mapNameToken(&sParse, zX3, "TOK_X3");
RenameCtx ctx;
memset(&ctx, 0, sizeof(ctx));
ctx.pParse = &sParse;
test_renameColumnElistNames(&sParse, &ctx, pList, "x");
TEST_ASSERT_EQUAL_INT(3, ctx.nList);
sqlite3DbFree(sParse.db, ctx.aList);
sqlite3ExprListDelete(sParse.db, pList);
sqlite3_close(db);
}
/* Test: Entries with eEName != ENAME_NAME are ignored */
void test_renameColumnElistNames_ignores_non_ENAME_NAME(void){
sqlite3 *db = 0;
Parse sParse;
openDbAndInitParse(&db, &sParse);
ExprList *pList = NULL;
const char *zTgtIgnored = appendExprWithAlias(&sParse, &pList, "c1", "tgt");
const char *zTgtMatch = appendExprWithAlias(&sParse, &pList, "c2", "tgt");
/* Force the first entry to have a non-name eEName (e.g. ENAME_SPAN) */
TEST_ASSERT_TRUE(pList->nExpr >= 2);
pList->a[0].fg.eEName = ENAME_SPAN; /* ensure it is ignored */
/* The second entry remains ENAME_NAME as set by sqlite3ExprListSetName */
mapNameToken(&sParse, zTgtIgnored, "TOK_IGN");
mapNameToken(&sParse, zTgtMatch, "TOK_MATCH");
RenameCtx ctx;
memset(&ctx, 0, sizeof(ctx));
ctx.pParse = &sParse;
test_renameColumnElistNames(&sParse, &ctx, pList, "TGT");
TEST_ASSERT_EQUAL_INT(1, ctx.nList);
sqlite3DbFree(sParse.db, ctx.aList);
sqlite3ExprListDelete(sParse.db, pList);
sqlite3_close(db);
}
/* Test: Entries with zEName == NULL are safely ignored (no crash, no addition) */
void test_renameColumnElistNames_ignores_null_zEName(void){
sqlite3 *db = 0;
Parse sParse;
openDbAndInitParse(&db, &sParse);
ExprList *pList = NULL;
const char *zGood = appendExprWithAlias(&sParse, &pList, "c2", "Alive");
/* Add another element and then nullify its zEName */
(void)appendExprWithAlias(&sParse, &pList, "cNULL", "NullName");
pList->a[pList->nExpr-1].zEName = NULL; /* simulate missing name */
/* Ensure eEName is ENAME_NAME for both; the NULL zEName should still be ignored */
pList->a[0].fg.eEName = ENAME_NAME;
pList->a[1].fg.eEName = ENAME_NAME;
mapNameToken(&sParse, zGood, "TOK_ALIVE");
RenameCtx ctx;
memset(&ctx, 0, sizeof(ctx));
ctx.pParse = &sParse;
test_renameColumnElistNames(&sParse, &ctx, pList, "Alive");
TEST_ASSERT_EQUAL_INT(1, ctx.nList);
sqlite3DbFree(sParse.db, ctx.aList);
sqlite3ExprListDelete(sParse.db, pList);
sqlite3_close(db);
}
int main(void){
UNITY_BEGIN();
RUN_TEST(test_renameColumnElistNames_null_list);
RUN_TEST(test_renameColumnElistNames_no_matches);
RUN_TEST(test_renameColumnElistNames_single_match_case_insensitive);
RUN_TEST(test_renameColumnElistNames_multiple_matches);
RUN_TEST(test_renameColumnElistNames_ignores_non_ENAME_NAME);
RUN_TEST(test_renameColumnElistNames_ignores_null_zEName);
return UNITY_END();
}