AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Helpers */7static Token mkToken(const char *z){8 Token t;9 t.z = z;10 t.n = (int)strlen(z);11 return t;12}13 14static SrcList* makeSrcList(sqlite3 *db, const char *zDbName, const char *zTab){15 /* Allocate a SrcList with a single item using SQLite's allocator so that16 sqlite3SrcListDelete() in the target function can free it safely. */17 SrcList *p = (SrcList*)sqlite3DbMallocZero(db, sizeof(SrcList));18 TEST_ASSERT_NOT_NULL_MESSAGE(p, "Failed to allocate SrcList");19 p->nAlloc = 1;20 p->nSrc = 1;21 p->a[0].zName = sqlite3DbStrDup(db, zTab);22 TEST_ASSERT_NOT_NULL_MESSAGE(p->a[0].zName, "Failed to dup table name");23 if( zDbName ){24 p->a[0].zDatabase = sqlite3DbStrDup(db, zDbName);25 TEST_ASSERT_NOT_NULL_MESSAGE(p->a[0].zDatabase, "Failed to dup db name");26 }27 return p;28}29 30static void parseInit(Parse *pParse, sqlite3 *db){31 memset(pParse, 0, sizeof(Parse));32 pParse->db = db;33}34 35static void parseCleanup(Parse *pParse){36 if( pParse->pVdbe ){37 sqlite3VdbeDelete(pParse->pVdbe);38 pParse->pVdbe = NULL;39 }40 if( pParse->zErrMsg ){41 sqlite3DbFree(pParse->db, pParse->zErrMsg);42 pParse->zErrMsg = NULL;43 }44}45 46/* Unity hooks */47void setUp(void) {48 /* no-op */49}50void tearDown(void) {51 /* no-op */52}53 54/* Tests */55 56void test_sqlite3AlterRenameColumn_no_such_table(void){57 sqlite3 *db = 0;58 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));59 60 Parse p; parseInit(&p, db);61 62 SrcList *pSrc = makeSrcList(db, NULL, "nope_table");63 Token oldTok = mkToken("a");64 Token newTok = mkToken("b");65 66 sqlite3AlterRenameColumn(&p, pSrc, &oldTok, &newTok);67 68 TEST_ASSERT_TRUE_MESSAGE(p.nErr>0 || p.zErrMsg!=NULL, "Expected error for missing table");69 /* Expect no VDBE was generated */70 TEST_ASSERT_NULL(p.pVdbe);71 72 parseCleanup(&p);73 sqlite3_close(db);74}75 76void test_sqlite3AlterRenameColumn_view_error(void){77 sqlite3 *db = 0;78 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));79 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_exec(db,80 "CREATE TABLE t1(a,b);"81 "CREATE VIEW v1 AS SELECT a,b FROM t1;", 0, 0, 0));82 83 Parse p; parseInit(&p, db);84 85 SrcList *pSrc = makeSrcList(db, NULL, "v1");86 Token oldTok = mkToken("a");87 Token newTok = mkToken("x");88 89 sqlite3AlterRenameColumn(&p, pSrc, &oldTok, &newTok);90 91 TEST_ASSERT_TRUE(p.nErr>0);92 TEST_ASSERT_NOT_NULL(p.zErrMsg);93 TEST_ASSERT_NOT_EQUAL(NULL, strstr(p.zErrMsg, "cannot rename columns of"));94 95 /* Should not generate code on error */96 TEST_ASSERT_NULL(p.pVdbe);97 98 parseCleanup(&p);99 sqlite3_close(db);100}101 102void test_sqlite3AlterRenameColumn_column_not_found(void){103 sqlite3 *db = 0;104 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));105 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_exec(db,106 "CREATE TABLE t1(a,b);", 0, 0, 0));107 108 Parse p; parseInit(&p, db);109 110 SrcList *pSrc = makeSrcList(db, NULL, "t1");111 Token oldTok = mkToken("c"); /* does not exist */112 Token newTok = mkToken("d");113 114 sqlite3AlterRenameColumn(&p, pSrc, &oldTok, &newTok);115 116 TEST_ASSERT_TRUE(p.nErr>0);117 TEST_ASSERT_NOT_NULL(p.zErrMsg);118 TEST_ASSERT_NOT_EQUAL(NULL, strstr(p.zErrMsg, "no such column"));119 120 TEST_ASSERT_NULL(p.pVdbe);121 122 parseCleanup(&p);123 sqlite3_close(db);124}125 126void test_sqlite3AlterRenameColumn_success_main_db(void){127 sqlite3 *db = 0;128 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));129 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_exec(db,130 "CREATE TABLE t1(a,b,c);", 0, 0, 0));131 132 Parse p; parseInit(&p, db);133 134 SrcList *pSrc = makeSrcList(db, NULL, "t1");135 Token oldTok = mkToken("a");136 Token newTok = mkToken("x");137 138 sqlite3AlterRenameColumn(&p, pSrc, &oldTok, &newTok);139 140 TEST_ASSERT_EQUAL_INT(0, p.nErr);141 TEST_ASSERT_NULL(p.zErrMsg);142 TEST_ASSERT_NOT_NULL(p.pVdbe);143 /* sqlite3NestedParse should have added some ops */144 TEST_ASSERT_TRUE(p.pVdbe->nOp > 0);145 146 parseCleanup(&p);147 sqlite3_close(db);148}149 150void test_sqlite3AlterRenameColumn_success_temp_db_quoted_newname(void){151 sqlite3 *db = 0;152 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));153 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_exec(db,154 "CREATE TEMP TABLE tt(a,b);", 0, 0, 0));155 156 Parse p; parseInit(&p, db);157 158 /* Force lookup in temp by providing zDatabase="temp" */159 SrcList *pSrc = makeSrcList(db, "temp", "tt");160 Token oldTok = mkToken("b");161 Token newTok = mkToken("\"x y\""); /* quoted new name */162 163 sqlite3AlterRenameColumn(&p, pSrc, &oldTok, &newTok);164 165 TEST_ASSERT_EQUAL_INT(0, p.nErr);166 TEST_ASSERT_NULL(p.zErrMsg);167 TEST_ASSERT_NOT_NULL(p.pVdbe);168 TEST_ASSERT_TRUE(p.pVdbe->nOp > 0);169 170 parseCleanup(&p);171 sqlite3_close(db);172}173 174void test_sqlite3AlterRenameColumn_cannot_alter_system_table(void){175 sqlite3 *db = 0;176 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));177 178 Parse p; parseInit(&p, db);179 180 /* Attempt to alter the sqlite_schema/system table */181 SrcList *pSrc = makeSrcList(db, NULL, "sqlite_schema");182 Token oldTok = mkToken("type");183 Token newTok = mkToken("xtype");184 185 sqlite3AlterRenameColumn(&p, pSrc, &oldTok, &newTok);186 187 TEST_ASSERT_TRUE(p.nErr>0);188 TEST_ASSERT_NOT_NULL(p.zErrMsg);189 TEST_ASSERT_NOT_EQUAL(NULL, strstr(p.zErrMsg, "may not be altered"));190 191 TEST_ASSERT_NULL(p.pVdbe);192 193 parseCleanup(&p);194 sqlite3_close(db);195}196 197#ifndef SQLITE_OMIT_AUTHORIZATION198static int denyAuthorizer(void *p, int op,199 const char *z1, const char *z2,200 const char *z3, const char *z4){201 UNUSED_PARAMETER(p);202 UNUSED_PARAMETER(op);203 UNUSED_PARAMETER(z1);204 UNUSED_PARAMETER(z2);205 UNUSED_PARAMETER(z3);206 UNUSED_PARAMETER(z4);207 return SQLITE_DENY;208}209 210void test_sqlite3AlterRenameColumn_authorizer_denies(void){211 sqlite3 *db = 0;212 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));213 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_exec(db,214 "CREATE TABLE t1(a,b);", 0, 0, 0));215 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_set_authorizer(db, denyAuthorizer, 0));216 217 Parse p; parseInit(&p, db);218 219 SrcList *pSrc = makeSrcList(db, NULL, "t1");220 Token oldTok = mkToken("a");221 Token newTok = mkToken("x");222 223 sqlite3AlterRenameColumn(&p, pSrc, &oldTok, &newTok);224 225 /* Expect abort without generating code */226 TEST_ASSERT_TRUE(p.nErr>0 || p.zErrMsg!=NULL);227 TEST_ASSERT_NULL(p.pVdbe);228 229 sqlite3_set_authorizer(db, 0, 0);230 parseCleanup(&p);231 sqlite3_close(db);232}233#endif234 235int main(void){236 UNITY_BEGIN();237 RUN_TEST(test_sqlite3AlterRenameColumn_no_such_table);238 RUN_TEST(test_sqlite3AlterRenameColumn_view_error);239 RUN_TEST(test_sqlite3AlterRenameColumn_column_not_found);240 RUN_TEST(test_sqlite3AlterRenameColumn_success_main_db);241 RUN_TEST(test_sqlite3AlterRenameColumn_success_temp_db_quoted_newname);242 RUN_TEST(test_sqlite3AlterRenameColumn_cannot_alter_system_table);243#ifndef SQLITE_OMIT_AUTHORIZATION244 RUN_TEST(test_sqlite3AlterRenameColumn_authorizer_denies);245#endif246 return UNITY_END();247}