| #include "sqliteInt.h" |
| #include "unity.h" |
| #include <string.h> |
| #include <stdlib.h> |
|
|
| |
| extern int test_renameUnmapSelectCb(Walker *pWalker, Select *p); |
|
|
| |
| static int g_expr_walk_count = 0; |
|
|
| |
| static int testExprCallback(Walker *pWalker, Expr *pExpr){ |
| (void)pWalker; |
| (void)pExpr; |
| g_expr_walk_count++; |
| return WRC_Continue; |
| } |
|
|
| void setUp(void) { |
| |
| } |
|
|
| void tearDown(void) { |
| |
| } |
|
|
| |
| static RenameToken* addRenameToken(Parse *pParse, const void *pTarget){ |
| RenameToken *pTok = (RenameToken*)sqlite3DbMallocZero(pParse->db, sizeof(RenameToken)); |
| TEST_ASSERT_NOT_NULL_MESSAGE(pTok, "Failed to allocate RenameToken"); |
| pTok->p = (void*)pTarget; |
| pTok->pNext = pParse->pRename; |
| pParse->pRename = pTok; |
| return pTok; |
| } |
|
|
| |
| static ExprList* makeEmptyExprList(sqlite3 *db){ |
| ExprList *p = (ExprList*)sqlite3DbMallocZero(db, sizeof(ExprList)); |
| TEST_ASSERT_NOT_NULL_MESSAGE(p, "Failed to allocate ExprList"); |
| |
| return p; |
| } |
|
|
| |
| static SrcList* makeEmptySrcList(sqlite3 *db){ |
| SrcList *p = (SrcList*)sqlite3DbMallocZero(db, sizeof(SrcList)); |
| TEST_ASSERT_NOT_NULL_MESSAGE(p, "Failed to allocate SrcList"); |
| |
| return p; |
| } |
|
|
| |
| static ExprList* makeExprListWithN(sqlite3 *db, int n){ |
| ExprList *p = (ExprList*)sqlite3DbMallocZero(db, sizeof(ExprList)); |
| TEST_ASSERT_NOT_NULL_MESSAGE(p, "Failed to allocate ExprList"); |
| p->nExpr = n; |
| if( n>0 ){ |
| p->a = (struct ExprList_item*)sqlite3DbMallocZero(db, sizeof(struct ExprList_item) * n); |
| TEST_ASSERT_NOT_NULL_MESSAGE(p->a, "Failed to allocate ExprList_item array"); |
| } |
| return p; |
| } |
|
|
| |
| static SrcList* makeSrcListWithN(sqlite3 *db, int n){ |
| SrcList *p = (SrcList*)sqlite3DbMallocZero(db, sizeof(SrcList)); |
| TEST_ASSERT_NOT_NULL_MESSAGE(p, "Failed to allocate SrcList"); |
| p->nSrc = n; |
| if( n>0 ){ |
| p->a = (struct SrcList_item*)sqlite3DbMallocZero(db, sizeof(struct SrcList_item) * n); |
| TEST_ASSERT_NOT_NULL_MESSAGE(p->a, "Failed to allocate SrcList_item array"); |
| } |
| return p; |
| } |
|
|
| |
| static IdList* makeIdList(sqlite3 *db, int n, const char **names){ |
| IdList *p = (IdList*)sqlite3DbMallocZero(db, sizeof(IdList)); |
| TEST_ASSERT_NOT_NULL_MESSAGE(p, "Failed to allocate IdList"); |
| p->nId = n; |
| if( n>0 ){ |
| p->a = (struct IdList_item*)sqlite3DbMallocZero(db, sizeof(struct IdList_item) * n); |
| TEST_ASSERT_NOT_NULL_MESSAGE(p->a, "Failed to allocate IdList_item array"); |
| for(int i=0; i<n; i++){ |
| p->a[i].zName = (char*)names[i]; |
| } |
| } |
| return p; |
| } |
|
|
| |
| void test_renameUnmapSelectCb_returns_abort_if_nErr(void){ |
| sqlite3 *db = 0; |
| TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
|
|
| Parse sParse; |
| memset(&sParse, 0, sizeof(sParse)); |
| sParse.db = db; |
| sParse.nErr = 1; |
|
|
| Walker w; |
| memset(&w, 0, sizeof(w)); |
| w.pParse = &sParse; |
| w.xExprCallback = testExprCallback; |
|
|
| Select sSel; |
| memset(&sSel, 0, sizeof(sSel)); |
| sSel.pEList = makeEmptyExprList(db); |
| sSel.pSrc = makeEmptySrcList(db); |
|
|
| int rc = test_renameUnmapSelectCb(&w, &sSel); |
| TEST_ASSERT_EQUAL_INT(WRC_Abort, rc); |
|
|
| sqlite3_close(db); |
| } |
|
|
| |
| void test_renameUnmapSelectCb_prunes_on_view_and_preserves_tokens(void){ |
| sqlite3 *db = 0; |
| TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
|
|
| Parse sParse; |
| memset(&sParse, 0, sizeof(sParse)); |
| sParse.db = db; |
|
|
| Walker w; |
| memset(&w, 0, sizeof(w)); |
| w.pParse = &sParse; |
| w.xExprCallback = testExprCallback; |
|
|
| Select sSel; |
| memset(&sSel, 0, sizeof(sSel)); |
| sSel.selFlags = SF_View; |
| sSel.pEList = makeExprListWithN(db, 1); |
| sSel.pSrc = makeSrcListWithN(db, 1); |
|
|
| |
| const char *alias = "aliasA"; |
| const char *tname = "tabA"; |
| sSel.pEList->a[0].zEName = (char*)alias; |
| sSel.pEList->a[0].fg.eEName = ENAME_NAME; |
| sSel.pSrc->a[0].zName = (char*)tname; |
|
|
| RenameToken *pTokAlias = addRenameToken(&sParse, alias); |
| RenameToken *pTokTab = addRenameToken(&sParse, tname); |
|
|
| int rc = test_renameUnmapSelectCb(&w, &sSel); |
| TEST_ASSERT_EQUAL_INT(WRC_Prune, rc); |
|
|
| |
| TEST_ASSERT_EQUAL_PTR(alias, pTokAlias->p); |
| TEST_ASSERT_EQUAL_PTR(tname, pTokTab->p); |
|
|
| sqlite3_close(db); |
| } |
|
|
| |
| void test_renameUnmapSelectCb_unmaps_only_ENAME_NAME_aliases(void){ |
| sqlite3 *db = 0; |
| TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
|
|
| Parse sParse; |
| memset(&sParse, 0, sizeof(sParse)); |
| sParse.db = db; |
|
|
| Walker w; |
| memset(&w, 0, sizeof(w)); |
| w.pParse = &sParse; |
| w.xExprCallback = testExprCallback; |
|
|
| Select sSel; |
| memset(&sSel, 0, sizeof(sSel)); |
| sSel.pEList = makeExprListWithN(db, 2); |
| sSel.pSrc = makeEmptySrcList(db); |
|
|
| const char *alias1 = "alias1"; |
| const char *alias2 = "alias2"; |
| sSel.pEList->a[0].zEName = (char*)alias1; |
| sSel.pEList->a[0].fg.eEName = ENAME_NAME; |
| sSel.pEList->a[1].zEName = (char*)alias2; |
| sSel.pEList->a[1].fg.eEName = ENAME_NAME + 1; |
|
|
| RenameToken *pTok1 = addRenameToken(&sParse, alias1); |
| RenameToken *pTok2 = addRenameToken(&sParse, alias2); |
|
|
| int rc = test_renameUnmapSelectCb(&w, &sSel); |
| TEST_ASSERT_EQUAL_INT(WRC_Continue, rc); |
|
|
| TEST_ASSERT_EQUAL_PTR(NULL, pTok1->p); |
| TEST_ASSERT_EQUAL_PTR(alias2, pTok2->p); |
|
|
| sqlite3_close(db); |
| } |
|
|
| |
| void test_renameUnmapSelectCb_unmaps_srclist_and_walks_on_or_using(void){ |
| sqlite3 *db = 0; |
| TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
|
|
| Parse sParse; |
| memset(&sParse, 0, sizeof(sParse)); |
| sParse.db = db; |
|
|
| Walker w; |
| memset(&w, 0, sizeof(w)); |
| w.pParse = &sParse; |
| w.xExprCallback = testExprCallback; |
|
|
| Select sSel; |
| memset(&sSel, 0, sizeof(sSel)); |
| sSel.pEList = makeEmptyExprList(db); |
| sSel.pSrc = makeSrcListWithN(db, 2); |
|
|
| |
| const char *tA = "tA"; |
| sSel.pSrc->a[0].zName = (char*)tA; |
| sSel.pSrc->a[0].fg.isUsing = 0; |
| Expr onExpr; |
| memset(&onExpr, 0, sizeof(onExpr)); |
| onExpr.op = TK_NULL; |
| sSel.pSrc->a[0].u3.pOn = &onExpr; |
|
|
| |
| const char *tB = "tB"; |
| sSel.pSrc->a[1].zName = (char*)tB; |
| sSel.pSrc->a[1].fg.isUsing = 1; |
| const char *usingNames[] = { "u1", "u2" }; |
| sSel.pSrc->a[1].u3.pUsing = makeIdList(db, 2, usingNames); |
|
|
| RenameToken *pTok_tA = addRenameToken(&sParse, tA); |
| RenameToken *pTok_tB = addRenameToken(&sParse, tB); |
| RenameToken *pTok_u1 = addRenameToken(&sParse, usingNames[0]); |
| RenameToken *pTok_u2 = addRenameToken(&sParse, usingNames[1]); |
|
|
| g_expr_walk_count = 0; |
| int rc = test_renameUnmapSelectCb(&w, &sSel); |
| TEST_ASSERT_EQUAL_INT(WRC_Continue, rc); |
|
|
| |
| TEST_ASSERT_EQUAL_PTR(NULL, pTok_tA->p); |
| TEST_ASSERT_EQUAL_PTR(NULL, pTok_tB->p); |
|
|
| |
| TEST_ASSERT_EQUAL_PTR(NULL, pTok_u1->p); |
| TEST_ASSERT_EQUAL_PTR(NULL, pTok_u2->p); |
|
|
| |
| TEST_ASSERT_TRUE(g_expr_walk_count >= 1); |
|
|
| sqlite3_close(db); |
| } |
|
|
| int main(void){ |
| UNITY_BEGIN(); |
| RUN_TEST(test_renameUnmapSelectCb_returns_abort_if_nErr); |
| RUN_TEST(test_renameUnmapSelectCb_prunes_on_view_and_preserves_tokens); |
| RUN_TEST(test_renameUnmapSelectCb_unmaps_only_ENAME_NAME_aliases); |
| RUN_TEST(test_renameUnmapSelectCb_unmaps_srclist_and_walks_on_or_using); |
| return UNITY_END(); |
| } |