|
|
#include "sqliteInt.h" |
|
|
#include "unity.h" |
|
|
#include <string.h> |
|
|
#include <stdio.h> |
|
|
#include <stdlib.h> |
|
|
|
|
|
|
|
|
extern void test_renameColumnFunc(sqlite3_context *context, int NotUsed, sqlite3_value **argv); |
|
|
|
|
|
|
|
|
void setUp(void) { |
|
|
|
|
|
} |
|
|
void tearDown(void) { |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
static sqlite3_value *make_text_value(sqlite3 *db, const char *z){ |
|
|
Mem *p = sqlite3ValueNew(db); |
|
|
if( z ){ |
|
|
sqlite3VdbeMemSetStr(p, z, (int)strlen(z), SQLITE_UTF8, SQLITE_TRANSIENT); |
|
|
}else{ |
|
|
sqlite3VdbeMemSetNull(p); |
|
|
} |
|
|
return (sqlite3_value*)p; |
|
|
} |
|
|
static sqlite3_value *make_int_value(sqlite3 *db, int v){ |
|
|
Mem *p = sqlite3ValueNew(db); |
|
|
sqlite3VdbeMemSetInt64(p, (i64)v); |
|
|
return (sqlite3_value*)p; |
|
|
} |
|
|
static void free_value(sqlite3 *db, sqlite3_value *v){ |
|
|
if( v ){ |
|
|
sqlite3ValueFree((Mem*)v); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static void exec_ok(sqlite3 *db, const char *zSql){ |
|
|
char *zErr = 0; |
|
|
int rc = sqlite3_exec(db, zSql, 0, 0, &zErr); |
|
|
if( rc!=SQLITE_OK ){ |
|
|
|
|
|
fprintf(stderr, "exec error: rc=%d sql=[%s] err=[%s]\n", rc, zSql, zErr ? zErr : "(null)"); |
|
|
} |
|
|
TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_exec failed"); |
|
|
sqlite3_free(zErr); |
|
|
} |
|
|
|
|
|
|
|
|
static char *call_rename( |
|
|
sqlite3 *db, |
|
|
const char *zSql, |
|
|
const char *zType, |
|
|
const char *zObject, |
|
|
const char *zDb, |
|
|
const char *zTable, |
|
|
int iCol, |
|
|
const char *zNew, |
|
|
int bQuote, |
|
|
int bTemp |
|
|
){ |
|
|
sqlite3_value *argv[9]; |
|
|
sqlite3_context ctx; |
|
|
Mem out; |
|
|
char *zRet = NULL; |
|
|
|
|
|
|
|
|
argv[0] = make_text_value(db, zSql); |
|
|
argv[1] = make_text_value(db, zType); |
|
|
argv[2] = make_text_value(db, zObject); |
|
|
argv[3] = make_text_value(db, zDb); |
|
|
argv[4] = make_text_value(db, zTable); |
|
|
argv[5] = make_int_value(db, iCol); |
|
|
argv[6] = make_text_value(db, zNew); |
|
|
argv[7] = make_int_value(db, bQuote); |
|
|
argv[8] = make_int_value(db, bTemp); |
|
|
|
|
|
|
|
|
memset(&ctx, 0, sizeof(ctx)); |
|
|
memset(&out, 0, sizeof(out)); |
|
|
out.db = db; |
|
|
sqlite3VdbeMemZero(&out); |
|
|
ctx.db = db; |
|
|
ctx.pOut = &out; |
|
|
|
|
|
|
|
|
test_renameColumnFunc(&ctx, 9, argv); |
|
|
|
|
|
|
|
|
if( (out.flags & MEM_Str)!=0 && out.z!=0 ){ |
|
|
zRet = sqlite3_mprintf("%s", out.z); |
|
|
}else{ |
|
|
zRet = NULL; |
|
|
} |
|
|
|
|
|
|
|
|
sqlite3VdbeMemRelease(&out); |
|
|
for(int i=0;i<9;i++) free_value(db, argv[i]); |
|
|
|
|
|
return zRet; |
|
|
} |
|
|
|
|
|
|
|
|
void test_renameColumnFunc_table_basic_unquoted_noquote(void){ |
|
|
sqlite3 *db = 0; |
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
|
|
exec_ok(db, "CREATE TABLE t(a, b, c)"); |
|
|
|
|
|
const char *zSql = "CREATE TABLE t(a, b, c)"; |
|
|
char *zOut = call_rename(db, zSql, "table", "t", "main", "t", 1, "d", 0, 0); |
|
|
TEST_ASSERT_NOT_NULL(zOut); |
|
|
TEST_ASSERT_EQUAL_STRING("CREATE TABLE t(a, d, c)", zOut); |
|
|
|
|
|
sqlite3_free(zOut); |
|
|
sqlite3_close(db); |
|
|
} |
|
|
|
|
|
|
|
|
void test_renameColumnFunc_table_basic_unquoted_forcequote(void){ |
|
|
sqlite3 *db = 0; |
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
|
|
exec_ok(db, "CREATE TABLE t(a, b, c)"); |
|
|
|
|
|
const char *zSql = "CREATE TABLE t(a, b, c)"; |
|
|
char *zOut = call_rename(db, zSql, "table", "t", "main", "t", 1, "d", 1, 0); |
|
|
TEST_ASSERT_NOT_NULL(zOut); |
|
|
TEST_ASSERT_EQUAL_STRING("CREATE TABLE t(a, \"d\", c)", zOut); |
|
|
|
|
|
sqlite3_free(zOut); |
|
|
sqlite3_close(db); |
|
|
} |
|
|
|
|
|
|
|
|
void test_renameColumnFunc_table_original_quoted(void){ |
|
|
sqlite3 *db = 0; |
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
|
|
exec_ok(db, "CREATE TABLE t(\"a\", \"b\", c)"); |
|
|
|
|
|
const char *zSql = "CREATE TABLE t(\"a\", \"b\", c)"; |
|
|
char *zOut = call_rename(db, zSql, "table", "t", "main", "t", 1, "x", 0, 0); |
|
|
TEST_ASSERT_NOT_NULL(zOut); |
|
|
TEST_ASSERT_EQUAL_STRING("CREATE TABLE t(\"a\", \"x\", c)", zOut); |
|
|
|
|
|
sqlite3_free(zOut); |
|
|
sqlite3_close(db); |
|
|
} |
|
|
|
|
|
|
|
|
void test_renameColumnFunc_view_rewrite_select_list(void){ |
|
|
sqlite3 *db = 0; |
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
|
|
exec_ok(db, "CREATE TABLE t(a, b)"); |
|
|
|
|
|
const char *zSql = "CREATE VIEW v AS SELECT a, b FROM t"; |
|
|
char *zOut = call_rename(db, zSql, "view", "v", "main", "t", 1, "d", 0, 0); |
|
|
TEST_ASSERT_NOT_NULL(zOut); |
|
|
TEST_ASSERT_EQUAL_STRING("CREATE VIEW v AS SELECT a, d FROM t", zOut); |
|
|
|
|
|
sqlite3_free(zOut); |
|
|
sqlite3_close(db); |
|
|
} |
|
|
|
|
|
|
|
|
void test_renameColumnFunc_trigger_update_of_clause(void){ |
|
|
sqlite3 *db = 0; |
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
|
|
exec_ok(db, "CREATE TABLE t(a, b)"); |
|
|
|
|
|
const char *zSql = |
|
|
"CREATE TRIGGER tr AFTER UPDATE OF b ON t BEGIN SELECT 1; END"; |
|
|
char *zOut = call_rename(db, zSql, "trigger", "tr", "main", "t", 1, "d", 0, 0); |
|
|
TEST_ASSERT_NOT_NULL(zOut); |
|
|
TEST_ASSERT_EQUAL_STRING( |
|
|
"CREATE TRIGGER tr AFTER UPDATE OF d ON t BEGIN SELECT 1; END", zOut |
|
|
); |
|
|
|
|
|
sqlite3_free(zOut); |
|
|
sqlite3_close(db); |
|
|
} |
|
|
|
|
|
|
|
|
void test_renameColumnFunc_invalid_col_index_no_result(void){ |
|
|
sqlite3 *db = 0; |
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
|
|
exec_ok(db, "CREATE TABLE t(a, b)"); |
|
|
|
|
|
const char *zSql = "CREATE TABLE t(a, b)"; |
|
|
|
|
|
char *zOut = call_rename(db, zSql, "table", "t", "main", "t", 2, "d", 0, 0); |
|
|
TEST_ASSERT_NULL(zOut); |
|
|
|
|
|
sqlite3_free(zOut); |
|
|
sqlite3_close(db); |
|
|
} |
|
|
|
|
|
|
|
|
void test_renameColumnFunc_wrong_table_no_result(void){ |
|
|
sqlite3 *db = 0; |
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db)); |
|
|
exec_ok(db, "CREATE TABLE t(a, b)"); |
|
|
|
|
|
const char *zSql = "CREATE TABLE t(a, b)"; |
|
|
char *zOut = call_rename(db, zSql, "table", "t", "main", "nope", 1, "d", 0, 0); |
|
|
TEST_ASSERT_NULL(zOut); |
|
|
|
|
|
sqlite3_free(zOut); |
|
|
sqlite3_close(db); |
|
|
} |
|
|
|
|
|
int main(void){ |
|
|
UNITY_BEGIN(); |
|
|
RUN_TEST(test_renameColumnFunc_table_basic_unquoted_noquote); |
|
|
RUN_TEST(test_renameColumnFunc_table_basic_unquoted_forcequote); |
|
|
RUN_TEST(test_renameColumnFunc_table_original_quoted); |
|
|
RUN_TEST(test_renameColumnFunc_view_rewrite_select_list); |
|
|
RUN_TEST(test_renameColumnFunc_trigger_update_of_clause); |
|
|
RUN_TEST(test_renameColumnFunc_invalid_col_index_no_result); |
|
|
RUN_TEST(test_renameColumnFunc_wrong_table_no_result); |
|
|
return UNITY_END(); |
|
|
} |