File size: 5,896 Bytes
7510827 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
#include "sqliteInt.h"
#include "unity.h"
#include <stdlib.h>
#include <string.h>
/* Global DB handle for each test */
static sqlite3 *gDb = NULL;
/* Helper: execute SQL and assert success */
static void execSQL(const char *zSql){
char *zErr = 0;
int rc = sqlite3_exec(gDb, zSql, 0, 0, &zErr);
if( rc!=SQLITE_OK ){
/* Use Unity assertion here (stdout not redirected) */
TEST_FAIL_MESSAGE(zErr ? zErr : "sqlite3_exec error");
}
sqlite3_free(zErr);
}
/* Helper: make a Token from a C-string */
static Token makeToken(const char *z){
Token t;
t.z = z;
t.n = (int)strlen(z);
t.dyn = 0;
t.enc = 0;
t.term = 0;
return t;
}
/* Helper: build a SrcList with one entry, optionally with a database/schema name.
** The SrcList is allocated using SQLite allocators and will be owned and freed
** by sqlite3AlterRenameTable().
*/
static SrcList* mkSrcList(sqlite3 *db, const char *zDb, const char *zTab){
Token tTab = makeToken(zTab);
if( zDb ){
Token tDb = makeToken(zDb);
return sqlite3SrcListAppend(db, 0, &tTab, &tDb);
}else{
return sqlite3SrcListAppend(db, 0, &tTab, 0);
}
}
void setUp(void) {
int rc = sqlite3_initialize();
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
rc = sqlite3_open(":memory:", &gDb);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
}
void tearDown(void) {
if( gDb ){
sqlite3_close(gDb);
gDb = NULL;
}
}
/* Success case: rename a regular table to a new unique name.
** Expect: no parse error, VDBE generated (pVdbe != NULL).
*/
void test_sqlite3AlterRenameTable_success_generates_vdbe(void){
execSQL("CREATE TABLE t1(a)");
Parse parse;
memset(&parse, 0, sizeof(parse));
parse.db = gDb;
SrcList *pSrc = mkSrcList(gDb, "main", "t1");
Token newName = makeToken("t2");
sqlite3BtreeEnterAll(gDb);
sqlite3AlterRenameTable(&parse, pSrc, &newName);
sqlite3BtreeLeaveAll(gDb);
TEST_ASSERT_EQUAL_INT(0, parse.nErr);
TEST_ASSERT_NULL(parse.zErrMsg);
TEST_ASSERT_NOT_NULL(parse.pVdbe);
if( parse.pVdbe ) sqlite3VdbeDelete(parse.pVdbe);
}
/* Error: rename to a name that already exists as another table */
void test_sqlite3AlterRenameTable_error_duplicate_name_table(void){
execSQL("CREATE TABLE t1(a)");
execSQL("CREATE TABLE t2(b)");
Parse parse;
memset(&parse, 0, sizeof(parse));
parse.db = gDb;
SrcList *pSrc = mkSrcList(gDb, "main", "t1");
Token newName = makeToken("t2");
sqlite3BtreeEnterAll(gDb);
sqlite3AlterRenameTable(&parse, pSrc, &newName);
sqlite3BtreeLeaveAll(gDb);
TEST_ASSERT_GREATER_THAN_INT(0, parse.nErr);
TEST_ASSERT_NOT_NULL(parse.zErrMsg);
TEST_ASSERT_NULL(parse.pVdbe);
if( parse.zErrMsg ) sqlite3DbFree(gDb, parse.zErrMsg);
}
/* Error: rename to a name that already exists as an index */
void test_sqlite3AlterRenameTable_error_duplicate_name_index(void){
execSQL("CREATE TABLE t1(a)");
execSQL("CREATE INDEX t2 ON t1(a)");
Parse parse;
memset(&parse, 0, sizeof(parse));
parse.db = gDb;
SrcList *pSrc = mkSrcList(gDb, "main", "t1");
Token newName = makeToken("t2");
sqlite3BtreeEnterAll(gDb);
sqlite3AlterRenameTable(&parse, pSrc, &newName);
sqlite3BtreeLeaveAll(gDb);
TEST_ASSERT_GREATER_THAN_INT(0, parse.nErr);
TEST_ASSERT_NOT_NULL(parse.zErrMsg);
TEST_ASSERT_NULL(parse.pVdbe);
if( parse.zErrMsg ) sqlite3DbFree(gDb, parse.zErrMsg);
}
/* Error: attempt to alter a view */
void test_sqlite3AlterRenameTable_error_view_not_alterable(void){
execSQL("CREATE TABLE t1(a)");
execSQL("CREATE VIEW v1 AS SELECT a FROM t1");
Parse parse;
memset(&parse, 0, sizeof(parse));
parse.db = gDb;
SrcList *pSrc = mkSrcList(gDb, "main", "v1");
Token newName = makeToken("v2");
sqlite3BtreeEnterAll(gDb);
sqlite3AlterRenameTable(&parse, pSrc, &newName);
sqlite3BtreeLeaveAll(gDb);
TEST_ASSERT_GREATER_THAN_INT(0, parse.nErr);
TEST_ASSERT_NOT_NULL(parse.zErrMsg);
TEST_ASSERT_NULL(parse.pVdbe);
if( parse.zErrMsg ) sqlite3DbFree(gDb, parse.zErrMsg);
}
/* Error: attempt to alter a system table (sqlite_sequence) */
void test_sqlite3AlterRenameTable_error_system_table_not_alterable(void){
/* Ensure sqlite_sequence exists by creating AUTOINCREMENT table and inserting */
execSQL("CREATE TABLE tauto(id INTEGER PRIMARY KEY AUTOINCREMENT, x)");
execSQL("INSERT INTO tauto(x) VALUES (1)");
/* Now attempt to rename sqlite_sequence itself */
Parse parse;
memset(&parse, 0, sizeof(parse));
parse.db = gDb;
SrcList *pSrc = mkSrcList(gDb, "main", "sqlite_sequence");
Token newName = makeToken("seq2");
sqlite3BtreeEnterAll(gDb);
sqlite3AlterRenameTable(&parse, pSrc, &newName);
sqlite3BtreeLeaveAll(gDb);
TEST_ASSERT_GREATER_THAN_INT(0, parse.nErr);
TEST_ASSERT_NOT_NULL(parse.zErrMsg);
TEST_ASSERT_NULL(parse.pVdbe);
if( parse.zErrMsg ) sqlite3DbFree(gDb, parse.zErrMsg);
}
/* Error: rename to a reserved/internal name (starts with sqlite_) */
void test_sqlite3AlterRenameTable_error_reserved_new_name(void){
execSQL("CREATE TABLE t1(a)");
Parse parse;
memset(&parse, 0, sizeof(parse));
parse.db = gDb;
SrcList *pSrc = mkSrcList(gDb, "main", "t1");
Token newName = makeToken("sqlite_stat1");
sqlite3BtreeEnterAll(gDb);
sqlite3AlterRenameTable(&parse, pSrc, &newName);
sqlite3BtreeLeaveAll(gDb);
TEST_ASSERT_GREATER_THAN_INT(0, parse.nErr);
TEST_ASSERT_NOT_NULL(parse.zErrMsg);
TEST_ASSERT_NULL(parse.pVdbe);
if( parse.zErrMsg ) sqlite3DbFree(gDb, parse.zErrMsg);
}
int main(void) {
UNITY_BEGIN();
RUN_TEST(test_sqlite3AlterRenameTable_success_generates_vdbe);
RUN_TEST(test_sqlite3AlterRenameTable_error_duplicate_name_table);
RUN_TEST(test_sqlite3AlterRenameTable_error_duplicate_name_index);
RUN_TEST(test_sqlite3AlterRenameTable_error_view_not_alterable);
RUN_TEST(test_sqlite3AlterRenameTable_error_system_table_not_alterable);
RUN_TEST(test_sqlite3AlterRenameTable_error_reserved_new_name);
return UNITY_END();
} |