Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_build_sqlite3CreateView.c256 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Helper: create a simple Select AST for "SELECT 1" (or other constant) */7static Select* makeSelectConst(Parse *pParse, const char *zVal){8  sqlite3 *db = pParse->db;9  Token t;10  t.z = zVal;11  t.n = (int)strlen(zVal);12  Expr *pExpr = sqlite3ExprAlloc(db, TK_INTEGER, &t, 0);13  ExprList *pList = sqlite3ExprListAppend(pParse, 0, pExpr);14  return sqlite3SelectNew(pParse, pList, 0, 0, 0, 0, 0, 0, 0, 0);15}16 17/* Helper: create ExprList for column names like (c1, c2, ...) with 1 entry */18static ExprList* makeOneColName(Parse *pParse, const char *zName){19  sqlite3 *db = pParse->db;20  Token t;21  t.z = zName;22  t.n = (int)strlen(zName);23  Expr *pId = sqlite3ExprAlloc(db, TK_ID, &t, 0);24  return sqlite3ExprListAppend(pParse, 0, pId);25}26 27/* Helper: cleanup resources created on Parse during tests */28static void cleanupParse(Parse *p){29  if( p->pVdbe ){30    sqlite3VdbeDelete(p->pVdbe);31    p->pVdbe = 0;32  }33  if( p->pNewTable ){34    sqlite3DeleteTable(p->db, p->pNewTable);35    p->pNewTable = 0;36  }37  if( p->zErrMsg ){38    sqlite3DbFree(p->db, p->zErrMsg);39    p->zErrMsg = 0;40  }41}42 43void setUp(void) {44  /* Setup code here, or leave empty */45}46 47void tearDown(void) {48  /* Cleanup code here, or leave empty */49}50 51/* Test: Basic successful CREATE VIEW */52void test_sqlite3CreateView_basic_success(void){53  sqlite3 *db = 0;54  TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));55 56  Parse p; memset(&p, 0, sizeof(p));57  p.db = db;58  p.isCreate = 1; /* Required by sqlite3StartTable path */59 60  const char *zSql = "CREATE VIEW v_basic AS SELECT 1";61  Token tBegin, tName1, tName2, tLast;62  tBegin.z = zSql; tBegin.n = 6; /* "CREATE" */63  /* Unqualified name: pName1 = "v_basic", pName2 empty */64  const char *zName = strstr(zSql, "v_basic");65  TEST_ASSERT_NOT_NULL(zName);66  tName1.z = zName; tName1.n = (int)strlen("v_basic");67  tName2.z = zSql; tName2.n = 0; /* empty */68  /* Last token is the literal 1 */69  const char *zOne = strrchr(zSql, '1');70  TEST_ASSERT_NOT_NULL(zOne);71  tLast.z = zOne; tLast.n = 1;72  p.sLastToken = tLast;73 74  ExprList *pCNames = makeOneColName(&p, "c1");75  Select *pSel = makeSelectConst(&p, "1");76 77  sqlite3CreateView(&p, &tBegin, &tName1, &tName2, pCNames, pSel, 0, 0);78 79  TEST_ASSERT_EQUAL_INT(0, p.nErr);80  TEST_ASSERT_NOT_NULL(p.pNewTable);81  TEST_ASSERT_EQUAL_INT(TABTYP_VIEW, p.pNewTable->eTabType);82  TEST_ASSERT_NOT_NULL(p.pNewTable->u.view.pSelect);83  TEST_ASSERT_NOT_NULL(p.pNewTable->pCheck); /* stores view column name list copy */84  TEST_ASSERT_EQUAL_INT(1, p.pNewTable->pCheck->nExpr);85 86  /* Check rowid visibility flag behavior */87#ifdef SQLITE_ALLOW_ROWID_IN_VIEW88  /* Bit presence should match runtime config */89  int hasNoVisible = (p.pNewTable->tabFlags & TF_NoVisibleRowid)!=0;90  int cfgRequires = (sqlite3Config.mNoVisibleRowid & TF_NoVisibleRowid)!=0;91  TEST_ASSERT_EQUAL_INT(cfgRequires, hasNoVisible);92#else93  TEST_ASSERT_TRUE((p.pNewTable->tabFlags & TF_NoVisibleRowid)!=0);94#endif95 96  cleanupParse(&p);97  sqlite3_close(db);98}99 100/* Test: parameters are not allowed in views (nVar>0) */101void test_sqlite3CreateView_error_parameters_not_allowed(void){102  sqlite3 *db = 0;103  TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));104 105  Parse p; memset(&p, 0, sizeof(p));106  p.db = db;107  p.isCreate = 1;108  p.nVar = 1; /* triggers error */109 110  const char *zSql = "CREATE VIEW v_params AS SELECT 1";111  Token tBegin, tName1, tName2, tLast;112  tBegin.z = zSql; tBegin.n = 6;113  const char *zName = strstr(zSql, "v_params");114  TEST_ASSERT_NOT_NULL(zName);115  tName1.z = zName; tName1.n = (int)strlen("v_params");116  tName2.z = zSql; tName2.n = 0;117  const char *zOne = strrchr(zSql, '1');118  TEST_ASSERT_NOT_NULL(zOne);119  tLast.z = zOne; tLast.n = 1;120  p.sLastToken = tLast;121 122  ExprList *pCNames = makeOneColName(&p, "c1");123  Select *pSel = makeSelectConst(&p, "1");124 125  sqlite3CreateView(&p, &tBegin, &tName1, &tName2, pCNames, pSel, 0, 0);126 127  TEST_ASSERT_TRUE(p.nErr>0);128  TEST_ASSERT_NOT_NULL(p.zErrMsg);129  TEST_ASSERT_NOT_NULL(strstr(p.zErrMsg, "parameters are not allowed in views"));130  TEST_ASSERT_NULL(p.pNewTable);131 132  cleanupParse(&p);133  sqlite3_close(db);134}135 136/* Test: unknown database qualifier (two-part name with unknown db) */137void test_sqlite3CreateView_unknown_database(void){138  sqlite3 *db = 0;139  TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));140 141  Parse p; memset(&p, 0, sizeof(p));142  p.db = db;143  p.isCreate = 1;144 145  const char *zSql = "CREATE VIEW nosuchdb.v AS SELECT 1";146  Token tBegin, tName1, tName2, tLast;147  tBegin.z = zSql; tBegin.n = 6;148  const char *zDb = strstr(zSql, "nosuchdb");149  const char *zTbl = strstr(zSql, ".v");150  TEST_ASSERT_NOT_NULL(zDb);151  TEST_ASSERT_NOT_NULL(zTbl);152  tName1.z = zDb; tName1.n = (int)strlen("nosuchdb");153  tName2.z = zTbl+1; tName2.n = 1; /* "v" */154  const char *zOne = strrchr(zSql, '1');155  TEST_ASSERT_NOT_NULL(zOne);156  tLast.z = zOne; tLast.n = 1;157  p.sLastToken = tLast;158 159  ExprList *pCNames = makeOneColName(&p, "c1");160  Select *pSel = makeSelectConst(&p, "1");161 162  sqlite3CreateView(&p, &tBegin, &tName1, &tName2, pCNames, pSel, 0, 0);163 164  TEST_ASSERT_TRUE(p.nErr>0);165  TEST_ASSERT_NOT_NULL(p.zErrMsg);166  TEST_ASSERT_NOT_NULL(strstr(p.zErrMsg, "unknown database"));167  TEST_ASSERT_NULL(p.pNewTable);168 169  cleanupParse(&p);170  sqlite3_close(db);171}172 173/* Test: TEMP view name must be unqualified (isTemp && qualified && db!="temp") */174void test_sqlite3CreateView_temp_must_be_unqualified(void){175  sqlite3 *db = 0;176  TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));177 178  Parse p; memset(&p, 0, sizeof(p));179  p.db = db;180  p.isCreate = 1;181 182  const char *zSql = "CREATE TEMP VIEW main.vt AS SELECT 1";183  Token tBegin, tName1, tName2, tLast;184  tBegin.z = zSql; tBegin.n = 6;185  const char *zDb = strstr(zSql, "main");186  const char *zTblDot = strstr(zSql, "main.vt");187  TEST_ASSERT_NOT_NULL(zDb);188  TEST_ASSERT_NOT_NULL(zTblDot);189  tName1.z = zDb; tName1.n = (int)strlen("main");190  tName2.z = zTblDot + 5; tName2.n = (int)strlen("vt"); /* after 'main.' */191  const char *zOne = strrchr(zSql, '1');192  TEST_ASSERT_NOT_NULL(zOne);193  tLast.z = zOne; tLast.n = 1;194  p.sLastToken = tLast;195 196  ExprList *pCNames = makeOneColName(&p, "c1");197  Select *pSel = makeSelectConst(&p, "1");198 199  sqlite3CreateView(&p, &tBegin, &tName1, &tName2, pCNames, pSel, 1 /*isTemp*/, 0);200 201  TEST_ASSERT_TRUE(p.nErr>0);202  TEST_ASSERT_NOT_NULL(p.zErrMsg);203  TEST_ASSERT_NOT_NULL(strstr(p.zErrMsg, "temporary table name must be unqualified"));204  TEST_ASSERT_NULL(p.pNewTable);205 206  cleanupParse(&p);207  sqlite3_close(db);208}209 210/* Test: noErr=true when view already exists should not raise an error */211void test_sqlite3CreateView_noErr_when_exists(void){212  sqlite3 *db = 0;213  TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));214 215  /* Pre-create the view using the public API to populate schema */216  TEST_ASSERT_EQUAL(SQLITE_OK,217    sqlite3_exec(db, "CREATE VIEW v_exists AS SELECT 1", 0, 0, 0));218 219  Parse p; memset(&p, 0, sizeof(p));220  p.db = db;221  p.isCreate = 1;222 223  const char *zSql = "CREATE VIEW v_exists AS SELECT 1";224  Token tBegin, tName1, tName2, tLast;225  tBegin.z = zSql; tBegin.n = 6;226  const char *zName = strstr(zSql, "v_exists");227  TEST_ASSERT_NOT_NULL(zName);228  tName1.z = zName; tName1.n = (int)strlen("v_exists");229  tName2.z = zSql; tName2.n = 0;230  const char *zOne = strrchr(zSql, '1');231  TEST_ASSERT_NOT_NULL(zOne);232  tLast.z = zOne; tLast.n = 1;233  p.sLastToken = tLast;234 235  ExprList *pCNames = makeOneColName(&p, "c1");236  Select *pSel = makeSelectConst(&p, "1");237 238  sqlite3CreateView(&p, &tBegin, &tName1, &tName2, pCNames, pSel, 0, 1 /*noErr*/);239 240  /* Should not report an error, and should not create a new table object */241  TEST_ASSERT_EQUAL_INT(0, p.nErr);242  TEST_ASSERT_NULL(p.pNewTable);243 244  cleanupParse(&p);245  sqlite3_close(db);246}247 248int main(void) {249  UNITY_BEGIN();250  RUN_TEST(test_sqlite3CreateView_basic_success);251  RUN_TEST(test_sqlite3CreateView_error_parameters_not_allowed);252  RUN_TEST(test_sqlite3CreateView_unknown_database);253  RUN_TEST(test_sqlite3CreateView_temp_must_be_unqualified);254  RUN_TEST(test_sqlite3CreateView_noErr_when_exists);255  return UNITY_END();256}