sqlite / tests /tests_alter_sqlite3AlterRenameColumn.c
AryaWu's picture
Upload folder using huggingface_hub
7510827 verified
#include "sqliteInt.h"
#include "unity.h"
#include <string.h>
#include <stdlib.h>
/* Helpers */
static Token mkToken(const char *z){
Token t;
t.z = z;
t.n = (int)strlen(z);
return t;
}
static SrcList* makeSrcList(sqlite3 *db, const char *zDbName, const char *zTab){
/* Allocate a SrcList with a single item using SQLite's allocator so that
sqlite3SrcListDelete() in the target function can free it safely. */
SrcList *p = (SrcList*)sqlite3DbMallocZero(db, sizeof(SrcList));
TEST_ASSERT_NOT_NULL_MESSAGE(p, "Failed to allocate SrcList");
p->nAlloc = 1;
p->nSrc = 1;
p->a[0].zName = sqlite3DbStrDup(db, zTab);
TEST_ASSERT_NOT_NULL_MESSAGE(p->a[0].zName, "Failed to dup table name");
if( zDbName ){
p->a[0].zDatabase = sqlite3DbStrDup(db, zDbName);
TEST_ASSERT_NOT_NULL_MESSAGE(p->a[0].zDatabase, "Failed to dup db name");
}
return p;
}
static void parseInit(Parse *pParse, sqlite3 *db){
memset(pParse, 0, sizeof(Parse));
pParse->db = db;
}
static void parseCleanup(Parse *pParse){
if( pParse->pVdbe ){
sqlite3VdbeDelete(pParse->pVdbe);
pParse->pVdbe = NULL;
}
if( pParse->zErrMsg ){
sqlite3DbFree(pParse->db, pParse->zErrMsg);
pParse->zErrMsg = NULL;
}
}
/* Unity hooks */
void setUp(void) {
/* no-op */
}
void tearDown(void) {
/* no-op */
}
/* Tests */
void test_sqlite3AlterRenameColumn_no_such_table(void){
sqlite3 *db = 0;
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));
Parse p; parseInit(&p, db);
SrcList *pSrc = makeSrcList(db, NULL, "nope_table");
Token oldTok = mkToken("a");
Token newTok = mkToken("b");
sqlite3AlterRenameColumn(&p, pSrc, &oldTok, &newTok);
TEST_ASSERT_TRUE_MESSAGE(p.nErr>0 || p.zErrMsg!=NULL, "Expected error for missing table");
/* Expect no VDBE was generated */
TEST_ASSERT_NULL(p.pVdbe);
parseCleanup(&p);
sqlite3_close(db);
}
void test_sqlite3AlterRenameColumn_view_error(void){
sqlite3 *db = 0;
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_exec(db,
"CREATE TABLE t1(a,b);"
"CREATE VIEW v1 AS SELECT a,b FROM t1;", 0, 0, 0));
Parse p; parseInit(&p, db);
SrcList *pSrc = makeSrcList(db, NULL, "v1");
Token oldTok = mkToken("a");
Token newTok = mkToken("x");
sqlite3AlterRenameColumn(&p, pSrc, &oldTok, &newTok);
TEST_ASSERT_TRUE(p.nErr>0);
TEST_ASSERT_NOT_NULL(p.zErrMsg);
TEST_ASSERT_NOT_EQUAL(NULL, strstr(p.zErrMsg, "cannot rename columns of"));
/* Should not generate code on error */
TEST_ASSERT_NULL(p.pVdbe);
parseCleanup(&p);
sqlite3_close(db);
}
void test_sqlite3AlterRenameColumn_column_not_found(void){
sqlite3 *db = 0;
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_exec(db,
"CREATE TABLE t1(a,b);", 0, 0, 0));
Parse p; parseInit(&p, db);
SrcList *pSrc = makeSrcList(db, NULL, "t1");
Token oldTok = mkToken("c"); /* does not exist */
Token newTok = mkToken("d");
sqlite3AlterRenameColumn(&p, pSrc, &oldTok, &newTok);
TEST_ASSERT_TRUE(p.nErr>0);
TEST_ASSERT_NOT_NULL(p.zErrMsg);
TEST_ASSERT_NOT_EQUAL(NULL, strstr(p.zErrMsg, "no such column"));
TEST_ASSERT_NULL(p.pVdbe);
parseCleanup(&p);
sqlite3_close(db);
}
void test_sqlite3AlterRenameColumn_success_main_db(void){
sqlite3 *db = 0;
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_exec(db,
"CREATE TABLE t1(a,b,c);", 0, 0, 0));
Parse p; parseInit(&p, db);
SrcList *pSrc = makeSrcList(db, NULL, "t1");
Token oldTok = mkToken("a");
Token newTok = mkToken("x");
sqlite3AlterRenameColumn(&p, pSrc, &oldTok, &newTok);
TEST_ASSERT_EQUAL_INT(0, p.nErr);
TEST_ASSERT_NULL(p.zErrMsg);
TEST_ASSERT_NOT_NULL(p.pVdbe);
/* sqlite3NestedParse should have added some ops */
TEST_ASSERT_TRUE(p.pVdbe->nOp > 0);
parseCleanup(&p);
sqlite3_close(db);
}
void test_sqlite3AlterRenameColumn_success_temp_db_quoted_newname(void){
sqlite3 *db = 0;
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_exec(db,
"CREATE TEMP TABLE tt(a,b);", 0, 0, 0));
Parse p; parseInit(&p, db);
/* Force lookup in temp by providing zDatabase="temp" */
SrcList *pSrc = makeSrcList(db, "temp", "tt");
Token oldTok = mkToken("b");
Token newTok = mkToken("\"x y\""); /* quoted new name */
sqlite3AlterRenameColumn(&p, pSrc, &oldTok, &newTok);
TEST_ASSERT_EQUAL_INT(0, p.nErr);
TEST_ASSERT_NULL(p.zErrMsg);
TEST_ASSERT_NOT_NULL(p.pVdbe);
TEST_ASSERT_TRUE(p.pVdbe->nOp > 0);
parseCleanup(&p);
sqlite3_close(db);
}
void test_sqlite3AlterRenameColumn_cannot_alter_system_table(void){
sqlite3 *db = 0;
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));
Parse p; parseInit(&p, db);
/* Attempt to alter the sqlite_schema/system table */
SrcList *pSrc = makeSrcList(db, NULL, "sqlite_schema");
Token oldTok = mkToken("type");
Token newTok = mkToken("xtype");
sqlite3AlterRenameColumn(&p, pSrc, &oldTok, &newTok);
TEST_ASSERT_TRUE(p.nErr>0);
TEST_ASSERT_NOT_NULL(p.zErrMsg);
TEST_ASSERT_NOT_EQUAL(NULL, strstr(p.zErrMsg, "may not be altered"));
TEST_ASSERT_NULL(p.pVdbe);
parseCleanup(&p);
sqlite3_close(db);
}
#ifndef SQLITE_OMIT_AUTHORIZATION
static int denyAuthorizer(void *p, int op,
const char *z1, const char *z2,
const char *z3, const char *z4){
UNUSED_PARAMETER(p);
UNUSED_PARAMETER(op);
UNUSED_PARAMETER(z1);
UNUSED_PARAMETER(z2);
UNUSED_PARAMETER(z3);
UNUSED_PARAMETER(z4);
return SQLITE_DENY;
}
void test_sqlite3AlterRenameColumn_authorizer_denies(void){
sqlite3 *db = 0;
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_exec(db,
"CREATE TABLE t1(a,b);", 0, 0, 0));
TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_set_authorizer(db, denyAuthorizer, 0));
Parse p; parseInit(&p, db);
SrcList *pSrc = makeSrcList(db, NULL, "t1");
Token oldTok = mkToken("a");
Token newTok = mkToken("x");
sqlite3AlterRenameColumn(&p, pSrc, &oldTok, &newTok);
/* Expect abort without generating code */
TEST_ASSERT_TRUE(p.nErr>0 || p.zErrMsg!=NULL);
TEST_ASSERT_NULL(p.pVdbe);
sqlite3_set_authorizer(db, 0, 0);
parseCleanup(&p);
sqlite3_close(db);
}
#endif
int main(void){
UNITY_BEGIN();
RUN_TEST(test_sqlite3AlterRenameColumn_no_such_table);
RUN_TEST(test_sqlite3AlterRenameColumn_view_error);
RUN_TEST(test_sqlite3AlterRenameColumn_column_not_found);
RUN_TEST(test_sqlite3AlterRenameColumn_success_main_db);
RUN_TEST(test_sqlite3AlterRenameColumn_success_temp_db_quoted_newname);
RUN_TEST(test_sqlite3AlterRenameColumn_cannot_alter_system_table);
#ifndef SQLITE_OMIT_AUTHORIZATION
RUN_TEST(test_sqlite3AlterRenameColumn_authorizer_denies);
#endif
return UNITY_END();
}