sqlite / tests /tests_alter_dropColumnFunc.c
AryaWu's picture
Upload folder using huggingface_hub
7510827 verified
#include "sqliteInt.h"
#include "unity.h"
#include <stdlib.h>
#include <string.h>
/* The wrapper for the static function is provided by the module build. */
extern void test_dropColumnFunc(sqlite3_context *context, int NotUsed, sqlite3_value **argv);
static sqlite3 *gDb = NULL;
/* UDF trampoline that forwards directly to the function-under-test. */
static void udf_call_drop_column(sqlite3_context *ctx, int argc, sqlite3_value **argv){
/* Expect exactly 3 arguments as specified by dropColumnFunc. */
if( argc!=3 ){
sqlite3_result_error_code(ctx, SQLITE_MISUSE);
return;
}
test_dropColumnFunc(ctx, 0, argv);
}
/* Helper: Execute SELECT call_drop_column(?, ?, ?) and capture result text or error. */
static int run_drop_and_capture(
int iSchema, /* argv[0] */
const char *zCreate, /* argv[1] - may be NULL */
int iCol, /* argv[2] */
char **pzResult, /* OUT: sqlite3_malloc'ed copy (via sqlite3_mprintf) of result text if SQLITE_ROW */
int *pDbErr /* OUT: sqlite3_errcode(db) if not SQLITE_ROW, else SQLITE_OK */
){
sqlite3_stmt *pStmt = NULL;
int rcPrep = sqlite3_prepare_v2(gDb, "SELECT call_drop_column(?, ?, ?)", -1, &pStmt, 0);
if( rcPrep!=SQLITE_OK ){
if( pDbErr ) *pDbErr = rcPrep;
return rcPrep;
}
sqlite3_bind_int(pStmt, 1, iSchema);
if( zCreate ){
sqlite3_bind_text(pStmt, 2, zCreate, -1, SQLITE_TRANSIENT);
}else{
sqlite3_bind_null(pStmt, 2);
}
sqlite3_bind_int(pStmt, 3, iCol);
int rcStep = sqlite3_step(pStmt);
if( rcStep==SQLITE_ROW ){
const unsigned char *z = sqlite3_column_text(pStmt, 0);
if( z && pzResult ){
*pzResult = sqlite3_mprintf("%s", z);
}
if( pDbErr ) *pDbErr = SQLITE_OK;
}else{
if( pDbErr ) *pDbErr = sqlite3_errcode(gDb);
}
sqlite3_finalize(pStmt);
return rcStep;
}
void setUp(void) {
int rc = sqlite3_open(":memory:", &gDb);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
sqlite3_extended_result_codes(gDb, 1);
rc = sqlite3_create_function(gDb, "call_drop_column", 3, SQLITE_UTF8, NULL,
udf_call_drop_column, NULL, NULL);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
}
void tearDown(void) {
if( gDb ){
sqlite3_close(gDb);
gDb = NULL;
}
}
/* Simple: drop first column */
void test_dropColumnFunc_drop_first_simple(void){
char *zOut = NULL; int err = SQLITE_OK;
int rc = run_drop_and_capture(0, "CREATE TABLE t(a,b,c)", 0, &zOut, &err);
TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, err);
TEST_ASSERT_NOT_NULL(zOut);
TEST_ASSERT_EQUAL_STRING("CREATE TABLE t(b,c)", zOut);
sqlite3_free(zOut);
}
/* Simple: drop middle column */
void test_dropColumnFunc_drop_middle_simple(void){
char *zOut = NULL; int err = SQLITE_OK;
int rc = run_drop_and_capture(0, "CREATE TABLE t(a,b,c)", 1, &zOut, &err);
TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, err);
TEST_ASSERT_NOT_NULL(zOut);
TEST_ASSERT_EQUAL_STRING("CREATE TABLE t(a,c)", zOut);
sqlite3_free(zOut);
}
/* Simple: drop last column */
void test_dropColumnFunc_drop_last_simple(void){
char *zOut = NULL; int err = SQLITE_OK;
int rc = run_drop_and_capture(0, "CREATE TABLE t(a,b,c)", 2, &zOut, &err);
TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, err);
TEST_ASSERT_NOT_NULL(zOut);
TEST_ASSERT_EQUAL_STRING("CREATE TABLE t(a,b)", zOut);
sqlite3_free(zOut);
}
/* Drop last column when previous column has nested parentheses and commas in constraints */
void test_dropColumnFunc_drop_last_with_nested_constraints(void){
const char *zCreate =
"CREATE TABLE t(a, b TEXT CHECK(b IN (1,2,3) AND (b IS NOT NULL)), c)";
char *zOut = NULL; int err = SQLITE_OK;
int rc = run_drop_and_capture(0, zCreate, 2, &zOut, &err);
TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, err);
TEST_ASSERT_NOT_NULL(zOut);
TEST_ASSERT_EQUAL_STRING(
"CREATE TABLE t(a, b TEXT CHECK(b IN (1,2,3) AND (b IS NOT NULL)))", zOut);
sqlite3_free(zOut);
}
/* Error: invalid column index (>= nCol) */
void test_dropColumnFunc_invalid_index_error(void){
int err = SQLITE_OK;
int rc = run_drop_and_capture(0, "CREATE TABLE t(a,b)", 5, NULL, &err);
TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);
TEST_ASSERT_EQUAL_INT(SQLITE_CORRUPT, err);
}
/* Error: single-column table cannot drop (nCol==1) */
void test_dropColumnFunc_single_column_error(void){
int err = SQLITE_OK;
int rc = run_drop_and_capture(0, "CREATE TABLE t(a)", 0, NULL, &err);
TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);
TEST_ASSERT_EQUAL_INT(SQLITE_CORRUPT, err);
}
/* Error: SQL not starting with CREATE should produce corruption error */
void test_dropColumnFunc_invalid_sql_error(void){
int err = SQLITE_OK;
int rc = run_drop_and_capture(0, "DROP TABLE t", 0, NULL, &err);
TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);
TEST_ASSERT_EQUAL_INT(SQLITE_CORRUPT, err);
}
/* Temp schema path (iSchema==1) */
void test_dropColumnFunc_temp_schema(void){
char *zOut = NULL; int err = SQLITE_OK;
int rc = run_drop_and_capture(1, "CREATE TABLE t(a,b)", 1, &zOut, &err);
TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, err);
TEST_ASSERT_NOT_NULL(zOut);
TEST_ASSERT_EQUAL_STRING("CREATE TABLE t(a)", zOut);
sqlite3_free(zOut);
}
/* Quoted identifiers and spacing preserved */
void test_dropColumnFunc_preserves_quotes_and_spacing(void){
const char *zCreate =
"CREATE TABLE \"My T\"( \"a1\" INTEGER PRIMARY KEY, \"b-2\" TEXT, c )";
char *zOut = NULL; int err = SQLITE_OK;
int rc = run_drop_and_capture(0, zCreate, 1, &zOut, &err);
TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, err);
TEST_ASSERT_NOT_NULL(zOut);
TEST_ASSERT_EQUAL_STRING(
"CREATE TABLE \"My T\"( \"a1\" INTEGER PRIMARY KEY, c )", zOut);
sqlite3_free(zOut);
}
/* NULL SQL argument -> treated as SQLITE_NOMEM by renameParseSql */
void test_dropColumnFunc_null_sql_error(void){
int err = SQLITE_OK;
int rc = run_drop_and_capture(0, NULL, 0, NULL, &err);
TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);
TEST_ASSERT_EQUAL_INT(SQLITE_NOMEM, err);
}
int main(void) {
UNITY_BEGIN();
RUN_TEST(test_dropColumnFunc_drop_first_simple);
RUN_TEST(test_dropColumnFunc_drop_middle_simple);
RUN_TEST(test_dropColumnFunc_drop_last_simple);
RUN_TEST(test_dropColumnFunc_drop_last_with_nested_constraints);
RUN_TEST(test_dropColumnFunc_invalid_index_error);
RUN_TEST(test_dropColumnFunc_single_column_error);
RUN_TEST(test_dropColumnFunc_invalid_sql_error);
RUN_TEST(test_dropColumnFunc_temp_schema);
RUN_TEST(test_dropColumnFunc_preserves_quotes_and_spacing);
RUN_TEST(test_dropColumnFunc_null_sql_error);
return UNITY_END();
}