|
|
#include "sqliteInt.h" |
|
|
#include "unity.h" |
|
|
#include <stdlib.h> |
|
|
#include <string.h> |
|
|
|
|
|
extern void test_renameWalkWith(Walker *pWalker, Select *pSelect); |
|
|
|
|
|
static sqlite3 *gDb = NULL; |
|
|
|
|
|
|
|
|
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; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
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; |
|
|
} |
|
|
|
|
|
|
|
|
static With *allocWith(int nCte, Select **apSel){ |
|
|
|
|
|
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; |
|
|
p->a[i].zName = 0; |
|
|
p->a[i].zCteErr = 0; |
|
|
} |
|
|
return p; |
|
|
} |
|
|
|
|
|
|
|
|
static int countSelectCb(Walker *pWalker, Select *pSel){ |
|
|
(void)pSel; |
|
|
int *pCnt = (int*)pWalker->u.p; |
|
|
if( pCnt ) (*pCnt)++; |
|
|
return WRC_Continue; |
|
|
} |
|
|
|
|
|
|
|
|
void test_renameWalkWith_no_with_clause(void){ |
|
|
Parse sParse; |
|
|
memset(&sParse, 0, sizeof(sParse)); |
|
|
sParse.db = gDb; |
|
|
|
|
|
|
|
|
With *pOuter = allocWith(1, NULL); |
|
|
sParse.pWith = pOuter; |
|
|
|
|
|
|
|
|
Select *pTop = allocSelect(SF_Expanded); |
|
|
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); |
|
|
TEST_ASSERT_EQUAL_PTR(pOuter, sParse.pWith); |
|
|
} |
|
|
|
|
|
|
|
|
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; |
|
|
|
|
|
|
|
|
Select *pCTE1 = allocSelect(SF_Expanded); |
|
|
Select *pCTE2 = allocSelect(SF_Expanded); |
|
|
Select *apCTE[2] = { pCTE1, pCTE2 }; |
|
|
|
|
|
With *pWith = allocWith(2, apCTE); |
|
|
|
|
|
|
|
|
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); |
|
|
TEST_ASSERT_EQUAL_PTR(pOuter, sParse.pWith); |
|
|
} |
|
|
|
|
|
|
|
|
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; |
|
|
|
|
|
|
|
|
Select *pCTE1 = allocSelect(0); |
|
|
Select *pCTE2 = allocSelect(0); |
|
|
Select *pCTE3 = allocSelect(0); |
|
|
Select *apCTE[3] = { pCTE1, pCTE2, pCTE3 }; |
|
|
|
|
|
With *pWith = allocWith(3, apCTE); |
|
|
|
|
|
|
|
|
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); |
|
|
TEST_ASSERT_EQUAL_PTR(pOuter, sParse.pWith); |
|
|
} |
|
|
|
|
|
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(); |
|
|
} |