|
|
#include "sqliteInt.h" |
|
|
#include "unity.h" |
|
|
#include <string.h> |
|
|
#include <stdlib.h> |
|
|
|
|
|
|
|
|
extern void sqlite3AlterFunctions(sqlite3*); |
|
|
|
|
|
static char* call_rename_quotefix(sqlite3 *db, const char *zDb, const char *zInput, int *pRc){ |
|
|
char *zSQL = sqlite3_mprintf("SELECT sqlite_rename_quotefix(%Q,%Q)", zDb, zInput); |
|
|
sqlite3_stmt *pStmt = 0; |
|
|
int rc = sqlite3_prepare_v2(db, zSQL, -1, &pStmt, 0); |
|
|
sqlite3_free(zSQL); |
|
|
if( rc!=SQLITE_OK ){ |
|
|
if(pRc) *pRc = rc; |
|
|
return NULL; |
|
|
} |
|
|
rc = sqlite3_step(pStmt); |
|
|
char *zRes = NULL; |
|
|
if( rc==SQLITE_ROW ){ |
|
|
const unsigned char *z = sqlite3_column_text(pStmt, 0); |
|
|
if( z ){ |
|
|
zRes = sqlite3_mprintf("%s", z); |
|
|
} |
|
|
rc = SQLITE_OK; |
|
|
} |
|
|
int rc2 = sqlite3_finalize(pStmt); |
|
|
if( rc==SQLITE_OK && rc2!=SQLITE_OK ) rc = rc2; |
|
|
if( pRc ) *pRc = rc; |
|
|
return zRes; |
|
|
} |
|
|
|
|
|
static void execSQL(sqlite3 *db, const char *zSql){ |
|
|
char *zErr = 0; |
|
|
int rc = sqlite3_exec(db, zSql, 0, 0, &zErr); |
|
|
TEST_ASSERT_EQUAL_MESSAGE(SQLITE_OK, rc, zErr ? zErr : "execSQL failed"); |
|
|
if( zErr ) sqlite3_free(zErr); |
|
|
} |
|
|
|
|
|
void setUp(void) { |
|
|
|
|
|
} |
|
|
|
|
|
void tearDown(void) { |
|
|
|
|
|
} |
|
|
|
|
|
void test_renameQuotefixFunc_view_basic(void){ |
|
|
sqlite3 *db = 0; int rc; |
|
|
TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db)); |
|
|
sqlite3AlterFunctions(db); |
|
|
execSQL(db, "CREATE TABLE t1(a, b, c);"); |
|
|
|
|
|
const char *inSql = "CREATE VIEW v1 AS SELECT \"a\", \"string\" FROM t1"; |
|
|
char *out = call_rename_quotefix(db, "main", inSql, &rc); |
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc); |
|
|
TEST_ASSERT_NOT_NULL(out); |
|
|
TEST_ASSERT_EQUAL_STRING("CREATE VIEW v1 AS SELECT \"a\", 'string' FROM t1", out); |
|
|
|
|
|
sqlite3_free(out); |
|
|
sqlite3_close(db); |
|
|
} |
|
|
|
|
|
void test_renameQuotefixFunc_table_check_expr(void){ |
|
|
sqlite3 *db = 0; int rc; |
|
|
TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db)); |
|
|
sqlite3AlterFunctions(db); |
|
|
|
|
|
const char *inSql = "CREATE TABLE t2(a CHECK(\"ok\" IN (\"ok\",\"bad\")))"; |
|
|
char *out = call_rename_quotefix(db, "main", inSql, &rc); |
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc); |
|
|
TEST_ASSERT_NOT_NULL(out); |
|
|
TEST_ASSERT_EQUAL_STRING("CREATE TABLE t2(a CHECK('ok' IN ('ok','bad')))", out); |
|
|
|
|
|
sqlite3_free(out); |
|
|
sqlite3_close(db); |
|
|
} |
|
|
|
|
|
void test_renameQuotefixFunc_index_partial_where(void){ |
|
|
sqlite3 *db = 0; int rc; |
|
|
TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db)); |
|
|
sqlite3AlterFunctions(db); |
|
|
execSQL(db, "CREATE TABLE t1(a, b);"); |
|
|
|
|
|
const char *inSql = "CREATE INDEX i1 ON t1(a) WHERE b=\"str\""; |
|
|
char *out = call_rename_quotefix(db, "main", inSql, &rc); |
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc); |
|
|
TEST_ASSERT_NOT_NULL(out); |
|
|
TEST_ASSERT_EQUAL_STRING("CREATE INDEX i1 ON t1(a) WHERE b='str'", out); |
|
|
|
|
|
sqlite3_free(out); |
|
|
sqlite3_close(db); |
|
|
} |
|
|
|
|
|
void test_renameQuotefixFunc_trigger_when_and_step(void){ |
|
|
sqlite3 *db = 0; int rc; |
|
|
TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db)); |
|
|
sqlite3AlterFunctions(db); |
|
|
execSQL(db, "CREATE TABLE t1(a, b);"); |
|
|
|
|
|
const char *inSql = |
|
|
"CREATE TRIGGER tr1 AFTER INSERT ON t1 " |
|
|
"WHEN \"string\"='x' BEGIN UPDATE t1 SET a=1 WHERE b=\"y\"; END"; |
|
|
|
|
|
char *out = call_rename_quotefix(db, "main", inSql, &rc); |
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc); |
|
|
TEST_ASSERT_NOT_NULL(out); |
|
|
TEST_ASSERT_EQUAL_STRING( |
|
|
"CREATE TRIGGER tr1 AFTER INSERT ON t1 " |
|
|
"WHEN 'string'='x' BEGIN UPDATE t1 SET a=1 WHERE b='y'; END", |
|
|
out |
|
|
); |
|
|
|
|
|
sqlite3_free(out); |
|
|
sqlite3_close(db); |
|
|
} |
|
|
|
|
|
void test_renameQuotefixFunc_adjacent_single_quote_alias_spacing(void){ |
|
|
sqlite3 *db = 0; int rc; |
|
|
TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db)); |
|
|
sqlite3AlterFunctions(db); |
|
|
execSQL(db, "CREATE TABLE t1(a);"); |
|
|
|
|
|
|
|
|
const char *inSql = "CREATE VIEW v2 AS SELECT \"string\"'alias' FROM t1"; |
|
|
char *out = call_rename_quotefix(db, "main", inSql, &rc); |
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc); |
|
|
TEST_ASSERT_NOT_NULL(out); |
|
|
TEST_ASSERT_EQUAL_STRING("CREATE VIEW v2 AS SELECT 'string' 'alias' FROM t1", out); |
|
|
|
|
|
sqlite3_free(out); |
|
|
sqlite3_close(db); |
|
|
} |
|
|
|
|
|
void test_renameQuotefixFunc_writable_schema_returns_input_on_error(void){ |
|
|
sqlite3 *db = 0; int rc; |
|
|
TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db)); |
|
|
sqlite3AlterFunctions(db); |
|
|
|
|
|
execSQL(db, "PRAGMA writable_schema=ON;"); |
|
|
const char *inSql = "CREATE VIEW v_bad AS SELECT \"x\" FROM nosuchtable"; |
|
|
char *out = call_rename_quotefix(db, "main", inSql, &rc); |
|
|
|
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc); |
|
|
TEST_ASSERT_NOT_NULL(out); |
|
|
TEST_ASSERT_EQUAL_STRING(inSql, out); |
|
|
|
|
|
sqlite3_free(out); |
|
|
sqlite3_close(db); |
|
|
} |
|
|
|
|
|
void test_renameQuotefixFunc_error_without_writable_schema(void){ |
|
|
sqlite3 *db = 0; int rc; |
|
|
TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db)); |
|
|
sqlite3AlterFunctions(db); |
|
|
|
|
|
const char *inSql = "CREATE VIEW v_bad AS SELECT \"x\" FROM nosuchtable"; |
|
|
char *out = call_rename_quotefix(db, "main", inSql, &rc); |
|
|
|
|
|
TEST_ASSERT_NULL(out); |
|
|
TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc); |
|
|
|
|
|
sqlite3_close(db); |
|
|
} |
|
|
|
|
|
int main(void){ |
|
|
UNITY_BEGIN(); |
|
|
RUN_TEST(test_renameQuotefixFunc_view_basic); |
|
|
RUN_TEST(test_renameQuotefixFunc_table_check_expr); |
|
|
RUN_TEST(test_renameQuotefixFunc_index_partial_where); |
|
|
RUN_TEST(test_renameQuotefixFunc_trigger_when_and_step); |
|
|
RUN_TEST(test_renameQuotefixFunc_adjacent_single_quote_alias_spacing); |
|
|
RUN_TEST(test_renameQuotefixFunc_writable_schema_returns_input_on_error); |
|
|
RUN_TEST(test_renameQuotefixFunc_error_without_writable_schema); |
|
|
return UNITY_END(); |
|
|
} |