sqlite / tests /tests_alter_sqlite3AlterDropConstraint.c
AryaWu's picture
Upload folder using huggingface_hub
7510827 verified
#include "sqliteInt.h"
#include "unity.h"
#include <string.h>
#include <stdlib.h>
/* Unity setUp/tearDown */
void setUp(void) {
/* No global setup required */
}
void tearDown(void) {
/* No global teardown required */
}
/* Helper: create a SrcList with one item for table zTab in database zDb (or NULL for main) */
static SrcList *makeSrcListOne(sqlite3 *db, const char *zDb, const char *zTab){
/* SrcList has a flexible array a[1], so sizeof(SrcList) is sufficient for one element */
SrcList *p = (SrcList*)sqlite3DbMallocZero(db, sizeof(SrcList));
TEST_ASSERT_NOT_NULL_MESSAGE(p, "sqlite3DbMallocZero failed creating SrcList");
p->nAlloc = 1;
p->nSrc = 1;
p->a[0].zName = sqlite3DbStrDup(db, zTab);
TEST_ASSERT_NOT_NULL_MESSAGE(p->a[0].zName, "sqlite3DbStrDup failed for table name");
if( zDb ){
p->a[0].zDatabase = sqlite3DbStrDup(db, zDb);
TEST_ASSERT_NOT_NULL_MESSAGE(p->a[0].zDatabase, "sqlite3DbStrDup failed for database name");
}
return p;
}
/* Helper: make a Token from a C string literal */
static Token makeToken(const char *z){
Token t;
t.z = z;
t.n = (int)strlen(z);
return t;
}
/* Helper: initialize a Parse object for a given db */
static void initParse(Parse *pParse, sqlite3 *db){
memset(pParse, 0, sizeof(*pParse));
pParse->db = db;
}
/* Helper: exec SQL and assert SQLITE_OK */
static void execSqlOk(sqlite3 *db, const char *zSql){
int rc = sqlite3_exec(db, zSql, 0, 0, 0);
if( rc!=SQLITE_OK ){
const char *err = sqlite3_errmsg(db);
char msg[512];
sqlite3_snprintf(sizeof(msg), msg, "SQL exec failed (%d): %s; SQL: %s", rc, err ? err : "(null)", zSql);
TEST_FAIL_MESSAGE(msg);
}
}
/* Test: Nonexistent table should cause early return: no VDBE and an error recorded */
void test_sqlite3AlterDropConstraint_nonexistent_table(void){
sqlite3 *db = 0;
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));
Parse p;
initParse(&p, db);
SrcList *pSrc = makeSrcListOne(db, NULL, "nosuchtable");
Token cons = makeToken("c1");
sqlite3AlterDropConstraint(&p, pSrc, &cons, 0);
TEST_ASSERT_NULL_MESSAGE(p.pVdbe, "VDBE should not be created for nonexistent table");
TEST_ASSERT_TRUE_MESSAGE(p.nErr>0, "An error should be recorded for nonexistent table");
sqlite3SrcListDelete(db, pSrc);
if( p.pVdbe ) sqlite3VdbeDelete(p.pVdbe);
sqlite3_close(db);
}
/* Test: Existing table, drop NOT NULL from existing column -> code generated (VDBE created) */
void test_sqlite3AlterDropConstraint_drop_not_null_on_existing_col_generates_code(void){
sqlite3 *db = 0;
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));
execSqlOk(db, "CREATE TABLE t1(a INTEGER NOT NULL, b TEXT);");
Parse p;
initParse(&p, db);
SrcList *pSrc = makeSrcListOne(db, NULL, "t1");
Token col = makeToken("a");
sqlite3AlterDropConstraint(&p, pSrc, 0, &col);
TEST_ASSERT_NOT_NULL_MESSAGE(p.pVdbe, "VDBE should be created for valid DROP NOT NULL operation");
/* We do not execute the VDBE here; we only ensure code generation occurred. */
sqlite3SrcListDelete(db, pSrc);
if( p.pVdbe ) sqlite3VdbeDelete(p.pVdbe);
sqlite3_close(db);
}
/* Test: Existing table, drop NOT NULL from nonexistent column -> error, no VDBE */
void test_sqlite3AlterDropConstraint_nonexistent_column_reports_error(void){
sqlite3 *db = 0;
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));
execSqlOk(db, "CREATE TABLE t2(a INTEGER NOT NULL, b TEXT);");
Parse p;
initParse(&p, db);
SrcList *pSrc = makeSrcListOne(db, NULL, "t2");
Token col = makeToken("no_such_col");
sqlite3AlterDropConstraint(&p, pSrc, 0, &col);
TEST_ASSERT_NULL_MESSAGE(p.pVdbe, "VDBE should not be created when column does not exist");
TEST_ASSERT_TRUE_MESSAGE(p.nErr>0, "An error should be recorded for nonexistent column");
sqlite3SrcListDelete(db, pSrc);
if( p.pVdbe ) sqlite3VdbeDelete(p.pVdbe);
sqlite3_close(db);
}
/* Test: Existing table with named constraint, drop named constraint -> code generated */
void test_sqlite3AlterDropConstraint_drop_named_constraint_generates_code(void){
sqlite3 *db = 0;
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));
/* Create a table with a named CHECK constraint */
execSqlOk(db, "CREATE TABLE t3(x INT, y INT, CONSTRAINT c1 CHECK(x>0));");
Parse p;
initParse(&p, db);
SrcList *pSrc = makeSrcListOne(db, NULL, "t3");
Token cons = makeToken("c1");
sqlite3AlterDropConstraint(&p, pSrc, &cons, 0);
TEST_ASSERT_NOT_NULL_MESSAGE(p.pVdbe, "VDBE should be created for valid DROP CONSTRAINT operation");
sqlite3SrcListDelete(db, pSrc);
if( p.pVdbe ) sqlite3VdbeDelete(p.pVdbe);
sqlite3_close(db);
}
int main(void){
UNITY_BEGIN();
RUN_TEST(test_sqlite3AlterDropConstraint_nonexistent_table);
RUN_TEST(test_sqlite3AlterDropConstraint_drop_not_null_on_existing_col_generates_code);
RUN_TEST(test_sqlite3AlterDropConstraint_nonexistent_column_reports_error);
RUN_TEST(test_sqlite3AlterDropConstraint_drop_named_constraint_generates_code);
return UNITY_END();
}