sqlite / tests /tests_alter_renameQuotefixFunc.c
AryaWu's picture
Upload folder using huggingface_hub
7510827 verified
#include "sqliteInt.h"
#include "unity.h"
#include <string.h>
#include <stdlib.h>
/* Some builds may not expose the prototype in headers, so declare here. */
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) {
/* no-op */
}
void tearDown(void) {
/* no-op */
}
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);");
/* Ensure that a space is inserted to avoid adjacent literal concatenation */
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);
/* With writable_schema=ON and an error during processing, the original input is returned */
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);
/* Expect an error (no row) because name resolution fails and writable_schema is OFF */
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();
}