AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4 5/* Helpers */6 7static SrcList* make_src_list(sqlite3 *db, int n){8 SrcList *p = (SrcList*)sqlite3DbMallocZero(db,9 (int)(sizeof(SrcList) + (n-1)*sizeof(SrcItem)));10 TEST_ASSERT_NOT_NULL_MESSAGE(p, "Failed to allocate SrcList");11 p->nSrc = n;12 p->nAlloc = n;13 return p;14}15 16static void parse_init(sqlite3 *db, Parse *pParse){17 memset(pParse, 0, sizeof(*pParse));18 pParse->db = db;19}20 21static void fixer_init(DbFixer *pFix, Parse *pParse, int iDb, const char *zType){22 Token nameTok;23 nameTok.z = "obj";24 nameTok.n = (int)strlen(nameTok.z);25 sqlite3FixInit(pFix, pParse, iDb, zType, &nameTok);26}27 28static int str_contains(const char *hay, const char *needle){29 return (hay && needle && strstr(hay, needle)!=0);30}31 32/* Unity fixtures */33void setUp(void) {34 /* empty */35}36void tearDown(void) {37 /* empty */38}39 40/* Tests */41 42void test_sqlite3FixSrcList_null_list_returns_ok(void){43 sqlite3 *db = 0;44 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));45 Parse pParse; parse_init(db, &pParse);46 47 DbFixer fix; fixer_init(&fix, &pParse, 0, "view");48 49 int rc = sqlite3FixSrcList(&fix, 0);50 TEST_ASSERT_EQUAL_INT(0, rc);51 TEST_ASSERT_NULL(pParse.zErrMsg);52 53 sqlite3_close(db);54}55 56void test_sqlite3FixSrcList_sets_schema_and_flags_on_unqualified_term(void){57 sqlite3 *db = 0;58 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));59 Parse pParse; parse_init(db, &pParse);60 DbFixer fix; fixer_init(&fix, &pParse, 0, "view"); /* main */61 62 SrcList *pList = make_src_list(db, 1);63 /* No schema qualifier, not a subquery */64 pList->a[0].fg.isSubquery = 0;65 pList->a[0].fg.fixedSchema = 0;66 pList->a[0].u4.zDatabase = 0;67 68 int rc = sqlite3FixSrcList(&fix, pList);69 TEST_ASSERT_EQUAL_INT(0, rc);70 TEST_ASSERT_NULL(pParse.zErrMsg);71 72 TEST_ASSERT_EQUAL_INT(1, pList->a[0].fg.fixedSchema);73 TEST_ASSERT_EQUAL_INT(1, pList->a[0].fg.fromDDL);74 TEST_ASSERT_EQUAL_PTR(db->aDb[0].pSchema, pList->a[0].u4.pSchema);75 TEST_ASSERT_EQUAL_INT(0, pList->a[0].fg.hadSchema); /* was unqualified */76 77 sqlite3DbFree(db, pList);78 sqlite3_close(db);79}80 81void test_sqlite3FixSrcList_accepts_matching_schema_and_sets_hadSchema(void){82 sqlite3 *db = 0;83 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));84 Parse pParse; parse_init(db, &pParse);85 DbFixer fix; fixer_init(&fix, &pParse, 0, "view"); /* main */86 87 SrcList *pList = make_src_list(db, 1);88 pList->a[0].fg.isSubquery = 0;89 pList->a[0].fg.fixedSchema = 0;90 /* Provide explicit schema qualifier "main" */91 pList->a[0].u4.zDatabase = sqlite3DbStrDup(db, "main");92 TEST_ASSERT_NOT_NULL(pList->a[0].u4.zDatabase);93 94 int rc = sqlite3FixSrcList(&fix, pList);95 TEST_ASSERT_EQUAL_INT(0, rc);96 TEST_ASSERT_NULL(pParse.zErrMsg);97 98 TEST_ASSERT_EQUAL_INT(1, pList->a[0].fg.fixedSchema);99 TEST_ASSERT_EQUAL_INT(1, pList->a[0].fg.fromDDL);100 TEST_ASSERT_EQUAL_INT(1, pList->a[0].fg.hadSchema);101 TEST_ASSERT_EQUAL_INT(1, pList->a[0].fg.notCte);102 TEST_ASSERT_EQUAL_PTR(db->aDb[0].pSchema, pList->a[0].u4.pSchema);103 104 sqlite3DbFree(db, pList);105 sqlite3_close(db);106}107 108void test_sqlite3FixSrcList_rejects_mismatched_schema_and_sets_error(void){109 sqlite3 *db = 0;110 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));111 /* Ensure "temp" exists conceptually (it always does as aDb[1]) */112 Parse pParse; parse_init(db, &pParse);113 DbFixer fix; fixer_init(&fix, &pParse, 0, "view"); /* fixing to main */114 115 SrcList *pList = make_src_list(db, 1);116 pList->a[0].fg.isSubquery = 0;117 pList->a[0].fg.fixedSchema = 0;118 pList->a[0].u4.zDatabase = sqlite3DbStrDup(db, "temp");119 TEST_ASSERT_NOT_NULL(pList->a[0].u4.zDatabase);120 121 int rc = sqlite3FixSrcList(&fix, pList);122 TEST_ASSERT_NOT_EQUAL(0, rc);123 TEST_ASSERT_NOT_NULL(pParse.zErrMsg);124 TEST_ASSERT_TRUE_MESSAGE(125 str_contains(pParse.zErrMsg, "cannot reference objects in database temp"),126 pParse.zErrMsg ? pParse.zErrMsg : "(null)"127 );128 129 /* On error, item should be unchanged */130 TEST_ASSERT_EQUAL_INT(0, pList->a[0].fg.fixedSchema);131 TEST_ASSERT_EQUAL_STRING("temp", pList->a[0].u4.zDatabase);132 133 /* Cleanup */134 sqlite3DbFree(db, pList->a[0].u4.zDatabase);135 sqlite3DbFree(db, pList);136 sqlite3DbFree(db, pParse.zErrMsg);137 sqlite3_close(db);138}139 140void test_sqlite3FixSrcList_bTemp_skips_fixup(void){141 sqlite3 *db = 0;142 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));143 Parse pParse; parse_init(db, &pParse);144 DbFixer fix; fixer_init(&fix, &pParse, 1, "view"); /* TEMP => bTemp==1 */145 146 SrcList *pList = make_src_list(db, 1);147 pList->a[0].fg.isSubquery = 0;148 pList->a[0].fg.fixedSchema = 0;149 pList->a[0].u4.zDatabase = 0; /* unqualified */150 151 int rc = sqlite3FixSrcList(&fix, pList);152 TEST_ASSERT_EQUAL_INT(0, rc);153 TEST_ASSERT_NULL(pParse.zErrMsg);154 155 /* No modifications should be made for TEMP fixer */156 TEST_ASSERT_EQUAL_INT(0, pList->a[0].fg.fixedSchema);157 TEST_ASSERT_EQUAL_INT(0, pList->a[0].fg.fromDDL);158 TEST_ASSERT_NULL(pList->a[0].u4.zDatabase);159 160 sqlite3DbFree(db, pList);161 sqlite3_close(db);162}163 164void test_sqlite3FixSrcList_does_not_touch_subquery_item(void){165 sqlite3 *db = 0;166 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));167 Parse pParse; parse_init(db, &pParse);168 DbFixer fix; fixer_init(&fix, &pParse, 0, "view"); /* main */169 170 SrcList *pList = make_src_list(db, 1);171 pList->a[0].fg.isSubquery = 1; /* subquery => skip */172 pList->a[0].fg.fixedSchema = 0;173 pList->a[0].u4.zDatabase = 0;174 175 int rc = sqlite3FixSrcList(&fix, pList);176 TEST_ASSERT_EQUAL_INT(0, rc);177 TEST_ASSERT_NULL(pParse.zErrMsg);178 179 TEST_ASSERT_EQUAL_INT(0, pList->a[0].fg.fixedSchema);180 TEST_ASSERT_EQUAL_INT(0, pList->a[0].fg.fromDDL);181 TEST_ASSERT_NULL(pList->a[0].u4.zDatabase);182 183 sqlite3DbFree(db, pList);184 sqlite3_close(db);185}186 187void test_sqlite3FixSrcList_multiple_items_mixed(void){188 sqlite3 *db = 0;189 TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));190 Parse pParse; parse_init(db, &pParse);191 DbFixer fix; fixer_init(&fix, &pParse, 0, "view"); /* main */192 193 SrcList *pList = make_src_list(db, 3);194 195 /* Item 0: unqualified => should be set */196 pList->a[0].fg.isSubquery = 0;197 pList->a[0].fg.fixedSchema = 0;198 pList->a[0].u4.zDatabase = 0;199 200 /* Item 1: qualified with main => should be accepted */201 pList->a[1].fg.isSubquery = 0;202 pList->a[1].fg.fixedSchema = 0;203 pList->a[1].u4.zDatabase = sqlite3DbStrDup(db, "main");204 TEST_ASSERT_NOT_NULL(pList->a[1].u4.zDatabase);205 206 /* Item 2: qualified with temp => should cause error and remain unchanged */207 pList->a[2].fg.isSubquery = 0;208 pList->a[2].fg.fixedSchema = 0;209 pList->a[2].u4.zDatabase = sqlite3DbStrDup(db, "temp");210 TEST_ASSERT_NOT_NULL(pList->a[2].u4.zDatabase);211 212 int rc = sqlite3FixSrcList(&fix, pList);213 TEST_ASSERT_NOT_EQUAL(0, rc);214 TEST_ASSERT_NOT_NULL(pParse.zErrMsg);215 TEST_ASSERT_TRUE(str_contains(pParse.zErrMsg, "database temp"));216 217 /* Verify item 0 updated */218 TEST_ASSERT_EQUAL_INT(1, pList->a[0].fg.fixedSchema);219 TEST_ASSERT_EQUAL_INT(1, pList->a[0].fg.fromDDL);220 TEST_ASSERT_EQUAL_PTR(db->aDb[0].pSchema, pList->a[0].u4.pSchema);221 222 /* Verify item 1 updated and zDatabase consumed */223 TEST_ASSERT_EQUAL_INT(1, pList->a[1].fg.fixedSchema);224 TEST_ASSERT_EQUAL_INT(1, pList->a[1].fg.hadSchema);225 TEST_ASSERT_EQUAL_INT(1, pList->a[1].fg.notCte);226 TEST_ASSERT_EQUAL_PTR(db->aDb[0].pSchema, pList->a[1].u4.pSchema);227 228 /* Verify item 2 unchanged */229 TEST_ASSERT_EQUAL_INT(0, pList->a[2].fg.fixedSchema);230 TEST_ASSERT_EQUAL_STRING("temp", pList->a[2].u4.zDatabase);231 232 /* Cleanup: item 2's zDatabase not freed by the function due to error */233 sqlite3DbFree(db, pList->a[2].u4.zDatabase);234 sqlite3DbFree(db, pList);235 sqlite3DbFree(db, pParse.zErrMsg);236 sqlite3_close(db);237}238 239int main(void){240 UNITY_BEGIN();241 RUN_TEST(test_sqlite3FixSrcList_null_list_returns_ok);242 RUN_TEST(test_sqlite3FixSrcList_sets_schema_and_flags_on_unqualified_term);243 RUN_TEST(test_sqlite3FixSrcList_accepts_matching_schema_and_sets_hadSchema);244 RUN_TEST(test_sqlite3FixSrcList_rejects_mismatched_schema_and_sets_error);245 RUN_TEST(test_sqlite3FixSrcList_bTemp_skips_fixup);246 RUN_TEST(test_sqlite3FixSrcList_does_not_touch_subquery_item);247 RUN_TEST(test_sqlite3FixSrcList_multiple_items_mixed);248 return UNITY_END();249}