| #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(); |
| } |