Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_insert_xferCompatibleIndex.c391 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5 6/* External wrapper for the static function under test */7extern int test_xferCompatibleIndex(Index *pDest, Index *pSrc);8 9void setUp(void) {10  /* Setup code here, or leave empty */11}12void tearDown(void) {13  /* Cleanup code here, or leave empty */14}15 16/* Helper: create a minimal Expr with a specific opcode */17static Expr* makeExprOp(int op){18  Expr *e = (Expr*)malloc(sizeof(Expr));19  if( e ){20    memset(e, 0, sizeof(Expr));21    e->op = (u8)op;22  }23  return e;24}25 26/* Helper: create an ExprList with n entries referencing exprs[i] */27static ExprList* makeExprList(Expr **exprs, int n){28  if( n<=0 ) return NULL;29  /* ExprList has flexible array member a[] */30  ExprList *p = (ExprList*)malloc(sizeof(ExprList) + (n-1)*(sizeof(p->a[0])));31  if( p ){32    memset(p, 0, sizeof(ExprList) + (n-1)*(sizeof(p->a[0])));33    p->nExpr = n;34    p->nAlloc = n;35    for(int i=0; i<n; i++){36      p->a[i].pExpr = exprs ? exprs[i] : NULL;37    }38  }39  return p;40}41 42/* Helper: allocate and populate an Index structure.43   - aiCol: length nColumn44   - sort:  length nKeyCol45   - coll:  length nKeyCol (array of const char*)46   - exprList: length nKeyCol if any aiCol[i]==XN_EXPR, otherwise may be NULL47   - whereExpr: optional WHERE Expr (may be NULL)48*/49static Index* buildIndex(50  int nKeyCol, int nColumn, int onError,51  const int *aiCol, const u8 *sort, const char* const *coll,52  Expr **exprList, Expr *whereExpr53){54  Index *pIdx = (Index*)malloc(sizeof(Index));55  Table *pTab = (Table*)malloc(sizeof(Table));56  if( !pIdx || !pTab ) {57    free(pIdx);58    free(pTab);59    return NULL;60  }61  memset(pIdx, 0, sizeof(Index));62  memset(pTab, 0, sizeof(Table));63  pIdx->pTable = pTab;64 65  pIdx->nKeyCol = (u16)nKeyCol;66  pIdx->nColumn = (i16)nColumn;67  pIdx->onError = (u8)onError;68 69  /* aiColumn (length = nColumn) */70  if( nColumn>0 ){71    pIdx->aiColumn = (i16*)malloc(sizeof(i16)*nColumn);72    for(int i=0;i<nColumn;i++){73      pIdx->aiColumn[i] = aiCol ? (i16)aiCol[i] : (i16)i;74    }75  }76 77  /* aSortOrder (length = nKeyCol) */78  if( nKeyCol>0 ){79    pIdx->aSortOrder = (u8*)malloc(sizeof(u8)*nKeyCol);80    pIdx->azColl     = (char**)malloc(sizeof(char*)*nKeyCol);81    for(int i=0;i<nKeyCol;i++){82      pIdx->aSortOrder[i] = sort ? sort[i] : 0;83      pIdx->azColl[i]     = coll ? (char*)coll[i] : (char*)"BINARY";84    }85  }86 87  /* aColExpr if any expression-based columns */88  int needExprList = 0;89  for(int i=0;i<nKeyCol;i++){90    if( pIdx->aiColumn && pIdx->aiColumn[i]==XN_EXPR ){91      needExprList = 1;92      break;93    }94  }95  if( needExprList ){96    pIdx->aColExpr = makeExprList(exprList, nKeyCol);97  }98 99  pIdx->pPartIdxWhere = whereExpr;100 101  return pIdx;102}103 104/* Helper: free Index and owned allocations (does not free Expr or strings) */105static void freeIndexShallow(Index *pIdx){106  if( !pIdx ) return;107  if( pIdx->aiColumn ) free(pIdx->aiColumn);108  if( pIdx->aSortOrder ) free(pIdx->aSortOrder);109  if( pIdx->azColl ) free(pIdx->azColl);110  if( pIdx->aColExpr ) free(pIdx->aColExpr); /* ExprList container only */111  if( pIdx->pTable ) free(pIdx->pTable);112  free(pIdx);113}114 115/* ========== Tests ========== */116 117void test_xferCompatibleIndex_identical_basic(void){118  int aiCol[1] = { 3 };119  u8 sort[1] = { 0 };120  const char* coll[1] = { "BINARY" };121 122  Index *pDest = buildIndex(1, 1, OE_Abort, aiCol, sort, coll, NULL, NULL);123  Index *pSrc  = buildIndex(1, 1, OE_Abort, aiCol, sort, coll, NULL, NULL);124 125  TEST_ASSERT_NOT_NULL(pDest);126  TEST_ASSERT_NOT_NULL(pSrc);127  TEST_ASSERT_TRUE(pDest->pTable != pSrc->pTable);128 129  int rc = test_xferCompatibleIndex(pDest, pSrc);130  TEST_ASSERT_EQUAL_INT(1, rc);131 132  freeIndexShallow(pDest);133  freeIndexShallow(pSrc);134}135 136void test_xferCompatibleIndex_diff_nKeyCol(void){137  int aiCol2[2] = { 0, 1 };138  int aiCol1[2] = { 0, 1 };139  u8 sort2[2] = { 0, 0 };140  const char* coll2[2] = { "BINARY", "BINARY" };141 142  Index *pDest = buildIndex(1, 2, OE_Abort, aiCol1, sort2, coll2, NULL, NULL);143  Index *pSrc  = buildIndex(2, 2, OE_Abort, aiCol2, sort2, coll2, NULL, NULL);144 145  TEST_ASSERT_NOT_NULL(pDest);146  TEST_ASSERT_NOT_NULL(pSrc);147  TEST_ASSERT_TRUE(pDest->pTable != pSrc->pTable);148 149  int rc = test_xferCompatibleIndex(pDest, pSrc);150  TEST_ASSERT_EQUAL_INT(0, rc);151 152  freeIndexShallow(pDest);153  freeIndexShallow(pSrc);154}155 156void test_xferCompatibleIndex_diff_nColumn(void){157  int aiCol1[1] = { 0 };158  int aiCol2[2] = { 0, 1 };159  u8 sort1[1] = { 0 };160  const char* coll1[1] = { "BINARY" };161 162  Index *pDest = buildIndex(1, 1, OE_Abort, aiCol1, sort1, coll1, NULL, NULL);163  Index *pSrc  = buildIndex(1, 2, OE_Abort, aiCol2, sort1, coll1, NULL, NULL);164 165  TEST_ASSERT_NOT_NULL(pDest);166  TEST_ASSERT_NOT_NULL(pSrc);167  TEST_ASSERT_TRUE(pDest->pTable != pSrc->pTable);168 169  int rc = test_xferCompatibleIndex(pDest, pSrc);170  TEST_ASSERT_EQUAL_INT(0, rc);171 172  freeIndexShallow(pDest);173  freeIndexShallow(pSrc);174}175 176void test_xferCompatibleIndex_diff_onError(void){177  int aiCol[1] = { 0 };178  u8 sort[1] = { 0 };179  const char* coll[1] = { "BINARY" };180 181  Index *pDest = buildIndex(1, 1, OE_Abort,  aiCol, sort, coll, NULL, NULL);182  Index *pSrc  = buildIndex(1, 1, OE_Ignore, aiCol, sort, coll, NULL, NULL);183 184  TEST_ASSERT_NOT_NULL(pDest);185  TEST_ASSERT_NOT_NULL(pSrc);186  TEST_ASSERT_TRUE(pDest->pTable != pSrc->pTable);187 188  int rc = test_xferCompatibleIndex(pDest, pSrc);189  TEST_ASSERT_EQUAL_INT(0, rc);190 191  freeIndexShallow(pDest);192  freeIndexShallow(pSrc);193}194 195void test_xferCompatibleIndex_diff_aiColumn(void){196  int aiColA[1] = { 1 };197  int aiColB[1] = { 2 };198  u8 sort[1] = { 0 };199  const char* coll[1] = { "BINARY" };200 201  Index *pDest = buildIndex(1, 1, OE_Abort, aiColA, sort, coll, NULL, NULL);202  Index *pSrc  = buildIndex(1, 1, OE_Abort, aiColB, sort, coll, NULL, NULL);203 204  TEST_ASSERT_NOT_NULL(pDest);205  TEST_ASSERT_NOT_NULL(pSrc);206  TEST_ASSERT_TRUE(pDest->pTable != pSrc->pTable);207 208  int rc = test_xferCompatibleIndex(pDest, pSrc);209  TEST_ASSERT_EQUAL_INT(0, rc);210 211  freeIndexShallow(pDest);212  freeIndexShallow(pSrc);213}214 215void test_xferCompatibleIndex_expr_equal(void){216  int aiCol[1] = { XN_EXPR };217  u8 sort[1] = { 0 };218  const char* coll[1] = { "BINARY" };219 220  /* Use identical expressions on both sides */221  Expr *e = makeExprOp(TK_INTEGER);222  Expr *exprs[1] = { e };223 224  Index *pDest = buildIndex(1, 1, OE_Abort, aiCol, sort, coll, exprs, NULL);225  Index *pSrc  = buildIndex(1, 1, OE_Abort, aiCol, sort, coll, exprs, NULL);226 227  TEST_ASSERT_NOT_NULL(pDest);228  TEST_ASSERT_NOT_NULL(pSrc);229  TEST_ASSERT_TRUE(pDest->pTable != pSrc->pTable);230  TEST_ASSERT_NOT_NULL(pDest->aColExpr);231  TEST_ASSERT_NOT_NULL(pSrc->aColExpr);232 233  int rc = test_xferCompatibleIndex(pDest, pSrc);234  TEST_ASSERT_EQUAL_INT(1, rc);235 236  /* Avoid double-free of shared Expr 'e' by not freeing Expr pointers */237  freeIndexShallow(pDest);238  freeIndexShallow(pSrc);239  free(e);240}241 242void test_xferCompatibleIndex_expr_different(void){243  int aiCol[1] = { XN_EXPR };244  u8 sort[1] = { 0 };245  const char* coll[1] = { "BINARY" };246 247  Expr *e1 = makeExprOp(TK_INTEGER);248  Expr *e2 = makeExprOp(TK_NULL);249  Expr *exprs1[1] = { e1 };250  Expr *exprs2[1] = { e2 };251 252  Index *pDest = buildIndex(1, 1, OE_Abort, aiCol, sort, coll, exprs1, NULL);253  Index *pSrc  = buildIndex(1, 1, OE_Abort, aiCol, sort, coll, exprs2, NULL);254 255  TEST_ASSERT_NOT_NULL(pDest);256  TEST_ASSERT_NOT_NULL(pSrc);257  TEST_ASSERT_TRUE(pDest->pTable != pSrc->pTable);258  TEST_ASSERT_NOT_NULL(pDest->aColExpr);259  TEST_ASSERT_NOT_NULL(pSrc->aColExpr);260 261  int rc = test_xferCompatibleIndex(pDest, pSrc);262  TEST_ASSERT_EQUAL_INT(0, rc);263 264  freeIndexShallow(pDest);265  freeIndexShallow(pSrc);266  free(e1);267  free(e2);268}269 270void test_xferCompatibleIndex_sort_order_mismatch(void){271  int aiCol[1] = { 0 };272  u8 sortA[1] = { 0 }; /* ASC */273  u8 sortB[1] = { 1 }; /* DESC */274  const char* coll[1] = { "BINARY" };275 276  Index *pDest = buildIndex(1, 1, OE_Abort, aiCol, sortA, coll, NULL, NULL);277  Index *pSrc  = buildIndex(1, 1, OE_Abort, aiCol, sortB, coll, NULL, NULL);278 279  TEST_ASSERT_NOT_NULL(pDest);280  TEST_ASSERT_NOT_NULL(pSrc);281  TEST_ASSERT_TRUE(pDest->pTable != pSrc->pTable);282 283  int rc = test_xferCompatibleIndex(pDest, pSrc);284  TEST_ASSERT_EQUAL_INT(0, rc);285 286  freeIndexShallow(pDest);287  freeIndexShallow(pSrc);288}289 290void test_xferCompatibleIndex_collation_mismatch(void){291  int aiCol[1] = { 0 };292  u8 sort[1] = { 0 };293  const char* collA[1] = { "BINARY" };294  const char* collB[1] = { "NOCASE" };295 296  Index *pDest = buildIndex(1, 1, OE_Abort, aiCol, sort, collA, NULL, NULL);297  Index *pSrc  = buildIndex(1, 1, OE_Abort, aiCol, sort, collB, NULL, NULL);298 299  TEST_ASSERT_NOT_NULL(pDest);300  TEST_ASSERT_NOT_NULL(pSrc);301  TEST_ASSERT_TRUE(pDest->pTable != pSrc->pTable);302 303  int rc = test_xferCompatibleIndex(pDest, pSrc);304  TEST_ASSERT_EQUAL_INT(0, rc);305 306  freeIndexShallow(pDest);307  freeIndexShallow(pSrc);308}309 310void test_xferCompatibleIndex_collation_case_insensitive_equal(void){311  int aiCol[1] = { 0 };312  u8 sort[1] = { 0 };313  const char* collA[1] = { "binary" };314  const char* collB[1] = { "BINARY" };315 316  Index *pDest = buildIndex(1, 1, OE_Abort, aiCol, sort, collA, NULL, NULL);317  Index *pSrc  = buildIndex(1, 1, OE_Abort, aiCol, sort, collB, NULL, NULL);318 319  TEST_ASSERT_NOT_NULL(pDest);320  TEST_ASSERT_NOT_NULL(pSrc);321  TEST_ASSERT_TRUE(pDest->pTable != pSrc->pTable);322 323  int rc = test_xferCompatibleIndex(pDest, pSrc);324  TEST_ASSERT_EQUAL_INT(1, rc);325 326  freeIndexShallow(pDest);327  freeIndexShallow(pSrc);328}329 330void test_xferCompatibleIndex_where_equal(void){331  int aiCol[1] = { 0 };332  u8 sort[1] = { 0 };333  const char* coll[1] = { "BINARY" };334 335  Expr *w = makeExprOp(TK_INTEGER);336 337  Index *pDest = buildIndex(1, 1, OE_Abort, aiCol, sort, coll, NULL, w);338  Index *pSrc  = buildIndex(1, 1, OE_Abort, aiCol, sort, coll, NULL, w);339 340  TEST_ASSERT_NOT_NULL(pDest);341  TEST_ASSERT_NOT_NULL(pSrc);342  TEST_ASSERT_TRUE(pDest->pTable != pSrc->pTable);343 344  int rc = test_xferCompatibleIndex(pDest, pSrc);345  TEST_ASSERT_EQUAL_INT(1, rc);346 347  freeIndexShallow(pDest);348  freeIndexShallow(pSrc);349  free(w);350}351 352void test_xferCompatibleIndex_where_different(void){353  int aiCol[1] = { 0 };354  u8 sort[1] = { 0 };355  const char* coll[1] = { "BINARY" };356 357  Expr *w1 = makeExprOp(TK_INTEGER);358  Expr *w2 = makeExprOp(TK_NULL);359 360  Index *pDest = buildIndex(1, 1, OE_Abort, aiCol, sort, coll, NULL, w1);361  Index *pSrc  = buildIndex(1, 1, OE_Abort, aiCol, sort, coll, NULL, w2);362 363  TEST_ASSERT_NOT_NULL(pDest);364  TEST_ASSERT_NOT_NULL(pSrc);365  TEST_ASSERT_TRUE(pDest->pTable != pSrc->pTable);366 367  int rc = test_xferCompatibleIndex(pDest, pSrc);368  TEST_ASSERT_EQUAL_INT(0, rc);369 370  freeIndexShallow(pDest);371  freeIndexShallow(pSrc);372  free(w1);373  free(w2);374}375 376int main(void) {377  UNITY_BEGIN();378  RUN_TEST(test_xferCompatibleIndex_identical_basic);379  RUN_TEST(test_xferCompatibleIndex_diff_nKeyCol);380  RUN_TEST(test_xferCompatibleIndex_diff_nColumn);381  RUN_TEST(test_xferCompatibleIndex_diff_onError);382  RUN_TEST(test_xferCompatibleIndex_diff_aiColumn);383  RUN_TEST(test_xferCompatibleIndex_expr_equal);384  RUN_TEST(test_xferCompatibleIndex_expr_different);385  RUN_TEST(test_xferCompatibleIndex_sort_order_mismatch);386  RUN_TEST(test_xferCompatibleIndex_collation_mismatch);387  RUN_TEST(test_xferCompatibleIndex_collation_case_insensitive_equal);388  RUN_TEST(test_xferCompatibleIndex_where_equal);389  RUN_TEST(test_xferCompatibleIndex_where_different);390  return UNITY_END();391}