Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_insert_sqlite3Insert.c158 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdio.h>5 6static sqlite3 *gDb = NULL;7 8static void init_parse(sqlite3 *db, Parse *p){9  memset(p, 0, sizeof(*p));10  p->db = db;11  db->pParse = p; /* sqlite3Insert asserts this */12}13 14static void cleanup_parse(Parse *p){15  if( p && p->pVdbe ){16    sqlite3VdbeDelete(p->pVdbe);17    p->pVdbe = NULL;18  }19  if( p && p->db ){20    p->db->pParse = NULL;21  }22}23 24static SrcList* srcListFromName(sqlite3 *db, const char *zName){25  Token t;26  t.z = zName;27  t.n = (int)strlen(zName);28  return sqlite3SrcListAppend(db, NULL, &t, NULL);29}30 31static IdList* idListFromNames(sqlite3 *db, const char *const *az, int n){32  IdList *p = NULL;33  for(int i=0;i<n;i++){34    Token t;35    t.z = az[i];36    t.n = (int)strlen(az[i]);37    p = sqlite3IdListAppend(db, p, &t);38  }39  return p;40}41 42static int vdbeHasOpcode(Vdbe *v, int opcode){43  if( v==NULL ) return 0;44  int n = sqlite3VdbeCurrentAddr(v);45  for(int i=0; i<n; i++){46    VdbeOp *pOp = sqlite3VdbeGetOp(v, i);47    if( pOp && pOp->opcode==opcode ) return 1;48  }49  return 0;50}51 52void setUp(void) {53  int rc = sqlite3_open(":memory:", &gDb);54  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);55}56 57void tearDown(void) {58  if( gDb ){59    sqlite3_close(gDb);60    gDb = NULL;61  }62}63 64/* Test 1: Successful DEFAULT VALUES insert into a simple rowid table. */65void test_sqlite3Insert_default_values_generates_insert_ops(void){66  int rc;67  char *zErr = 0;68  rc = sqlite3_exec(gDb, "CREATE TABLE t1(a INTEGER, b TEXT);", 0, 0, &zErr);69  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, zErr?zErr:"exec failed");70  if(zErr) sqlite3_free(zErr);71 72  Parse p; init_parse(gDb, &p);73  SrcList *pTabList = srcListFromName(gDb, "t1");74  /* DEFAULT VALUES: pSelect=NULL, pColumn=NULL, onError=OE_Default */75  sqlite3Insert(&p, pTabList, NULL, NULL, OE_Default, NULL);76 77  /* No parse errors expected */78  TEST_ASSERT_EQUAL_INT(0, p.nErr);79  TEST_ASSERT_NOT_NULL(p.pVdbe);80 81  /* Verify essential VDBE opcodes for an insert path */82  TEST_ASSERT_TRUE_MESSAGE(vdbeHasOpcode(p.pVdbe, OP_OpenWrite), "Expected OP_OpenWrite");83  TEST_ASSERT_TRUE_MESSAGE(vdbeHasOpcode(p.pVdbe, OP_MakeRecord), "Expected OP_MakeRecord");84  TEST_ASSERT_TRUE_MESSAGE(vdbeHasOpcode(p.pVdbe, OP_Insert), "Expected OP_Insert");85 86  cleanup_parse(&p);87}88 89/* Test 2: Error when IDLIST contains a non-existent column name. */90void test_sqlite3Insert_nonexistent_column_sets_error(void){91  int rc; char *zErr = 0;92  rc = sqlite3_exec(gDb, "CREATE TABLE t1(a, b);", 0, 0, &zErr);93  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, zErr?zErr:"exec failed");94  if(zErr) sqlite3_free(zErr);95 96  Parse p; init_parse(gDb, &p);97  SrcList *pTabList = srcListFromName(gDb, "t1");98  const char *cols[] = {"doesnotexist"};99  IdList *pColumn = idListFromNames(gDb, cols, 1);100 101  sqlite3Insert(&p, pTabList, NULL, pColumn, OE_Default, NULL);102 103  TEST_ASSERT_TRUE_MESSAGE(p.nErr>0, "Expected parse error when column does not exist");104  TEST_ASSERT_EQUAL_INT(1, p.checkSchema); /* sqlite3Insert sets this on this error */105 106  cleanup_parse(&p);107}108 109/* Test 3: Mismatch between provided column list and number of values. */110void test_sqlite3Insert_column_value_count_mismatch_sets_error(void){111  int rc; char *zErr = 0;112  rc = sqlite3_exec(gDb, "CREATE TABLE t1(a, b);", 0, 0, &zErr);113  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, zErr?zErr:"exec failed");114  if(zErr) sqlite3_free(zErr);115 116  Parse p; init_parse(gDb, &p);117  SrcList *pTabList = srcListFromName(gDb, "t1");118  /* Provide IDLIST with one valid column but no values (DEFAULT VALUES scenario).119     This should trigger the mismatch check: nColumn(=0) != pColumn->nId(=1). */120  const char *cols[] = {"a"};121  IdList *pColumn = idListFromNames(gDb, cols, 1);122 123  sqlite3Insert(&p, pTabList, NULL, pColumn, OE_Default, NULL);124 125  TEST_ASSERT_TRUE_MESSAGE(p.nErr>0, "Expected error due to column/value count mismatch");126 127  cleanup_parse(&p);128}129 130/* Test 4: Attempt to insert into a view should set an error (read-only). */131void test_sqlite3Insert_into_view_sets_error(void){132  int rc; char *zErr = 0;133  rc = sqlite3_exec(gDb,134    "CREATE TABLE t1(a, b);"135    "CREATE VIEW v1 AS SELECT a, b FROM t1;",136    0, 0, &zErr137  );138  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, zErr?zErr:"exec failed");139  if(zErr) sqlite3_free(zErr);140 141  Parse p; init_parse(gDb, &p);142  SrcList *pTabList = srcListFromName(gDb, "v1");143 144  sqlite3Insert(&p, pTabList, NULL, NULL, OE_Default, NULL);145 146  TEST_ASSERT_TRUE_MESSAGE(p.nErr>0, "Expected error inserting into a view");147 148  cleanup_parse(&p);149}150 151int main(void){152  UNITY_BEGIN();153  RUN_TEST(test_sqlite3Insert_default_values_generates_insert_ops);154  RUN_TEST(test_sqlite3Insert_nonexistent_column_sets_error);155  RUN_TEST(test_sqlite3Insert_column_value_count_mismatch_sets_error);156  RUN_TEST(test_sqlite3Insert_into_view_sets_error);157  return UNITY_END();158}