AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6static sqlite3 *gDb = NULL;7 8static ExprList* makeExprListN(sqlite3 *db, int n){9 ExprList *p = (ExprList*)sqlite3DbMallocZero(db, sizeof(ExprList));10 TEST_ASSERT_NOT_NULL(p);11 if( n>0 ){12 p->a = (struct ExprList_item*)sqlite3DbMallocZero(db, sizeof(struct ExprList_item)*n);13 TEST_ASSERT_NOT_NULL(p->a);14 }15 p->nExpr = n;16 return p;17}18 19static SrcList* makeSrcListN(sqlite3 *db, int n){20 SrcList *p = (SrcList*)sqlite3DbMallocZero(db, sizeof(SrcList));21 TEST_ASSERT_NOT_NULL(p);22 if( n>0 ){23 p->a = (SrcItem*)sqlite3DbMallocZero(db, sizeof(SrcItem)*n);24 TEST_ASSERT_NOT_NULL(p->a);25 }26 p->nSrc = n;27 return p;28}29 30/* Unity setup/teardown */31void setUp(void) {32 int rc = sqlite3_open(":memory:", &gDb);33 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);34}35 36void tearDown(void) {37 if( gDb ){38 int rc = sqlite3_close(gDb);39 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);40 gDb = NULL;41 }42}43 44/* Tests */45 46void test_sqlite3SrcListFuncArgs_sets_pointer_and_flag_on_single_item(void) {47 Parse pParse;48 memset(&pParse, 0, sizeof(pParse));49 pParse.db = gDb;50 51 SrcList *pSrc = makeSrcListN(gDb, 1);52 /* Precondition flags must be zero */53 TEST_ASSERT_EQUAL_INT(0, pSrc->a[0].fg.notIndexed);54 TEST_ASSERT_EQUAL_INT(0, pSrc->a[0].fg.isIndexedBy);55 TEST_ASSERT_EQUAL_INT(0, pSrc->a[0].fg.isTabFunc);56 57 ExprList *pList = makeExprListN(gDb, 2);58 59 sqlite3SrcListFuncArgs(&pParse, pSrc, pList);60 61 TEST_ASSERT_EQUAL_PTR(pList, pSrc->a[0].u1.pFuncArg);62 TEST_ASSERT_EQUAL_INT(1, pSrc->a[0].fg.isTabFunc);63 64 /* Cleanup: prevent sqlite3SrcListDelete from freeing pList twice */65 pSrc->a[0].u1.pFuncArg = NULL;66 sqlite3ExprListDelete(gDb, pList);67 sqlite3SrcListDelete(gDb, pSrc);68}69 70void test_sqlite3SrcListFuncArgs_affects_only_last_item_in_multi_item_list(void) {71 Parse pParse;72 memset(&pParse, 0, sizeof(pParse));73 pParse.db = gDb;74 75 SrcList *pSrc = makeSrcListN(gDb, 3);76 for( int i=0; i<3; i++ ){77 TEST_ASSERT_EQUAL_INT(0, pSrc->a[i].fg.notIndexed);78 TEST_ASSERT_EQUAL_INT(0, pSrc->a[i].fg.isIndexedBy);79 TEST_ASSERT_EQUAL_INT(0, pSrc->a[i].fg.isTabFunc);80 TEST_ASSERT_NULL(pSrc->a[i].u1.pFuncArg);81 }82 83 ExprList *pList = makeExprListN(gDb, 1);84 85 sqlite3SrcListFuncArgs(&pParse, pSrc, pList);86 87 /* Only the last item should be affected */88 TEST_ASSERT_EQUAL_INT(0, pSrc->a[0].fg.isTabFunc);89 TEST_ASSERT_EQUAL_INT(0, pSrc->a[1].fg.isTabFunc);90 TEST_ASSERT_EQUAL_INT(1, pSrc->a[2].fg.isTabFunc);91 TEST_ASSERT_NULL(pSrc->a[0].u1.pFuncArg);92 TEST_ASSERT_NULL(pSrc->a[1].u1.pFuncArg);93 TEST_ASSERT_EQUAL_PTR(pList, pSrc->a[2].u1.pFuncArg);94 95 /* Cleanup */96 pSrc->a[2].u1.pFuncArg = NULL;97 sqlite3ExprListDelete(gDb, pList);98 sqlite3SrcListDelete(gDb, pSrc);99}100 101void test_sqlite3SrcListFuncArgs_with_null_pList_marks_isTabFunc(void) {102 Parse pParse;103 memset(&pParse, 0, sizeof(pParse));104 pParse.db = gDb;105 106 SrcList *pSrc = makeSrcListN(gDb, 1);107 TEST_ASSERT_EQUAL_INT(0, pSrc->a[0].fg.isTabFunc);108 TEST_ASSERT_NULL(pSrc->a[0].u1.pFuncArg);109 110 /* Pass NULL pList - should still mark as table-valued function */111 sqlite3SrcListFuncArgs(&pParse, pSrc, NULL);112 113 TEST_ASSERT_EQUAL_INT(1, pSrc->a[0].fg.isTabFunc);114 TEST_ASSERT_NULL(pSrc->a[0].u1.pFuncArg);115 116 /* Cleanup */117 /* Nothing to free for pList, just delete SrcList */118 sqlite3SrcListDelete(gDb, pSrc);119}120 121void test_sqlite3SrcListFuncArgs_p_null_deletes_nonnull_list_without_crash(void) {122 Parse pParse;123 memset(&pParse, 0, sizeof(pParse));124 pParse.db = gDb;125 126 ExprList *pList = makeExprListN(gDb, 3);127 128 /* When p is NULL, function should delete pList using pParse->db.129 We cannot dereference pList after call; test simply ensures no crash. */130 sqlite3SrcListFuncArgs(&pParse, NULL, pList);131 132 /* Ensure the db is still valid and usable after deletion */133 TEST_ASSERT_NOT_NULL(pParse.db);134 /* Also verify we can perform a trivial SQL operation */135 char *errmsg = NULL;136 int rc = sqlite3_exec(gDb, "SELECT 1", NULL, NULL, &errmsg);137 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);138 if( errmsg ){ sqlite3_free(errmsg); }139}140 141void test_sqlite3SrcListFuncArgs_p_null_with_null_list_noop(void) {142 Parse pParse;143 memset(&pParse, 0, sizeof(pParse));144 pParse.db = gDb;145 146 /* Should be a no-op and not crash */147 sqlite3SrcListFuncArgs(&pParse, NULL, NULL);148 149 /* Verify db still fine */150 TEST_ASSERT_NOT_NULL(pParse.db);151}152 153/* Main runner */154int main(void) {155 UNITY_BEGIN();156 RUN_TEST(test_sqlite3SrcListFuncArgs_sets_pointer_and_flag_on_single_item);157 RUN_TEST(test_sqlite3SrcListFuncArgs_affects_only_last_item_in_multi_item_list);158 RUN_TEST(test_sqlite3SrcListFuncArgs_with_null_pList_marks_isTabFunc);159 RUN_TEST(test_sqlite3SrcListFuncArgs_p_null_deletes_nonnull_list_without_crash);160 RUN_TEST(test_sqlite3SrcListFuncArgs_p_null_with_null_list_noop);161 return UNITY_END();162}