AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5 6/* Unity setup/teardown */7void setUp(void) {8 /* empty */9}10void tearDown(void) {11 /* empty */12}13 14/* Helper: initialize a Parse object */15static void initParse(Parse *pParse, sqlite3 *db, const char *zCons){16 memset(pParse, 0, sizeof(*pParse));17 pParse->db = db;18 if( zCons ){19 /* sLastToken.z should point to the end of constraint text buffer */20 pParse->sLastToken.z = zCons + strlen(zCons);21 pParse->sLastToken.n = 0; /* not used by sqlite3AlterSetNotNull */22 }23}24 25/* Helper: create a SrcList for zDb.zTab (zDb may be NULL for "main") */26static SrcList* makeSrcList(sqlite3 *db, const char *zDb, const char *zTab){27 SrcList *p = 0;28 Token tTab, tDb;29 tTab.z = zTab;30 tTab.n = (int)strlen(zTab);31 if( zDb ){32 tDb.z = zDb;33 tDb.n = (int)strlen(zDb);34 p = sqlite3SrcListAppend(db, 0, &tTab, &tDb);35 }else{36 p = sqlite3SrcListAppend(db, 0, &tTab, 0);37 }38 return p;39}40 41/* Helper: free error message in Parse */42static void freeParseError(sqlite3 *db, Parse *pParse){43 if( pParse->zErrMsg ){44 sqlite3DbFree(db, pParse->zErrMsg);45 pParse->zErrMsg = 0;46 }47}48 49/* Test: table does not exist */50static void test_sqlite3AlterSetNotNull_table_not_found(void){51 sqlite3 *db = 0;52 int rc = sqlite3_open(":memory:", &db);53 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);54 55 /* Prepare Parse and inputs */56 const char *zCons = "NOT NULL -- trailing comment";57 Parse sParse;58 initParse(&sParse, db, zCons);59 60 SrcList *pSrc = makeSrcList(db, 0, "nosuchtable");61 TEST_ASSERT_NOT_NULL(pSrc);62 Token colTok;63 colTok.z = "a";64 colTok.n = 1;65 Token firstTok;66 firstTok.z = zCons;67 firstTok.n = 3; /* "NOT" */68 69 /* Call target */70 sqlite3AlterSetNotNull(&sParse, pSrc, &colTok, &firstTok);71 72 /* Validate: error reported, and no vdbe created */73 TEST_ASSERT_TRUE(sParse.nErr > 0);74 TEST_ASSERT_NOT_NULL(sParse.zErrMsg);75 TEST_ASSERT_NULL(sParse.pVdbe);76 77 /* Cleanup */78 freeParseError(db, &sParse);79 sqlite3SrcListDelete(db, pSrc);80 sqlite3_close(db);81}82 83/* Test: table exists, column does not */84static void test_sqlite3AlterSetNotNull_column_not_found(void){85 sqlite3 *db = 0;86 int rc = sqlite3_open(":memory:", &db);87 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);88 89 rc = sqlite3_exec(db, "CREATE TABLE t(a, b);", 0, 0, 0);90 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);91 92 const char *zCons = "NOT NULL -- trim me";93 Parse sParse;94 initParse(&sParse, db, zCons);95 96 SrcList *pSrc = makeSrcList(db, 0, "t");97 TEST_ASSERT_NOT_NULL(pSrc);98 Token colTok;99 colTok.z = "c"; /* non-existent column */100 colTok.n = 1;101 Token firstTok;102 firstTok.z = zCons;103 firstTok.n = 3;104 105 sqlite3AlterSetNotNull(&sParse, pSrc, &colTok, &firstTok);106 107 /* Expect an error: "no such column" and no VDBE */108 TEST_ASSERT_TRUE(sParse.nErr > 0);109 TEST_ASSERT_NOT_NULL(sParse.zErrMsg);110 if( sParse.zErrMsg ){111 TEST_ASSERT_NOT_NULL(strstr(sParse.zErrMsg, "no such column"));112 }113 TEST_ASSERT_NULL(sParse.pVdbe);114 115 /* Cleanup */116 freeParseError(db, &sParse);117 sqlite3SrcListDelete(db, pSrc);118 sqlite3_close(db);119}120 121/* Test: success path - table and column exist, VDBE program is generated */122static void test_sqlite3AlterSetNotNull_success_creates_vdbe_program(void){123 sqlite3 *db = 0;124 int rc = sqlite3_open(":memory:", &db);125 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);126 127 rc = sqlite3_exec(db, "CREATE TABLE t(a, b);", 0, 0, 0);128 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);129 130 rc = sqlite3_exec(db, "INSERT INTO t(a,b) VALUES(1,2),(3,4);", 0, 0, 0);131 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);132 133 const char *zCons = "NOT NULL -- ensure trimming and comment handling";134 Parse sParse;135 initParse(&sParse, db, zCons);136 137 SrcList *pSrc = makeSrcList(db, 0, "t");138 TEST_ASSERT_NOT_NULL(pSrc);139 140 Token colTok;141 colTok.z = "a";142 colTok.n = 1;143 144 Token firstTok;145 firstTok.z = zCons;146 firstTok.n = 3; /* "NOT" */147 148 sqlite3AlterSetNotNull(&sParse, pSrc, &colTok, &firstTok);149 150 /* No parse error expected, and a VDBE should have been created */151 TEST_ASSERT_EQUAL_INT(0, sParse.nErr);152 TEST_ASSERT_NULL(sParse.zErrMsg);153 TEST_ASSERT_NOT_NULL(sParse.pVdbe);154 155 /* The VDBE should have at least one opcode generated by sqlite3NestedParse */156 if( sParse.pVdbe ){157 int nOp = sqlite3VdbeCurrentAddr(sParse.pVdbe);158 TEST_ASSERT_TRUE(nOp > 0);159 }160 161 /* Cleanup */162 if( sParse.pVdbe ){163 sqlite3VdbeDelete(sParse.pVdbe);164 sParse.pVdbe = 0;165 }166 sqlite3SrcListDelete(db, pSrc);167 sqlite3_close(db);168}169 170/* main */171int main(void){172 UNITY_BEGIN();173 RUN_TEST(test_sqlite3AlterSetNotNull_table_not_found);174 RUN_TEST(test_sqlite3AlterSetNotNull_column_not_found);175 RUN_TEST(test_sqlite3AlterSetNotNull_success_creates_vdbe_program);176 return UNITY_END();177}