| | #include "sqliteInt.h" |
| | #include "unity.h" |
| | #include <string.h> |
| | #include <stdlib.h> |
| |
|
| | |
| | static Token mkToken(const char *z){ |
| | Token t; |
| | t.z = z; |
| | t.n = (int)strlen(z); |
| | return t; |
| | } |
| |
|
| | static SrcList* makeSrcList(sqlite3 *db, const char *zDbName, const char *zTab){ |
| | |
| | |
| | SrcList *p = (SrcList*)sqlite3DbMallocZero(db, sizeof(SrcList)); |
| | TEST_ASSERT_NOT_NULL_MESSAGE(p, "Failed to allocate SrcList"); |
| | p->nAlloc = 1; |
| | p->nSrc = 1; |
| | p->a[0].zName = sqlite3DbStrDup(db, zTab); |
| | TEST_ASSERT_NOT_NULL_MESSAGE(p->a[0].zName, "Failed to dup table name"); |
| | if( zDbName ){ |
| | p->a[0].zDatabase = sqlite3DbStrDup(db, zDbName); |
| | TEST_ASSERT_NOT_NULL_MESSAGE(p->a[0].zDatabase, "Failed to dup db name"); |
| | } |
| | return p; |
| | } |
| |
|
| | static void parseInit(Parse *pParse, sqlite3 *db){ |
| | memset(pParse, 0, sizeof(Parse)); |
| | pParse->db = db; |
| | } |
| |
|
| | static void parseCleanup(Parse *pParse){ |
| | if( pParse->pVdbe ){ |
| | sqlite3VdbeDelete(pParse->pVdbe); |
| | pParse->pVdbe = NULL; |
| | } |
| | if( pParse->zErrMsg ){ |
| | sqlite3DbFree(pParse->db, pParse->zErrMsg); |
| | pParse->zErrMsg = NULL; |
| | } |
| | } |
| |
|
| | |
| | void setUp(void) { |
| | |
| | } |
| | void tearDown(void) { |
| | |
| | } |
| |
|
| | |
| |
|
| | void test_sqlite3AlterRenameColumn_no_such_table(void){ |
| | sqlite3 *db = 0; |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
| |
|
| | Parse p; parseInit(&p, db); |
| |
|
| | SrcList *pSrc = makeSrcList(db, NULL, "nope_table"); |
| | Token oldTok = mkToken("a"); |
| | Token newTok = mkToken("b"); |
| |
|
| | sqlite3AlterRenameColumn(&p, pSrc, &oldTok, &newTok); |
| |
|
| | TEST_ASSERT_TRUE_MESSAGE(p.nErr>0 || p.zErrMsg!=NULL, "Expected error for missing table"); |
| | |
| | TEST_ASSERT_NULL(p.pVdbe); |
| |
|
| | parseCleanup(&p); |
| | sqlite3_close(db); |
| | } |
| |
|
| | void test_sqlite3AlterRenameColumn_view_error(void){ |
| | sqlite3 *db = 0; |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_exec(db, |
| | "CREATE TABLE t1(a,b);" |
| | "CREATE VIEW v1 AS SELECT a,b FROM t1;", 0, 0, 0)); |
| |
|
| | Parse p; parseInit(&p, db); |
| |
|
| | SrcList *pSrc = makeSrcList(db, NULL, "v1"); |
| | Token oldTok = mkToken("a"); |
| | Token newTok = mkToken("x"); |
| |
|
| | sqlite3AlterRenameColumn(&p, pSrc, &oldTok, &newTok); |
| |
|
| | TEST_ASSERT_TRUE(p.nErr>0); |
| | TEST_ASSERT_NOT_NULL(p.zErrMsg); |
| | TEST_ASSERT_NOT_EQUAL(NULL, strstr(p.zErrMsg, "cannot rename columns of")); |
| |
|
| | |
| | TEST_ASSERT_NULL(p.pVdbe); |
| |
|
| | parseCleanup(&p); |
| | sqlite3_close(db); |
| | } |
| |
|
| | void test_sqlite3AlterRenameColumn_column_not_found(void){ |
| | sqlite3 *db = 0; |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_exec(db, |
| | "CREATE TABLE t1(a,b);", 0, 0, 0)); |
| |
|
| | Parse p; parseInit(&p, db); |
| |
|
| | SrcList *pSrc = makeSrcList(db, NULL, "t1"); |
| | Token oldTok = mkToken("c"); |
| | Token newTok = mkToken("d"); |
| |
|
| | sqlite3AlterRenameColumn(&p, pSrc, &oldTok, &newTok); |
| |
|
| | TEST_ASSERT_TRUE(p.nErr>0); |
| | TEST_ASSERT_NOT_NULL(p.zErrMsg); |
| | TEST_ASSERT_NOT_EQUAL(NULL, strstr(p.zErrMsg, "no such column")); |
| |
|
| | TEST_ASSERT_NULL(p.pVdbe); |
| |
|
| | parseCleanup(&p); |
| | sqlite3_close(db); |
| | } |
| |
|
| | void test_sqlite3AlterRenameColumn_success_main_db(void){ |
| | sqlite3 *db = 0; |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_exec(db, |
| | "CREATE TABLE t1(a,b,c);", 0, 0, 0)); |
| |
|
| | Parse p; parseInit(&p, db); |
| |
|
| | SrcList *pSrc = makeSrcList(db, NULL, "t1"); |
| | Token oldTok = mkToken("a"); |
| | Token newTok = mkToken("x"); |
| |
|
| | sqlite3AlterRenameColumn(&p, pSrc, &oldTok, &newTok); |
| |
|
| | TEST_ASSERT_EQUAL_INT(0, p.nErr); |
| | TEST_ASSERT_NULL(p.zErrMsg); |
| | TEST_ASSERT_NOT_NULL(p.pVdbe); |
| | |
| | TEST_ASSERT_TRUE(p.pVdbe->nOp > 0); |
| |
|
| | parseCleanup(&p); |
| | sqlite3_close(db); |
| | } |
| |
|
| | void test_sqlite3AlterRenameColumn_success_temp_db_quoted_newname(void){ |
| | sqlite3 *db = 0; |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_exec(db, |
| | "CREATE TEMP TABLE tt(a,b);", 0, 0, 0)); |
| |
|
| | Parse p; parseInit(&p, db); |
| |
|
| | |
| | SrcList *pSrc = makeSrcList(db, "temp", "tt"); |
| | Token oldTok = mkToken("b"); |
| | Token newTok = mkToken("\"x y\""); |
| |
|
| | sqlite3AlterRenameColumn(&p, pSrc, &oldTok, &newTok); |
| |
|
| | TEST_ASSERT_EQUAL_INT(0, p.nErr); |
| | TEST_ASSERT_NULL(p.zErrMsg); |
| | TEST_ASSERT_NOT_NULL(p.pVdbe); |
| | TEST_ASSERT_TRUE(p.pVdbe->nOp > 0); |
| |
|
| | parseCleanup(&p); |
| | sqlite3_close(db); |
| | } |
| |
|
| | void test_sqlite3AlterRenameColumn_cannot_alter_system_table(void){ |
| | sqlite3 *db = 0; |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
| |
|
| | Parse p; parseInit(&p, db); |
| |
|
| | |
| | SrcList *pSrc = makeSrcList(db, NULL, "sqlite_schema"); |
| | Token oldTok = mkToken("type"); |
| | Token newTok = mkToken("xtype"); |
| |
|
| | sqlite3AlterRenameColumn(&p, pSrc, &oldTok, &newTok); |
| |
|
| | TEST_ASSERT_TRUE(p.nErr>0); |
| | TEST_ASSERT_NOT_NULL(p.zErrMsg); |
| | TEST_ASSERT_NOT_EQUAL(NULL, strstr(p.zErrMsg, "may not be altered")); |
| |
|
| | TEST_ASSERT_NULL(p.pVdbe); |
| |
|
| | parseCleanup(&p); |
| | sqlite3_close(db); |
| | } |
| |
|
| | #ifndef SQLITE_OMIT_AUTHORIZATION |
| | static int denyAuthorizer(void *p, int op, |
| | const char *z1, const char *z2, |
| | const char *z3, const char *z4){ |
| | UNUSED_PARAMETER(p); |
| | UNUSED_PARAMETER(op); |
| | UNUSED_PARAMETER(z1); |
| | UNUSED_PARAMETER(z2); |
| | UNUSED_PARAMETER(z3); |
| | UNUSED_PARAMETER(z4); |
| | return SQLITE_DENY; |
| | } |
| |
|
| | void test_sqlite3AlterRenameColumn_authorizer_denies(void){ |
| | sqlite3 *db = 0; |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_exec(db, |
| | "CREATE TABLE t1(a,b);", 0, 0, 0)); |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_set_authorizer(db, denyAuthorizer, 0)); |
| |
|
| | Parse p; parseInit(&p, db); |
| |
|
| | SrcList *pSrc = makeSrcList(db, NULL, "t1"); |
| | Token oldTok = mkToken("a"); |
| | Token newTok = mkToken("x"); |
| |
|
| | sqlite3AlterRenameColumn(&p, pSrc, &oldTok, &newTok); |
| |
|
| | |
| | TEST_ASSERT_TRUE(p.nErr>0 || p.zErrMsg!=NULL); |
| | TEST_ASSERT_NULL(p.pVdbe); |
| |
|
| | sqlite3_set_authorizer(db, 0, 0); |
| | parseCleanup(&p); |
| | sqlite3_close(db); |
| | } |
| | #endif |
| |
|
| | int main(void){ |
| | UNITY_BEGIN(); |
| | RUN_TEST(test_sqlite3AlterRenameColumn_no_such_table); |
| | RUN_TEST(test_sqlite3AlterRenameColumn_view_error); |
| | RUN_TEST(test_sqlite3AlterRenameColumn_column_not_found); |
| | RUN_TEST(test_sqlite3AlterRenameColumn_success_main_db); |
| | RUN_TEST(test_sqlite3AlterRenameColumn_success_temp_db_quoted_newname); |
| | RUN_TEST(test_sqlite3AlterRenameColumn_cannot_alter_system_table); |
| | #ifndef SQLITE_OMIT_AUTHORIZATION |
| | RUN_TEST(test_sqlite3AlterRenameColumn_authorizer_denies); |
| | #endif |
| | return UNITY_END(); |
| | } |