AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Unity setUp/tearDown */7void setUp(void) {8 /* No global setup required */9}10void tearDown(void) {11 /* No global teardown required */12}13 14/* Helpers */15 16static Token tokenFromString(const char *z){17 Token t;18 t.z = z;19 t.n = (int)strlen(z);20 return t;21}22 23/* Return a Token representing an empty second part, but with non-NULL z24** so that sqlite3Reindex does not treat it as a collation form. */25static Token emptySecondPartToken(void){26 static const char *zEmpty = "";27 Token t;28 t.z = zEmpty; /* non-NULL */29 t.n = 0;30 return t;31}32 33static void initParse(Parse *p, sqlite3 *db){34 memset(p, 0, sizeof(*p));35 p->db = db;36}37 38static void finalizeParseObjects(Parse *p){39 if( p->pVdbe ){40 sqlite3VdbeFinalize(p->pVdbe);41 p->pVdbe = NULL;42 }43 if( p->zErrMsg ){44 sqlite3DbFree(p->db, p->zErrMsg);45 p->zErrMsg = NULL;46 }47}48 49static void execSQL(sqlite3 *db, const char *sql){50 char *zErr = 0;51 int rc = sqlite3_exec(db, sql, 0, 0, &zErr);52 if( rc!=SQLITE_OK ){53 /* Fail the test with the error message if SQL execution fails */54 TEST_FAIL_MESSAGE(zErr ? zErr : "sqlite3_exec failed");55 }56 if( zErr ) sqlite3_free(zErr);57}58 59/* Tests */60 61static void test_sqlite3Reindex_unknown_object_sets_error(void){62 sqlite3 *db = 0;63 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));64 65 Parse p;66 initParse(&p, db);67 68 Token name1 = tokenFromString("no_such_object");69 Token name2 = emptySecondPartToken(); /* ensure object-name path */70 71 sqlite3Reindex(&p, &name1, &name2);72 73 TEST_ASSERT_GREATER_THAN_INT(0, p.nErr);74 TEST_ASSERT_NOT_NULL(p.zErrMsg);75 TEST_ASSERT_NOT_NULL(strstr(p.zErrMsg, "unable to identify"));76 77 finalizeParseObjects(&p);78 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_close(db));79}80 81static void test_sqlite3Reindex_unknown_database_sets_error(void){82 sqlite3 *db = 0;83 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));84 85 Parse p;86 initParse(&p, db);87 88 Token dbName = tokenFromString("nosuchdb");89 Token objName = tokenFromString("anything");90 91 sqlite3Reindex(&p, &dbName, &objName);92 93 TEST_ASSERT_GREATER_THAN_INT(0, p.nErr);94 TEST_ASSERT_NOT_NULL(p.zErrMsg);95 TEST_ASSERT_NOT_NULL(strstr(p.zErrMsg, "unknown database"));96 97 finalizeParseObjects(&p);98 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_close(db));99}100 101static void test_sqlite3Reindex_table_generates_vdbe_no_error(void){102 sqlite3 *db = 0;103 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));104 105 execSQL(db, "CREATE TABLE t(a);");106 execSQL(db, "CREATE INDEX i ON t(a);");107 108 Parse p;109 initParse(&p, db);110 111 Token name1 = tokenFromString("t");112 Token name2 = emptySecondPartToken(); /* single-part object name */113 114 sqlite3Reindex(&p, &name1, &name2);115 116 TEST_ASSERT_EQUAL_INT(0, p.nErr);117 TEST_ASSERT_NOT_NULL(p.pVdbe);118 TEST_ASSERT_GREATER_THAN_INT(0, sqlite3VdbeCurrentAddr(p.pVdbe));119 120 finalizeParseObjects(&p);121 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_close(db));122}123 124static void test_sqlite3Reindex_index_generates_vdbe_no_error(void){125 sqlite3 *db = 0;126 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));127 128 execSQL(db, "CREATE TABLE t(a);");129 execSQL(db, "CREATE INDEX i ON t(a);");130 131 Parse p;132 initParse(&p, db);133 134 /* Use qualified name: main.i */135 Token dbName = tokenFromString("main");136 Token idxName = tokenFromString("i");137 138 sqlite3Reindex(&p, &dbName, &idxName);139 140 TEST_ASSERT_EQUAL_INT(0, p.nErr);141 TEST_ASSERT_NOT_NULL(p.pVdbe);142 TEST_ASSERT_GREATER_THAN_INT(0, sqlite3VdbeCurrentAddr(p.pVdbe));143 144 finalizeParseObjects(&p);145 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_close(db));146}147 148static void test_sqlite3Reindex_by_collation_binary_generates_vdbe(void){149 sqlite3 *db = 0;150 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));151 152 /* Ensure there is at least one index using default BINARY collation */153 execSQL(db, "CREATE TABLE t(a);");154 execSQL(db, "CREATE INDEX i ON t(a);");155 156 Parse p;157 initParse(&p, db);158 159 Token coll = tokenFromString("BINARY");160 Token nullTok; nullTok.z = 0; nullTok.n = 0; /* trigger collation form */161 162 /* Hold all btree mutexes as required by reindexDatabases() assert */163 sqlite3BtreeEnterAll(db);164 sqlite3Reindex(&p, &coll, &nullTok);165 sqlite3BtreeLeaveAll(db);166 167 TEST_ASSERT_EQUAL_INT(0, p.nErr);168 TEST_ASSERT_NOT_NULL(p.pVdbe);169 TEST_ASSERT_GREATER_THAN_INT(0, sqlite3VdbeCurrentAddr(p.pVdbe));170 171 finalizeParseObjects(&p);172 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_close(db));173}174 175static void test_sqlite3Reindex_all_databases_generates_vdbe(void){176 sqlite3 *db = 0;177 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));178 179 execSQL(db, "CREATE TABLE t(a);");180 execSQL(db, "CREATE INDEX i ON t(a);");181 182 Parse p;183 initParse(&p, db);184 185 /* Form 1: REINDEX with no arguments */186 sqlite3BtreeEnterAll(db);187 sqlite3Reindex(&p, NULL, NULL);188 sqlite3BtreeLeaveAll(db);189 190 TEST_ASSERT_EQUAL_INT(0, p.nErr);191 TEST_ASSERT_NOT_NULL(p.pVdbe);192 TEST_ASSERT_GREATER_THAN_INT(0, sqlite3VdbeCurrentAddr(p.pVdbe));193 194 finalizeParseObjects(&p);195 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_close(db));196}197 198/* Unity main */199int main(void) {200 UNITY_BEGIN();201 RUN_TEST(test_sqlite3Reindex_unknown_object_sets_error);202 RUN_TEST(test_sqlite3Reindex_unknown_database_sets_error);203 RUN_TEST(test_sqlite3Reindex_table_generates_vdbe_no_error);204 RUN_TEST(test_sqlite3Reindex_index_generates_vdbe_no_error);205 RUN_TEST(test_sqlite3Reindex_by_collation_binary_generates_vdbe);206 RUN_TEST(test_sqlite3Reindex_all_databases_generates_vdbe);207 return UNITY_END();208}