sqlite / tests /tests_alter_sqlite3AlterRenameTable.c
AryaWu's picture
Upload folder using huggingface_hub
7510827 verified
#include "sqliteInt.h"
#include "unity.h"
#include <stdlib.h>
#include <string.h>
/* Global DB handle for each test */
static sqlite3 *gDb = NULL;
/* Helper: execute SQL and assert success */
static void execSQL(const char *zSql){
char *zErr = 0;
int rc = sqlite3_exec(gDb, zSql, 0, 0, &zErr);
if( rc!=SQLITE_OK ){
/* Use Unity assertion here (stdout not redirected) */
TEST_FAIL_MESSAGE(zErr ? zErr : "sqlite3_exec error");
}
sqlite3_free(zErr);
}
/* Helper: make a Token from a C-string */
static Token makeToken(const char *z){
Token t;
t.z = z;
t.n = (int)strlen(z);
t.dyn = 0;
t.enc = 0;
t.term = 0;
return t;
}
/* Helper: build a SrcList with one entry, optionally with a database/schema name.
** The SrcList is allocated using SQLite allocators and will be owned and freed
** by sqlite3AlterRenameTable().
*/
static SrcList* mkSrcList(sqlite3 *db, const char *zDb, const char *zTab){
Token tTab = makeToken(zTab);
if( zDb ){
Token tDb = makeToken(zDb);
return sqlite3SrcListAppend(db, 0, &tTab, &tDb);
}else{
return sqlite3SrcListAppend(db, 0, &tTab, 0);
}
}
void setUp(void) {
int rc = sqlite3_initialize();
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
rc = sqlite3_open(":memory:", &gDb);
TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
}
void tearDown(void) {
if( gDb ){
sqlite3_close(gDb);
gDb = NULL;
}
}
/* Success case: rename a regular table to a new unique name.
** Expect: no parse error, VDBE generated (pVdbe != NULL).
*/
void test_sqlite3AlterRenameTable_success_generates_vdbe(void){
execSQL("CREATE TABLE t1(a)");
Parse parse;
memset(&parse, 0, sizeof(parse));
parse.db = gDb;
SrcList *pSrc = mkSrcList(gDb, "main", "t1");
Token newName = makeToken("t2");
sqlite3BtreeEnterAll(gDb);
sqlite3AlterRenameTable(&parse, pSrc, &newName);
sqlite3BtreeLeaveAll(gDb);
TEST_ASSERT_EQUAL_INT(0, parse.nErr);
TEST_ASSERT_NULL(parse.zErrMsg);
TEST_ASSERT_NOT_NULL(parse.pVdbe);
if( parse.pVdbe ) sqlite3VdbeDelete(parse.pVdbe);
}
/* Error: rename to a name that already exists as another table */
void test_sqlite3AlterRenameTable_error_duplicate_name_table(void){
execSQL("CREATE TABLE t1(a)");
execSQL("CREATE TABLE t2(b)");
Parse parse;
memset(&parse, 0, sizeof(parse));
parse.db = gDb;
SrcList *pSrc = mkSrcList(gDb, "main", "t1");
Token newName = makeToken("t2");
sqlite3BtreeEnterAll(gDb);
sqlite3AlterRenameTable(&parse, pSrc, &newName);
sqlite3BtreeLeaveAll(gDb);
TEST_ASSERT_GREATER_THAN_INT(0, parse.nErr);
TEST_ASSERT_NOT_NULL(parse.zErrMsg);
TEST_ASSERT_NULL(parse.pVdbe);
if( parse.zErrMsg ) sqlite3DbFree(gDb, parse.zErrMsg);
}
/* Error: rename to a name that already exists as an index */
void test_sqlite3AlterRenameTable_error_duplicate_name_index(void){
execSQL("CREATE TABLE t1(a)");
execSQL("CREATE INDEX t2 ON t1(a)");
Parse parse;
memset(&parse, 0, sizeof(parse));
parse.db = gDb;
SrcList *pSrc = mkSrcList(gDb, "main", "t1");
Token newName = makeToken("t2");
sqlite3BtreeEnterAll(gDb);
sqlite3AlterRenameTable(&parse, pSrc, &newName);
sqlite3BtreeLeaveAll(gDb);
TEST_ASSERT_GREATER_THAN_INT(0, parse.nErr);
TEST_ASSERT_NOT_NULL(parse.zErrMsg);
TEST_ASSERT_NULL(parse.pVdbe);
if( parse.zErrMsg ) sqlite3DbFree(gDb, parse.zErrMsg);
}
/* Error: attempt to alter a view */
void test_sqlite3AlterRenameTable_error_view_not_alterable(void){
execSQL("CREATE TABLE t1(a)");
execSQL("CREATE VIEW v1 AS SELECT a FROM t1");
Parse parse;
memset(&parse, 0, sizeof(parse));
parse.db = gDb;
SrcList *pSrc = mkSrcList(gDb, "main", "v1");
Token newName = makeToken("v2");
sqlite3BtreeEnterAll(gDb);
sqlite3AlterRenameTable(&parse, pSrc, &newName);
sqlite3BtreeLeaveAll(gDb);
TEST_ASSERT_GREATER_THAN_INT(0, parse.nErr);
TEST_ASSERT_NOT_NULL(parse.zErrMsg);
TEST_ASSERT_NULL(parse.pVdbe);
if( parse.zErrMsg ) sqlite3DbFree(gDb, parse.zErrMsg);
}
/* Error: attempt to alter a system table (sqlite_sequence) */
void test_sqlite3AlterRenameTable_error_system_table_not_alterable(void){
/* Ensure sqlite_sequence exists by creating AUTOINCREMENT table and inserting */
execSQL("CREATE TABLE tauto(id INTEGER PRIMARY KEY AUTOINCREMENT, x)");
execSQL("INSERT INTO tauto(x) VALUES (1)");
/* Now attempt to rename sqlite_sequence itself */
Parse parse;
memset(&parse, 0, sizeof(parse));
parse.db = gDb;
SrcList *pSrc = mkSrcList(gDb, "main", "sqlite_sequence");
Token newName = makeToken("seq2");
sqlite3BtreeEnterAll(gDb);
sqlite3AlterRenameTable(&parse, pSrc, &newName);
sqlite3BtreeLeaveAll(gDb);
TEST_ASSERT_GREATER_THAN_INT(0, parse.nErr);
TEST_ASSERT_NOT_NULL(parse.zErrMsg);
TEST_ASSERT_NULL(parse.pVdbe);
if( parse.zErrMsg ) sqlite3DbFree(gDb, parse.zErrMsg);
}
/* Error: rename to a reserved/internal name (starts with sqlite_) */
void test_sqlite3AlterRenameTable_error_reserved_new_name(void){
execSQL("CREATE TABLE t1(a)");
Parse parse;
memset(&parse, 0, sizeof(parse));
parse.db = gDb;
SrcList *pSrc = mkSrcList(gDb, "main", "t1");
Token newName = makeToken("sqlite_stat1");
sqlite3BtreeEnterAll(gDb);
sqlite3AlterRenameTable(&parse, pSrc, &newName);
sqlite3BtreeLeaveAll(gDb);
TEST_ASSERT_GREATER_THAN_INT(0, parse.nErr);
TEST_ASSERT_NOT_NULL(parse.zErrMsg);
TEST_ASSERT_NULL(parse.pVdbe);
if( parse.zErrMsg ) sqlite3DbFree(gDb, parse.zErrMsg);
}
int main(void) {
UNITY_BEGIN();
RUN_TEST(test_sqlite3AlterRenameTable_success_generates_vdbe);
RUN_TEST(test_sqlite3AlterRenameTable_error_duplicate_name_table);
RUN_TEST(test_sqlite3AlterRenameTable_error_duplicate_name_index);
RUN_TEST(test_sqlite3AlterRenameTable_error_view_not_alterable);
RUN_TEST(test_sqlite3AlterRenameTable_error_system_table_not_alterable);
RUN_TEST(test_sqlite3AlterRenameTable_error_reserved_new_name);
return UNITY_END();
}