Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_build_sqlite3AddPrimaryKey.c197 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Helpers to construct minimal Table/Column and ExprList objects */7static Table* makeTable(sqlite3 *db, const char *zTabName,8                        int nCol, const char *const *azCol,9                        const int *aiIsInteger){10  Table *pTab = (Table*)sqlite3DbMallocZero(db, sizeof(Table));11  int i;12  TEST_ASSERT_NOT_NULL_MESSAGE(pTab, "malloc Table failed");13  pTab->zName = sqlite3DbStrDup(db, zTabName);14  TEST_ASSERT_NOT_NULL_MESSAGE(pTab->zName, "malloc zName failed");15  pTab->nCol = (i16)nCol;16  pTab->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nCol);17  TEST_ASSERT_NOT_NULL_MESSAGE(pTab->aCol, "malloc aCol failed");18  pTab->iPKey = -1;19  for(i=0; i<nCol; i++){20    Column *pCol = &pTab->aCol[i];21    /* Name */22    pCol->zCnName = sqlite3DbStrDup(db, azCol[i]);23    TEST_ASSERT_NOT_NULL_MESSAGE(pCol->zCnName, "malloc column name failed");24    /* Type classification: only check for INTEGER explicitly */25    pCol->eCType = (aiIsInteger && aiIsInteger[i]) ? COLTYPE_INTEGER : 0; /* non-integer as 0 */26    pCol->colFlags = 0;27    pCol->notNull = 0;28  }29  return pTab;30}31 32static void freeTable(sqlite3 *db, Table *pTab){33  if(!pTab) return;34  if(pTab->aCol){35    for(int i=0; i<pTab->nCol; i++){36      if(pTab->aCol[i].zCnName) sqlite3DbFree(db, (void*)pTab->aCol[i].zCnName);37    }38    sqlite3DbFree(db, pTab->aCol);39  }40  if(pTab->zName) sqlite3DbFree(db, pTab->zName);41  sqlite3DbFree(db, pTab);42}43 44static ExprList* makeExprListForColumn(Parse *pParse, const char *zCol){45  Token t;46  Expr *pExpr;47  ExprList *pList;48  t.z = zCol;49  t.n = (int)strlen(zCol);50  pExpr = sqlite3ExprAlloc(pParse->db, TK_ID, &t, 0);51  TEST_ASSERT_NOT_NULL_MESSAGE(pExpr, "sqlite3ExprAlloc failed");52  pList = sqlite3ExprListAppend(pParse, 0, pExpr);53  TEST_ASSERT_NOT_NULL_MESSAGE(pList, "sqlite3ExprListAppend failed");54  return pList;55}56 57void setUp(void) {58  /* no-op */59}60 61void tearDown(void) {62  /* no-op */63}64 65/* Test: last column is INTEGER, AUTOINCREMENT flag set, and conflict policy recorded */66void test_sqlite3AddPrimaryKey_lastcol_integer_autoinc(void){67  sqlite3 *db = 0; Parse p; memset(&p, 0, sizeof(p));68  const char *cols[] = {"c1", "id"};69  int isInt[] = {0, 1};70  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));71  p.db = db;72  Table *t = makeTable(db, "t1", 2, cols, isInt);73  p.pNewTable = t;74 75  sqlite3AddPrimaryKey(&p, 0, OE_Abort, 1, SQLITE_SO_ASC);76 77  TEST_ASSERT_EQUAL_INT(1, t->iPKey);78  TEST_ASSERT_EQUAL_UINT8(OE_Abort, t->keyConf);79  TEST_ASSERT_NOT_EQUAL(0, (t->tabFlags & TF_Autoincrement));80  TEST_ASSERT_NOT_EQUAL(0, (t->aCol[1].colFlags & COLFLAG_PRIMKEY));81  TEST_ASSERT_EQUAL_INT(0, p.nErr);82 83  if(p.zErrMsg){ sqlite3DbFree(db, p.zErrMsg); p.zErrMsg = 0; }84  freeTable(db, t);85  sqlite3_close(db);86}87 88/* Test: named single INTEGER column primary key sets iPKey and captures iPkSortOrder */89void test_sqlite3AddPrimaryKey_named_integer_column_and_sortflags(void){90  sqlite3 *db = 0; Parse p; memset(&p, 0, sizeof(p));91  const char *cols[] = {"a"};92  int isInt[] = {1};93  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));94  p.db = db;95  Table *t = makeTable(db, "t2", 1, cols, isInt);96  p.pNewTable = t;97 98  ExprList *pList = makeExprListForColumn(&p, "a");99  /* Simulate a DESC sort-flag on the column in the list */100  pList->a[0].fg.sortFlags = SQLITE_SO_DESC;101 102  sqlite3AddPrimaryKey(&p, pList, OE_Ignore, 0, SQLITE_SO_ASC);103 104  TEST_ASSERT_EQUAL_INT(0, t->iPKey);105  TEST_ASSERT_EQUAL_UINT8(OE_Ignore, t->keyConf);106  TEST_ASSERT_EQUAL_INT(SQLITE_SO_DESC, p.iPkSortOrder);107  TEST_ASSERT_NOT_EQUAL(0, (t->aCol[0].colFlags & COLFLAG_PRIMKEY));108  TEST_ASSERT_EQUAL_INT(0, p.nErr);109 110  if(p.zErrMsg){ sqlite3DbFree(db, p.zErrMsg); p.zErrMsg = 0; }111  freeTable(db, t);112  sqlite3_close(db);113}114 115/* Test: AUTOINCREMENT on non-integer primary key column yields an error */116void test_sqlite3AddPrimaryKey_autoinc_error_on_non_integer(void){117  sqlite3 *db = 0; Parse p; memset(&p, 0, sizeof(p));118  const char *cols[] = {"x", "y"};119  int isInt[] = {0, 0}; /* neither column is INTEGER */120  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));121  p.db = db;122  Table *t = makeTable(db, "t3", 2, cols, isInt);123  p.pNewTable = t;124 125  sqlite3AddPrimaryKey(&p, 0, OE_None, 1, SQLITE_SO_ASC);126 127  TEST_ASSERT_TRUE(p.nErr > 0);128  TEST_ASSERT_NOT_NULL(p.zErrMsg);129#ifndef SQLITE_OMIT_AUTOINCREMENT130  TEST_ASSERT_NOT_NULL(strstr(p.zErrMsg, "AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY"));131#endif132  TEST_ASSERT_EQUAL_INT(-1, t->iPKey); /* Should remain unchanged */133 134  if(p.zErrMsg){ sqlite3DbFree(db, p.zErrMsg); p.zErrMsg = 0; }135  freeTable(db, t);136  sqlite3_close(db);137}138 139/* Test: second primary key definition triggers appropriate error */140void test_sqlite3AddPrimaryKey_duplicate_pk_error(void){141  sqlite3 *db = 0; Parse p; memset(&p, 0, sizeof(p));142  const char *cols[] = {"a"};143  int isInt[] = {1};144  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));145  p.db = db;146  Table *t = makeTable(db, "tDup", 1, cols, isInt);147  t->tabFlags |= TF_HasPrimaryKey; /* Simulate already having a PK */148  p.pNewTable = t;149 150  sqlite3AddPrimaryKey(&p, 0, OE_None, 0, SQLITE_SO_ASC);151 152  TEST_ASSERT_TRUE(p.nErr > 0);153  TEST_ASSERT_NOT_NULL(p.zErrMsg);154  TEST_ASSERT_NOT_NULL(strstr(p.zErrMsg, "more than one primary key"));155 156  if(p.zErrMsg){ sqlite3DbFree(db, p.zErrMsg); p.zErrMsg = 0; }157  freeTable(db, t);158  sqlite3_close(db);159}160 161/* Test: explicit NULLS FIRST/LAST is rejected for INTEGER PRIMARY KEY */162void test_sqlite3AddPrimaryKey_explicit_nulls_error(void){163  sqlite3 *db = 0; Parse p; memset(&p, 0, sizeof(p));164  const char *cols[] = {"id"};165  int isInt[] = {1};166  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));167  p.db = db;168  Table *t = makeTable(db, "tNulls", 1, cols, isInt);169  p.pNewTable = t;170 171  ExprList *pList = makeExprListForColumn(&p, "id");172  /* Set explicit NULLS FIRST */173  pList->a[0].fg.bNulls = 1;174  pList->a[0].fg.sortFlags = 0; /* choose FIRST */175 176  sqlite3AddPrimaryKey(&p, pList, OE_Abort, 0, SQLITE_SO_ASC);177 178  TEST_ASSERT_TRUE(p.nErr > 0);179  TEST_ASSERT_NOT_NULL(p.zErrMsg);180  TEST_ASSERT_NOT_NULL(strstr(p.zErrMsg, "NULLS FIRST"));181  /* Even though error is set, the function may have set iPKey already */182  TEST_ASSERT_EQUAL_INT(0, t->iPKey);183 184  if(p.zErrMsg){ sqlite3DbFree(db, p.zErrMsg); p.zErrMsg = 0; }185  freeTable(db, t);186  sqlite3_close(db);187}188 189int main(void){190  UNITY_BEGIN();191  RUN_TEST(test_sqlite3AddPrimaryKey_lastcol_integer_autoinc);192  RUN_TEST(test_sqlite3AddPrimaryKey_named_integer_column_and_sortflags);193  RUN_TEST(test_sqlite3AddPrimaryKey_autoinc_error_on_non_integer);194  RUN_TEST(test_sqlite3AddPrimaryKey_duplicate_pk_error);195  RUN_TEST(test_sqlite3AddPrimaryKey_explicit_nulls_error);196  return UNITY_END();197}