Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_build_sqlite3AddCheckConstraint.c204 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Helper to get the last constraint name from pTab->pCheck */7static const char* get_last_check_name(Table *pTab){8  if( pTab==0 || pTab->pCheck==0 || pTab->pCheck->nExpr<=0 ) return NULL;9  return pTab->pCheck->a[pTab->pCheck->nExpr-1].zName;10}11 12/* Helper to get the i'th constraint name from pTab->pCheck */13static const char* get_check_name_at(Table *pTab, int i){14  if( pTab==0 || pTab->pCheck==0 ) return NULL;15  if( i<0 || i>=pTab->pCheck->nExpr ) return NULL;16  return pTab->pCheck->a[i].zName;17}18 19void setUp(void) {20  /* No global setup; each test sets up its own db/parse/table */21}22 23void tearDown(void) {24  /* No global teardown */25}26 27/* Basic test: appends a constraint and derives the name from zStart/zEnd */28void test_sqlite3AddCheckConstraint_append_and_trimmed_name(void){29  sqlite3 *db = 0;30  int rc = sqlite3_open(":memory:", &db);31  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);32  db->init.iDb = 0;33 34  Parse parse;35  memset(&parse, 0, sizeof(parse));36  parse.db = db;37  parse.isCreate = 1;38 39  Table *pTab = (Table*)sqlite3DbMallocZero(db, sizeof(Table));40  TEST_ASSERT_NOT_NULL(pTab);41  parse.pNewTable = pTab;42 43  Token t1 = { (char*)"1", 1 };44  Expr *pExpr = sqlite3Expr(db, TK_INTEGER, &t1);45  TEST_ASSERT_NOT_NULL(pExpr);46 47  const char *src = "(   a + 1   )";48  const char *zStart = src;                           /* points to '(' */49  const char *zEnd   = src + strlen(src) - 1;         /* points to ')' */50 51  sqlite3AddCheckConstraint(&parse, pExpr, zStart, zEnd);52 53  TEST_ASSERT_NOT_NULL(pTab->pCheck);54  TEST_ASSERT_EQUAL_INT(1, pTab->pCheck->nExpr);55 56  const char *zName = get_last_check_name(pTab);57  TEST_ASSERT_NOT_NULL(zName);58  TEST_ASSERT_EQUAL_STRING("a + 1", zName);59 60  /* Cleanup */61  sqlite3ExprListDelete(db, pTab->pCheck);62  sqlite3DbFree(db, pTab);63  sqlite3_close(db);64}65 66/* If a constraint name token is provided, it overrides the derived name */67void test_sqlite3AddCheckConstraint_constraintName_overrides(void){68  sqlite3 *db = 0;69  int rc = sqlite3_open(":memory:", &db);70  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);71  db->init.iDb = 0;72 73  Parse parse;74  memset(&parse, 0, sizeof(parse));75  parse.db = db;76  parse.isCreate = 1;77 78  Table *pTab = (Table*)sqlite3DbMallocZero(db, sizeof(Table));79  TEST_ASSERT_NOT_NULL(pTab);80  parse.pNewTable = pTab;81 82  Token tExpr = { (char*)"1", 1 };83  Expr *pExpr = sqlite3Expr(db, TK_INTEGER, &tExpr);84  TEST_ASSERT_NOT_NULL(pExpr);85 86  const char *src = "(x > 0)";87  const char *zStart = src;                           /* '(' */88  const char *zEnd   = src + strlen(src) - 1;         /* ')' */89 90  /* Provide a constraint name token */91  const char *nm = "my_constraint";92  Token tName = { (char*)nm, (int)strlen(nm) };93  parse.u1.cr.constraintName = tName;94 95  sqlite3AddCheckConstraint(&parse, pExpr, zStart, zEnd);96 97  TEST_ASSERT_NOT_NULL(pTab->pCheck);98  TEST_ASSERT_EQUAL_INT(1, pTab->pCheck->nExpr);99 100  const char *zName = get_last_check_name(pTab);101  TEST_ASSERT_NOT_NULL(zName);102  TEST_ASSERT_EQUAL_STRING(nm, zName);103 104  /* Cleanup */105  sqlite3ExprListDelete(db, pTab->pCheck);106  sqlite3DbFree(db, pTab);107  sqlite3_close(db);108}109 110/* Multiple constraints accumulate and each has correct derived name */111void test_sqlite3AddCheckConstraint_multiple_constraints_accumulate(void){112  sqlite3 *db = 0;113  int rc = sqlite3_open(":memory:", &db);114  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);115  db->init.iDb = 0;116 117  Parse parse;118  memset(&parse, 0, sizeof(parse));119  parse.db = db;120  parse.isCreate = 1;121 122  Table *pTab = (Table*)sqlite3DbMallocZero(db, sizeof(Table));123  TEST_ASSERT_NOT_NULL(pTab);124  parse.pNewTable = pTab;125 126  /* First constraint */127  Token t1 = { (char*)"1", 1 };128  Expr *pExpr1 = sqlite3Expr(db, TK_INTEGER, &t1);129  TEST_ASSERT_NOT_NULL(pExpr1);130 131  const char *src1 = "(x>0)";132  sqlite3AddCheckConstraint(&parse, pExpr1, src1, src1 + strlen(src1) - 1);133 134  TEST_ASSERT_NOT_NULL(pTab->pCheck);135  TEST_ASSERT_EQUAL_INT(1, pTab->pCheck->nExpr);136  TEST_ASSERT_EQUAL_STRING("x>0", get_check_name_at(pTab, 0));137 138  /* Ensure no explicit constraintName is used for next call */139  parse.u1.cr.constraintName.n = 0;140 141  /* Second constraint with interior spaces and outer whitespace */142  Token t2 = { (char*)"2", 1 };143  Expr *pExpr2 = sqlite3Expr(db, TK_INTEGER, &t2);144  TEST_ASSERT_NOT_NULL(pExpr2);145 146  const char *src2 = " (  y   is not null   ) ";147  /* The function expects zStart at '(' and zEnd at the closing ')'. */148  const char *lp = strchr(src2, '(');149  const char *rp = strrchr(src2, ')');150  TEST_ASSERT_NOT_NULL(lp);151  TEST_ASSERT_NOT_NULL(rp);152 153  sqlite3AddCheckConstraint(&parse, pExpr2, lp, rp);154 155  TEST_ASSERT_NOT_NULL(pTab->pCheck);156  TEST_ASSERT_EQUAL_INT(2, pTab->pCheck->nExpr);157  TEST_ASSERT_EQUAL_STRING("x>0", get_check_name_at(pTab, 0));158  TEST_ASSERT_EQUAL_STRING("y   is not null", get_check_name_at(pTab, 1));159 160  /* Cleanup */161  sqlite3ExprListDelete(db, pTab->pCheck);162  sqlite3DbFree(db, pTab);163  sqlite3_close(db);164}165 166/* Else-path: when pNewTable is NULL, the expression is deleted and nothing is appended */167void test_sqlite3AddCheckConstraint_null_table_expression_deleted_no_append(void){168  sqlite3 *db = 0;169  int rc = sqlite3_open(":memory:", &db);170  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);171  db->init.iDb = 0;172 173  Parse parse;174  memset(&parse, 0, sizeof(parse));175  parse.db = db;176  parse.isCreate = 1;177 178  /* No table under construction */179  parse.pNewTable = NULL;180 181  Token t1 = { (char*)"1", 1 };182  Expr *pExpr = sqlite3Expr(db, TK_INTEGER, &t1);183  TEST_ASSERT_NOT_NULL(pExpr);184 185  const char *src = "( x )";186  const char *zStart = src;187  const char *zEnd = src + strlen(src) - 1;188 189  /* Should hit the else-branch and delete pExpr internally without appending */190  sqlite3AddCheckConstraint(&parse, pExpr, zStart, zEnd);191 192  /* Nothing to assert on pTab since it is NULL; primary check is "no crash". */193  /* Close DB */194  sqlite3_close(db);195}196 197int main(void) {198  UNITY_BEGIN();199  RUN_TEST(test_sqlite3AddCheckConstraint_append_and_trimmed_name);200  RUN_TEST(test_sqlite3AddCheckConstraint_constraintName_overrides);201  RUN_TEST(test_sqlite3AddCheckConstraint_multiple_constraints_accumulate);202  RUN_TEST(test_sqlite3AddCheckConstraint_null_table_expression_deleted_no_append);203  return UNITY_END();204}