sqlite / tests /tests_alter_isRealTable.c
AryaWu's picture
Upload folder using huggingface_hub
7510827 verified
#include "sqliteInt.h"
#include "unity.h"
#include <string.h>
#include <stdio.h>
/* The wrapper for the static function is provided by the build harness. */
extern int test_isRealTable(Parse *pParse, Table *pTab, int iOp);
void setUp(void) {
/* No global setup needed */
}
void tearDown(void) {
/* No global teardown needed */
}
static sqlite3* open_mem_db(void){
sqlite3 *db = 0;
int rc = sqlite3_open(":memory:", &db);
TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed");
TEST_ASSERT_NOT_NULL_MESSAGE(db, "db is NULL after sqlite3_open");
return db;
}
static void clear_parse_err(sqlite3 *db, Parse *pParse){
if( pParse->zErrMsg ){
sqlite3DbFree(db, pParse->zErrMsg);
pParse->zErrMsg = 0;
}
}
/* Helper to initialize a Parse object */
static void init_parse(Parse *pParse, sqlite3 *db){
memset(pParse, 0, sizeof(*pParse));
pParse->db = db;
}
/* Make a "real" table (neither view nor virtual) */
static void make_real_table(Table *pTab, const char *zName){
memset(pTab, 0, sizeof(*pTab));
pTab->zName = (char*)zName;
}
/* Make a "view" table */
static void make_view_table(Table *pTab, const char *zName){
memset(pTab, 0, sizeof(*pTab));
pTab->zName = (char*)zName;
/* Make IsView(pTab) evaluate true across SQLite versions */
static Select dummySelect; /* address used, not dereferenced */
memset(&dummySelect, 0, sizeof(dummySelect));
pTab->pSelect = &dummySelect;
#ifdef TF_View
pTab->tabFlags |= TF_View;
#endif
}
/* Make a "virtual" table */
static void make_virtual_table(Table *pTab, const char *zName){
memset(pTab, 0, sizeof(*pTab));
pTab->zName = (char*)zName;
#ifdef TF_Virtual
pTab->tabFlags |= TF_Virtual;
#else
/* TF_Virtual should exist in modern SQLite, but ensure some non-zero to hint IsVirtual if macro differs */
pTab->tabFlags = 0xFFFFFFFF;
#endif
}
void test_isRealTable_returns_zero_for_real_table(void){
sqlite3 *db = open_mem_db();
Parse parse;
init_parse(&parse, db);
Table tab;
make_real_table(&tab, "t_real");
int rc = test_isRealTable(&parse, &tab, 0);
TEST_ASSERT_EQUAL_INT(0, rc);
TEST_ASSERT_NULL(parse.zErrMsg);
sqlite3_close(db);
}
void test_isRealTable_view_rename_columns_sets_error(void){
sqlite3 *db = open_mem_db();
Parse parse;
init_parse(&parse, db);
Table tab;
make_view_table(&tab, "v1");
int rc = test_isRealTable(&parse, &tab, 0); /* "rename columns of" */
TEST_ASSERT_EQUAL_INT(1, rc);
TEST_ASSERT_NOT_NULL(parse.zErrMsg);
/* Expect: cannot rename columns of view "v1" */
const char *msg = parse.zErrMsg;
TEST_ASSERT_NOT_NULL(strstr(msg, "cannot "));
TEST_ASSERT_NOT_NULL(strstr(msg, "rename columns of"));
TEST_ASSERT_NOT_NULL(strstr(msg, "view"));
TEST_ASSERT_NOT_NULL(strstr(msg, "\"v1\""));
clear_parse_err(db, &parse);
sqlite3_close(db);
}
void test_isRealTable_view_drop_column_sets_error(void){
sqlite3 *db = open_mem_db();
Parse parse;
init_parse(&parse, db);
Table tab;
make_view_table(&tab, "v_drop");
int rc = test_isRealTable(&parse, &tab, 1); /* "drop column from" */
TEST_ASSERT_EQUAL_INT(1, rc);
TEST_ASSERT_NOT_NULL(parse.zErrMsg);
const char *msg = parse.zErrMsg;
TEST_ASSERT_NOT_NULL(strstr(msg, "cannot "));
TEST_ASSERT_NOT_NULL(strstr(msg, "drop column from"));
TEST_ASSERT_NOT_NULL(strstr(msg, "view"));
TEST_ASSERT_NOT_NULL(strstr(msg, "\"v_drop\""));
clear_parse_err(db, &parse);
sqlite3_close(db);
}
void test_isRealTable_virtual_edit_constraints_sets_error(void){
sqlite3 *db = open_mem_db();
Parse parse;
init_parse(&parse, db);
Table tab;
make_virtual_table(&tab, "vt1");
int rc = test_isRealTable(&parse, &tab, 2); /* "edit constraints of" */
TEST_ASSERT_EQUAL_INT(1, rc);
TEST_ASSERT_NOT_NULL(parse.zErrMsg);
const char *msg = parse.zErrMsg;
TEST_ASSERT_NOT_NULL(strstr(msg, "cannot "));
TEST_ASSERT_NOT_NULL(strstr(msg, "edit constraints of"));
TEST_ASSERT_NOT_NULL(strstr(msg, "virtual table"));
TEST_ASSERT_NOT_NULL(strstr(msg, "\"vt1\""));
clear_parse_err(db, &parse);
sqlite3_close(db);
}
void test_isRealTable_both_view_and_virtual_prefers_virtual_in_message(void){
sqlite3 *db = open_mem_db();
Parse parse;
init_parse(&parse, db);
Table tab;
make_view_table(&tab, "bothy");
/* Also mark as virtual so the second branch overwrites zType */
#ifdef TF_Virtual
tab.tabFlags |= TF_Virtual;
#endif
int rc = test_isRealTable(&parse, &tab, 0);
TEST_ASSERT_EQUAL_INT(1, rc);
TEST_ASSERT_NOT_NULL(parse.zErrMsg);
const char *msg = parse.zErrMsg;
/* Ensure "virtual table" appears (wins over "view") */
TEST_ASSERT_NOT_NULL(strstr(msg, "virtual table"));
TEST_ASSERT_NOT_NULL(strstr(msg, "\"bothy\""));
clear_parse_err(db, &parse);
sqlite3_close(db);
}
int main(void) {
UNITY_BEGIN();
RUN_TEST(test_isRealTable_returns_zero_for_real_table);
RUN_TEST(test_isRealTable_view_rename_columns_sets_error);
RUN_TEST(test_isRealTable_view_drop_column_sets_error);
RUN_TEST(test_isRealTable_virtual_edit_constraints_sets_error);
RUN_TEST(test_isRealTable_both_view_and_virtual_prefers_virtual_in_message);
return UNITY_END();
}