| | #include "sqliteInt.h" |
| | #include "unity.h" |
| |
|
| | #include <string.h> |
| | #include <stdio.h> |
| |
|
| | |
| | static void execSQL(sqlite3 *db, const char *zSql){ |
| | char *zErr = 0; |
| | int rc = sqlite3_exec(db, zSql, 0, 0, &zErr); |
| | if( rc!=SQLITE_OK ){ |
| | fprintf(stderr, "SQL error (%d): %s while running: %s\n", rc, zErr?zErr:"(null)", zSql); |
| | } |
| | TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_exec failed"); |
| | if( zErr ) sqlite3_free(zErr); |
| | } |
| |
|
| | |
| | static SrcList *makeSrcList(sqlite3 *db, const char *zName){ |
| | Token tName; |
| | tName.z = zName; |
| | tName.n = (int)strlen(zName); |
| | return sqlite3SrcListAppend(db, 0, &tName, 0); |
| | } |
| |
|
| | |
| | static void initParse(sqlite3 *db, Parse *p){ |
| | memset(p, 0, sizeof(*p)); |
| | p->db = db; |
| | } |
| |
|
| | |
| | static void cleanupParse(sqlite3 *db, Parse *p){ |
| | if( p->zErrMsg ){ |
| | sqlite3DbFree(db, p->zErrMsg); |
| | p->zErrMsg = 0; |
| | } |
| | if( p->pVdbe ){ |
| | sqlite3VdbeDelete(p->pVdbe); |
| | p->pVdbe = 0; |
| | } |
| | } |
| |
|
| | void setUp(void) { |
| | |
| | } |
| |
|
| | void tearDown(void) { |
| | |
| | } |
| |
|
| | |
| | void test_sqlite3AlterDropColumn_no_such_column(void){ |
| | sqlite3 *db = 0; |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
| |
|
| | execSQL(db, "CREATE TABLE t1(a, b);"); |
| |
|
| | Parse p; |
| | initParse(db, &p); |
| | SrcList *pSrc = makeSrcList(db, "t1"); |
| |
|
| | Token tCol; |
| | tCol.z = "c"; |
| | tCol.n = 1; |
| |
|
| | sqlite3BtreeEnterAll(db); |
| | sqlite3AlterDropColumn(&p, pSrc, &tCol); |
| | sqlite3BtreeLeaveAll(db); |
| |
|
| | TEST_ASSERT_TRUE_MESSAGE(p.nErr>0, "Expected error for non-existent column"); |
| | TEST_ASSERT_NOT_NULL(p.zErrMsg); |
| | TEST_ASSERT_NOT_EQUAL(-1, (int)sqlite3StrLike("no such column:%", p.zErrMsg, 0)); |
| | |
| | TEST_ASSERT_NOT_EQUAL(NULL, strstr(p.zErrMsg, "no such column")); |
| |
|
| | cleanupParse(db, &p); |
| | sqlite3_close(db); |
| | } |
| |
|
| | |
| | void test_sqlite3AlterDropColumn_drop_primary_key_column(void){ |
| | sqlite3 *db = 0; |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
| |
|
| | execSQL(db, "CREATE TABLE tpk(a INTEGER PRIMARY KEY, b);"); |
| |
|
| | Parse p; |
| | initParse(db, &p); |
| | SrcList *pSrc = makeSrcList(db, "tpk"); |
| |
|
| | Token tCol; |
| | tCol.z = "a"; |
| | tCol.n = 1; |
| |
|
| | sqlite3BtreeEnterAll(db); |
| | sqlite3AlterDropColumn(&p, pSrc, &tCol); |
| | sqlite3BtreeLeaveAll(db); |
| |
|
| | TEST_ASSERT_TRUE_MESSAGE(p.nErr>0, "Expected error dropping PRIMARY KEY column"); |
| | TEST_ASSERT_NOT_NULL(p.zErrMsg); |
| | TEST_ASSERT_NOT_EQUAL(NULL, strstr(p.zErrMsg, "PRIMARY KEY")); |
| |
|
| | cleanupParse(db, &p); |
| | sqlite3_close(db); |
| | } |
| |
|
| | |
| | void test_sqlite3AlterDropColumn_drop_unique_column(void){ |
| | sqlite3 *db = 0; |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
| |
|
| | |
| | execSQL(db, "CREATE TABLE tu(a UNIQUE, b);"); |
| |
|
| | Parse p; |
| | initParse(db, &p); |
| | SrcList *pSrc = makeSrcList(db, "tu"); |
| |
|
| | Token tCol; |
| | tCol.z = "a"; |
| | tCol.n = 1; |
| |
|
| | sqlite3BtreeEnterAll(db); |
| | sqlite3AlterDropColumn(&p, pSrc, &tCol); |
| | sqlite3BtreeLeaveAll(db); |
| |
|
| | TEST_ASSERT_TRUE_MESSAGE(p.nErr>0, "Expected error dropping UNIQUE column"); |
| | TEST_ASSERT_NOT_NULL(p.zErrMsg); |
| | TEST_ASSERT_NOT_EQUAL(NULL, strstr(p.zErrMsg, "UNIQUE")); |
| |
|
| | cleanupParse(db, &p); |
| | sqlite3_close(db); |
| | } |
| |
|
| | |
| | void test_sqlite3AlterDropColumn_drop_only_remaining_column(void){ |
| | sqlite3 *db = 0; |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
| |
|
| | execSQL(db, "CREATE TABLE t1col(a);"); |
| |
|
| | Parse p; |
| | initParse(db, &p); |
| | SrcList *pSrc = makeSrcList(db, "t1col"); |
| |
|
| | Token tCol; |
| | tCol.z = "a"; |
| | tCol.n = 1; |
| |
|
| | sqlite3BtreeEnterAll(db); |
| | sqlite3AlterDropColumn(&p, pSrc, &tCol); |
| | sqlite3BtreeLeaveAll(db); |
| |
|
| | TEST_ASSERT_TRUE_MESSAGE(p.nErr>0, "Expected error dropping the only column"); |
| | TEST_ASSERT_NOT_NULL(p.zErrMsg); |
| | TEST_ASSERT_NOT_EQUAL(NULL, strstr(p.zErrMsg, "no other columns exist")); |
| |
|
| | cleanupParse(db, &p); |
| | sqlite3_close(db); |
| | } |
| |
|
| | |
| | void test_sqlite3AlterDropColumn_on_view(void){ |
| | sqlite3 *db = 0; |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
| |
|
| | execSQL(db, "CREATE VIEW v1 AS SELECT 1 AS a, 2 AS b;"); |
| |
|
| | Parse p; |
| | initParse(db, &p); |
| | SrcList *pSrc = makeSrcList(db, "v1"); |
| |
|
| | Token tCol; |
| | tCol.z = "a"; |
| | tCol.n = 1; |
| |
|
| | sqlite3BtreeEnterAll(db); |
| | sqlite3AlterDropColumn(&p, pSrc, &tCol); |
| | sqlite3BtreeLeaveAll(db); |
| |
|
| | TEST_ASSERT_TRUE_MESSAGE(p.nErr>0, "Expected error dropping column from view"); |
| | TEST_ASSERT_NOT_NULL(p.zErrMsg); |
| | TEST_ASSERT_NOT_EQUAL(NULL, strstr(p.zErrMsg, "drop column from view")); |
| |
|
| | cleanupParse(db, &p); |
| | sqlite3_close(db); |
| | } |
| |
|
| | |
| | void test_sqlite3AlterDropColumn_success_generates_vdbe(void){ |
| | sqlite3 *db = 0; |
| | TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
| |
|
| | execSQL(db, "CREATE TABLE tgood(a, b, c);"); |
| | execSQL(db, "INSERT INTO tgood VALUES(1,2,3);"); |
| |
|
| | Parse p; |
| | initParse(db, &p); |
| | SrcList *pSrc = makeSrcList(db, "tgood"); |
| |
|
| | Token tCol; |
| | tCol.z = "b"; |
| | tCol.n = 1; |
| |
|
| | sqlite3BtreeEnterAll(db); |
| | sqlite3AlterDropColumn(&p, pSrc, &tCol); |
| | sqlite3BtreeLeaveAll(db); |
| |
|
| | TEST_ASSERT_EQUAL_INT_MESSAGE(0, p.nErr, "Unexpected error during valid drop column codegen"); |
| | TEST_ASSERT_NOT_NULL_MESSAGE(p.pVdbe, "Expected VDBE code to be generated"); |
| | TEST_ASSERT_TRUE_MESSAGE(p.nMem>0 || p.nTab>0, "Expected some registers/cursors allocated"); |
| |
|
| | cleanupParse(db, &p); |
| | sqlite3_close(db); |
| | } |
| |
|
| | int main(void){ |
| | UNITY_BEGIN(); |
| | RUN_TEST(test_sqlite3AlterDropColumn_no_such_column); |
| | RUN_TEST(test_sqlite3AlterDropColumn_drop_primary_key_column); |
| | RUN_TEST(test_sqlite3AlterDropColumn_drop_unique_column); |
| | RUN_TEST(test_sqlite3AlterDropColumn_drop_only_remaining_column); |
| | RUN_TEST(test_sqlite3AlterDropColumn_on_view); |
| | RUN_TEST(test_sqlite3AlterDropColumn_success_generates_vdbe); |
| | return UNITY_END(); |
| | } |