Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_alter_sqlite3AlterBeginAddColumn.c210 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Globals for tests */7static sqlite3 *gDb = NULL;8 9/* Unity setup/teardown */10void setUp(void) {11  int rc = sqlite3_open(":memory:", &gDb);12  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);13  TEST_ASSERT_NOT_NULL(gDb);14}15 16void tearDown(void) {17  if (gDb) {18    sqlite3_close(gDb);19    gDb = NULL;20  }21}22 23/* Helper: create a SrcList with a single table name */24static SrcList* makeSrcList(const char *zName){25  Token t;26  memset(&t, 0, sizeof(t));27  t.z = zName;28  t.n = (int)strlen(zName);29  return sqlite3SrcListAppend(gDb, 0, &t, 0);30}31 32/* Helper: initialize a Parse object for our db */33static void initParse(Parse *p){34  memset(p, 0, sizeof(*p));35  p->db = gDb;36}37 38/* Test: successful copy for an ordinary table */39void test_sqlite3AlterBeginAddColumn_success_creates_partial_copy(void) {40  char *err = 0;41  int rc;42 43  /* Create a normal table with multiple columns and defaults */44  rc = sqlite3_exec(gDb,45    "CREATE TABLE t(a INTEGER DEFAULT 1, b TEXT, c REAL DEFAULT 3.14);",46    0, 0, &err);47  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, err ? err : "create failed");48  if (err) sqlite3_free(err), err = 0;49 50  /* Find original table metadata */51  Table *pOrig = sqlite3FindTable(gDb, "t", "main");52  TEST_ASSERT_NOT_NULL(pOrig);53  TEST_ASSERT_TRUE(pOrig->nCol > 0);54 55  /* Prepare SrcList and Parse */56  SrcList *pSrc = makeSrcList("t");57  TEST_ASSERT_NOT_NULL(pSrc);58 59  Parse parse;60  initParse(&parse);61  TEST_ASSERT_NULL(parse.pNewTable);62 63  /* Call the target function while holding btree mutexes */64  sqlite3BtreeEnterAll(gDb);65  sqlite3AlterBeginAddColumn(&parse, pSrc);66  sqlite3BtreeLeaveAll(gDb);67 68  /* Verify success: no error and pNewTable populated */69  TEST_ASSERT_EQUAL_INT(0, parse.nErr);70  TEST_ASSERT_NOT_NULL(parse.pNewTable);71 72  Table *pNew = parse.pNewTable;73 74  /* Name must be prefixed as "sqlite_altertab_t" */75  TEST_ASSERT_NOT_NULL(pNew->zName);76  TEST_ASSERT_EQUAL_STRING("sqlite_altertab_t", pNew->zName);77 78  /* Column count should match */79  TEST_ASSERT_EQUAL_INT(pOrig->nCol, pNew->nCol);80 81  /* Column names duplicated and hashes computed */82  for(int i=0; i<pNew->nCol; i++){83    Column *cOrig = &pOrig->aCol[i];84    Column *cNew  = &pNew->aCol[i];85    TEST_ASSERT_NOT_NULL(cNew->zCnName);86    TEST_ASSERT_NOT_NULL(cOrig->zCnName);87    /* Ensure duplicated pointer (not aliasing original) and same content */88    TEST_ASSERT(cNew->zCnName != cOrig->zCnName);89    TEST_ASSERT_EQUAL_STRING(cOrig->zCnName, cNew->zCnName);90    /* Ensure hash is set to case-insensitive hash of the name */91    TEST_ASSERT_EQUAL_INT(sqlite3StrIHash(cNew->zCnName), cNew->hName);92  }93 94  /* Schema and addColOffset should match original */95  TEST_ASSERT(pNew->pSchema == pOrig->pSchema);96  TEST_ASSERT_TRUE(pNew->u.tab.addColOffset > 0);97  TEST_ASSERT_EQUAL_INT(pOrig->u.tab.addColOffset, pNew->u.tab.addColOffset);98 99  /* Default expression list should be duplicated if present on original */100  if( pOrig->u.tab.pDfltList ){101    TEST_ASSERT_NOT_NULL(pNew->u.tab.pDfltList);102    TEST_ASSERT_NOT_NULL(pOrig->u.tab.pDfltList);103    TEST_ASSERT(pNew->u.tab.pDfltList != pOrig->u.tab.pDfltList);104    TEST_ASSERT_EQUAL_INT(pOrig->u.tab.pDfltList->nExpr,105                          pNew->u.tab.pDfltList->nExpr);106  }107 108  /* New table refcount should be 1 */109  TEST_ASSERT_EQUAL_INT(1, pNew->nTabRef);110 111  /* Cleanup: delete the allocated table copy */112  sqlite3DeleteTable(gDb, pNew);113  parse.pNewTable = 0;114}115 116/* Test: attempting to alter a view should raise an error */117void test_sqlite3AlterBeginAddColumn_on_view_sets_error(void) {118  char *err = 0;119  int rc;120 121  rc = sqlite3_exec(gDb, "CREATE VIEW v AS SELECT 1 AS x;", 0, 0, &err);122  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, err ? err : "create view failed");123  if (err) sqlite3_free(err), err = 0;124 125  SrcList *pSrc = makeSrcList("v");126  TEST_ASSERT_NOT_NULL(pSrc);127 128  Parse parse;129  initParse(&parse);130 131  sqlite3BtreeEnterAll(gDb);132  sqlite3AlterBeginAddColumn(&parse, pSrc);133  sqlite3BtreeLeaveAll(gDb);134 135  TEST_ASSERT_TRUE(parse.nErr > 0);136  TEST_ASSERT_NULL(parse.pNewTable);137  TEST_ASSERT_NOT_NULL(parse.zErrMsg);138  TEST_ASSERT_NOT_NULL(strstr(parse.zErrMsg, "Cannot add a column to a view"));139 140  sqlite3DbFree(gDb, parse.zErrMsg);141  parse.zErrMsg = 0;142}143 144/* Test: attempting to alter a system table (sqlite_sequence) should raise an error */145void test_sqlite3AlterBeginAddColumn_on_system_table_sets_error(void) {146  char *err = 0;147  int rc;148 149  /* Create an AUTOINCREMENT table to ensure sqlite_sequence exists */150  rc = sqlite3_exec(gDb,151    "CREATE TABLE at(id INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);",152    0, 0, &err);153  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, err ? err : "create autoinc failed");154  if (err) sqlite3_free(err), err = 0;155 156  /* Ensure sqlite_sequence exists by inserting a row (usually created at table create, but this is safe) */157  rc = sqlite3_exec(gDb, "INSERT INTO at(b) VALUES('x');", 0, 0, &err);158  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, err ? err : "insert failed");159  if (err) sqlite3_free(err), err = 0;160 161  /* Now attempt to alter sqlite_sequence */162  SrcList *pSrc = makeSrcList("sqlite_sequence");163  TEST_ASSERT_NOT_NULL(pSrc);164 165  Parse parse;166  initParse(&parse);167 168  sqlite3BtreeEnterAll(gDb);169  sqlite3AlterBeginAddColumn(&parse, pSrc);170  sqlite3BtreeLeaveAll(gDb);171 172  TEST_ASSERT_TRUE(parse.nErr > 0);173  TEST_ASSERT_NULL(parse.pNewTable);174  TEST_ASSERT_NOT_NULL(parse.zErrMsg);175  TEST_ASSERT_NOT_NULL(strstr(parse.zErrMsg, "table sqlite_sequence may not be altered"));176 177  sqlite3DbFree(gDb, parse.zErrMsg);178  parse.zErrMsg = 0;179}180 181/* Test: table not found should set an error and no pNewTable */182void test_sqlite3AlterBeginAddColumn_table_not_found_sets_error(void) {183  SrcList *pSrc = makeSrcList("no_such_table_123");184  TEST_ASSERT_NOT_NULL(pSrc);185 186  Parse parse;187  initParse(&parse);188 189  sqlite3BtreeEnterAll(gDb);190  sqlite3AlterBeginAddColumn(&parse, pSrc);191  sqlite3BtreeLeaveAll(gDb);192 193  TEST_ASSERT_TRUE(parse.nErr > 0);194  TEST_ASSERT_NULL(parse.pNewTable);195  TEST_ASSERT_NOT_NULL(parse.zErrMsg);196  TEST_ASSERT_NOT_NULL(strstr(parse.zErrMsg, "no such table"));197 198  sqlite3DbFree(gDb, parse.zErrMsg);199  parse.zErrMsg = 0;200}201 202/* Main runner */203int main(void) {204  UNITY_BEGIN();205  RUN_TEST(test_sqlite3AlterBeginAddColumn_success_creates_partial_copy);206  RUN_TEST(test_sqlite3AlterBeginAddColumn_on_view_sets_error);207  RUN_TEST(test_sqlite3AlterBeginAddColumn_on_system_table_sets_error);208  RUN_TEST(test_sqlite3AlterBeginAddColumn_table_not_found_sets_error);209  return UNITY_END();210}