sqlite / tests /tests_alter_renameWalkWith.c
AryaWu's picture
Upload folder using huggingface_hub
7510827 verified
#include "sqliteInt.h"
#include "unity.h"
#include <stdlib.h>
#include <string.h>
extern void test_renameWalkWith(Walker *pWalker, Select *pSelect);
static sqlite3 *gDb = NULL;
/* Unity setup/teardown */
void setUp(void) {
int rc = sqlite3_open(":memory:", &gDb);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
TEST_ASSERT_NOT_NULL(gDb);
}
void tearDown(void) {
if (gDb) {
sqlite3_close(gDb);
gDb = NULL;
}
}
/* Helper: allocate a minimal Select with given selFlags */
static Select *allocSelect(u32 selFlags){
Select *p = (Select*)sqlite3DbMallocZero(gDb, sizeof(Select));
TEST_ASSERT_NOT_NULL_MESSAGE(p, "allocSelect failed");
p->selFlags = selFlags;
return p;
}
/* Helper: allocate a With object with nCte entries and the provided Selects */
static With *allocWith(int nCte, Select **apSel){
/* With uses a flexible array member a[1] */
int nByte = (int)(sizeof(With) + (nCte-1) * sizeof(p->a[0]));
With *p = (With*)sqlite3DbMallocZero(gDb, nByte);
TEST_ASSERT_NOT_NULL_MESSAGE(p, "allocWith failed");
p->nCte = nCte;
p->pOuter = 0;
for(int i=0; i<nCte; i++){
p->a[i].pSelect = apSel ? apSel[i] : 0;
p->a[i].pCols = 0; /* keep NULL to avoid rename mapping side-effects */
p->a[i].zName = 0; /* not needed for these tests */
p->a[i].zCteErr = 0;
}
return p;
}
/* Walker select callback that increments a counter in walker.u.p */
static int countSelectCb(Walker *pWalker, Select *pSel){
(void)pSel;
int *pCnt = (int*)pWalker->u.p;
if( pCnt ) (*pCnt)++;
return WRC_Continue;
}
/* Test 1: When pSelect->pWith is NULL, nothing happens */
void test_renameWalkWith_no_with_clause(void){
Parse sParse;
memset(&sParse, 0, sizeof(sParse));
sParse.db = gDb;
/* Create a dummy outer WITH to ensure pParse->pWith is not touched */
With *pOuter = allocWith(1, NULL);
sParse.pWith = pOuter;
/* Minimal top-level SELECT with no WITH clause */
Select *pTop = allocSelect(SF_Expanded); /* flags irrelevant here */
pTop->pWith = NULL;
int count = 0;
Walker w;
memset(&w, 0, sizeof(w));
w.pParse = &sParse;
w.xSelectCallback = countSelectCb;
w.u.p = &count;
test_renameWalkWith(&w, pTop);
TEST_ASSERT_EQUAL_INT(0, count); /* no CTEs walked */
TEST_ASSERT_EQUAL_PTR(pOuter, sParse.pWith); /* unchanged */
}
/* Test 2: WITH present with SF_Expanded set: walks each CTE; no stack push/pop */
void test_renameWalkWith_expanded_with_multiple_ctes(void){
Parse sParse;
memset(&sParse, 0, sizeof(sParse));
sParse.db = gDb;
With *pOuter = allocWith(1, NULL);
sParse.pWith = pOuter;
/* Create two simple CTE selects with SF_Expanded set */
Select *pCTE1 = allocSelect(SF_Expanded);
Select *pCTE2 = allocSelect(SF_Expanded);
Select *apCTE[2] = { pCTE1, pCTE2 };
With *pWith = allocWith(2, apCTE);
/* Top-level select that carries the WITH clause */
Select *pTop = allocSelect(0);
pTop->pWith = pWith;
int count = 0;
Walker w;
memset(&w, 0, sizeof(w));
w.pParse = &sParse;
w.xSelectCallback = countSelectCb;
w.u.p = &count;
test_renameWalkWith(&w, pTop);
TEST_ASSERT_EQUAL_INT(2, count); /* walked both CTEs */
TEST_ASSERT_EQUAL_PTR(pOuter, sParse.pWith); /* no push/pop -> unchanged */
}
/* Test 3: WITH present with SF_Expanded not set: pushes/pops with-stack and walks each CTE */
void test_renameWalkWith_push_and_pop_with_stack(void){
Parse sParse;
memset(&sParse, 0, sizeof(sParse));
sParse.db = gDb;
With *pOuter = allocWith(1, NULL);
sParse.pWith = pOuter;
/* Create three simple CTE selects with SF_Expanded unset to force push/dup */
Select *pCTE1 = allocSelect(0);
Select *pCTE2 = allocSelect(0);
Select *pCTE3 = allocSelect(0);
Select *apCTE[3] = { pCTE1, pCTE2, pCTE3 };
With *pWith = allocWith(3, apCTE);
/* Top-level select that carries the WITH clause */
Select *pTop = allocSelect(0);
pTop->pWith = pWith;
int count = 0;
Walker w;
memset(&w, 0, sizeof(w));
w.pParse = &sParse;
w.xSelectCallback = countSelectCb;
w.u.p = &count;
test_renameWalkWith(&w, pTop);
TEST_ASSERT_EQUAL_INT(3, count); /* walked all CTEs */
TEST_ASSERT_EQUAL_PTR(pOuter, sParse.pWith); /* stack restored after pop */
}
int main(void){
UNITY_BEGIN();
RUN_TEST(test_renameWalkWith_no_with_clause);
RUN_TEST(test_renameWalkWith_expanded_with_multiple_ctes);
RUN_TEST(test_renameWalkWith_push_and_pop_with_stack);
return UNITY_END();
}