Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_build_sqlite3AddDefaultValue.c204 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 hooks */10void setUp(void) {11  int rc = sqlite3_open(":memory:", &gDb);12  TEST_ASSERT_EQUAL_INT(0, 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/* Helpers to construct and destroy Table/Column objects */24static Table* makeTable(sqlite3 *db, int nCol, const char **names, const unsigned int *flags){25  Table *pTab = (Table*)sqlite3DbMallocZero(db, sizeof(Table));26  TEST_ASSERT_NOT_NULL(pTab);27  pTab->nCol = nCol;28  pTab->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nCol);29  TEST_ASSERT_NOT_NULL(pTab->aCol);30  for(int i=0;i<nCol;i++){31    pTab->aCol[i].zCnName = sqlite3DbStrDup(db, names ? names[i] : "c");32    pTab->aCol[i].colFlags = flags ? flags[i] : 0;33    pTab->aCol[i].iDflt = 0;34  }35  /* Ordinary table by default; ensure default list starts null */36  pTab->u.tab.pDfltList = 0;37  return pTab;38}39 40static void freeTable(sqlite3 *db, Table *pTab){41  if(!pTab) return;42  if( IsOrdinaryTable(pTab) ){43    sqlite3ExprListDelete(db, pTab->u.tab.pDfltList);44  }45  if(pTab->aCol){46    for(int i=0;i<pTab->nCol;i++){47      if(pTab->aCol[i].zCnName){48        sqlite3DbFree(db, pTab->aCol[i].zCnName);49      }50    }51    sqlite3DbFree(db, pTab->aCol);52  }53  sqlite3DbFree(db, pTab);54}55 56/* Tests */57 58void test_sqlite3AddDefaultValue_non_constant_expression_sets_error_and_no_default(void) {59  const char *colNames[] = { "c1" };60  unsigned int flags[] = { 0 };61  Table *pTab = makeTable(gDb, 1, colNames, flags);62 63  Parse p;64  memset(&p, 0, sizeof(p));65  p.db = gDb;66  p.pNewTable = pTab;67 68  /* Non-constant expression: identifier */69  Expr *pExpr = sqlite3Expr(gDb, TK_ID, "x");70  const char *txt = "x";71  sqlite3AddDefaultValue(&p, pExpr, txt, txt + 1);72 73  TEST_ASSERT_NOT_NULL_MESSAGE(p.zErrMsg, "Expected error message for non-constant default");74  TEST_ASSERT_NOT_NULL(strstr(p.zErrMsg, "not constant"));75  TEST_ASSERT_NOT_NULL(strstr(p.zErrMsg, "[c1]"));76  TEST_ASSERT_NULL(pTab->u.tab.pDfltList);77  TEST_ASSERT_EQUAL_INT(0, pTab->aCol[0].iDflt);78 79  sqlite3DbFree(gDb, p.zErrMsg);80  freeTable(gDb, pTab);81}82 83void test_sqlite3AddDefaultValue_generated_column_error(void) {84  const char *colNames[] = { "c1" };85  unsigned int flags[] = { COLFLAG_GENERATED };86  Table *pTab = makeTable(gDb, 1, colNames, flags);87 88  Parse p;89  memset(&p, 0, sizeof(p));90  p.db = gDb;91  p.pNewTable = pTab;92 93  /* Constant expression: integer "1" */94  Expr *pExpr = sqlite3Expr(gDb, TK_INTEGER, "1");95  const char *txt = "1";96  sqlite3AddDefaultValue(&p, pExpr, txt, txt + 1);97 98  TEST_ASSERT_NOT_NULL_MESSAGE(p.zErrMsg, "Expected error message for generated column default");99  TEST_ASSERT_NOT_NULL(strstr(p.zErrMsg, "generated column"));100  TEST_ASSERT_NULL(pTab->u.tab.pDfltList);101  TEST_ASSERT_EQUAL_INT(0, pTab->aCol[0].iDflt);102 103  sqlite3DbFree(gDb, p.zErrMsg);104  freeTable(gDb, pTab);105}106 107void test_sqlite3AddDefaultValue_sets_default_for_constant_expression(void) {108  const char *colNames[] = { "c1" };109  unsigned int flags[] = { 0 };110  Table *pTab = makeTable(gDb, 1, colNames, flags);111 112  Parse p;113  memset(&p, 0, sizeof(p));114  p.db = gDb;115  p.pNewTable = pTab;116 117  Expr *pExpr = sqlite3Expr(gDb, TK_INTEGER, "1");118  const char *txt = "1";119  sqlite3AddDefaultValue(&p, pExpr, txt, txt + 1);120 121  TEST_ASSERT_NULL(p.zErrMsg);122  TEST_ASSERT_NOT_NULL(pTab->u.tab.pDfltList);123  TEST_ASSERT_EQUAL_INT(1, pTab->u.tab.pDfltList->nExpr);124  TEST_ASSERT_EQUAL_INT(1, pTab->aCol[0].iDflt);125 126  Expr *pStored = pTab->u.tab.pDfltList->a[0].pExpr;127  TEST_ASSERT_NOT_NULL(pStored);128  TEST_ASSERT_EQUAL_INT(TK_SPAN, pStored->op);129  TEST_ASSERT_NOT_NULL(pStored->u.zToken);130  TEST_ASSERT_EQUAL_STRING("1", pStored->u.zToken);131  TEST_ASSERT_NOT_NULL(pStored->pLeft);132  TEST_ASSERT_EQUAL_INT(TK_INTEGER, pStored->pLeft->op);133 134  freeTable(gDb, pTab);135}136 137void test_sqlite3AddDefaultValue_replaces_existing_default_not_appends(void) {138  const char *colNames[] = { "c1" };139  unsigned int flags[] = { 0 };140  Table *pTab = makeTable(gDb, 1, colNames, flags);141 142  Parse p;143  memset(&p, 0, sizeof(p));144  p.db = gDb;145  p.pNewTable = pTab;146 147  /* First default "1" */148  {149    Expr *pExpr1 = sqlite3Expr(gDb, TK_INTEGER, "1");150    const char *t1 = "1";151    sqlite3AddDefaultValue(&p, pExpr1, t1, t1 + 1);152  }153  TEST_ASSERT_NULL(p.zErrMsg);154  TEST_ASSERT_NOT_NULL(pTab->u.tab.pDfltList);155  TEST_ASSERT_EQUAL_INT(1, pTab->u.tab.pDfltList->nExpr);156  TEST_ASSERT_EQUAL_INT(1, pTab->aCol[0].iDflt);157  Expr *pStored1 = pTab->u.tab.pDfltList->a[ pTab->aCol[0].iDflt - 1 ].pExpr;158  TEST_ASSERT_NOT_NULL(pStored1);159  TEST_ASSERT_EQUAL_STRING("1", pStored1->u.zToken);160 161  /* Second default "2" should replace, not append */162  {163    Expr *pExpr2 = sqlite3Expr(gDb, TK_INTEGER, "2");164    const char *t2 = "2";165    sqlite3AddDefaultValue(&p, pExpr2, t2, t2 + 1);166  }167  TEST_ASSERT_NULL(p.zErrMsg);168  TEST_ASSERT_NOT_NULL(pTab->u.tab.pDfltList);169  TEST_ASSERT_EQUAL_INT(1, pTab->u.tab.pDfltList->nExpr); /* still 1, replaced */170  TEST_ASSERT_EQUAL_INT(1, pTab->aCol[0].iDflt);171  Expr *pStored2 = pTab->u.tab.pDfltList->a[ pTab->aCol[0].iDflt - 1 ].pExpr;172  TEST_ASSERT_NOT_NULL(pStored2);173  TEST_ASSERT_EQUAL_INT(TK_SPAN, pStored2->op);174  TEST_ASSERT_EQUAL_STRING("2", pStored2->u.zToken);175 176  freeTable(gDb, pTab);177}178 179void test_sqlite3AddDefaultValue_no_new_table_does_not_crash_and_deletes_expr(void) {180  Parse p;181  memset(&p, 0, sizeof(p));182  p.db = gDb;183  p.pNewTable = NULL;184 185  /* Exercise IN_RENAME_OBJECT path as well */186  p.eParseMode = PARSE_MODE_RENAME;187 188  Expr *pExpr = sqlite3Expr(gDb, TK_INTEGER, "1");189  const char *txt = "1";190  sqlite3AddDefaultValue(&p, pExpr, txt, txt + 1);191 192  TEST_ASSERT_NULL(p.zErrMsg);193  /* Nothing else to assert; primary goal is no crash and cleanup. */194}195 196int main(void) {197  UNITY_BEGIN();198  RUN_TEST(test_sqlite3AddDefaultValue_non_constant_expression_sets_error_and_no_default);199  RUN_TEST(test_sqlite3AddDefaultValue_generated_column_error);200  RUN_TEST(test_sqlite3AddDefaultValue_sets_default_for_constant_expression);201  RUN_TEST(test_sqlite3AddDefaultValue_replaces_existing_default_not_appends);202  RUN_TEST(test_sqlite3AddDefaultValue_no_new_table_does_not_crash_and_deletes_expr);203  return UNITY_END();204}