Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_insert_xferOptimization.c377 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5 6/* Globals for test setup */7static sqlite3 *gDb = NULL;8static Parse gParse;9 10/* Helpers to construct minimal internal structures needed by xferOptimization */11 12static SrcList* makeSrcList(sqlite3 *db, int n){13  /* Allocate a SrcList with n entries */14  size_t sz = sizeof(SrcList) + (n>0 ? (size_t)(n-1)*sizeof(SrcItem) : 0);15  SrcList *p = (SrcList*)sqlite3DbMallocZero(db, (int)sz);16  if( p ){17    p->nSrc = n;18    p->nAlloc = n;19  }20  return p;21}22 23static Expr* makeExprOp(sqlite3 *db, int op){24  Expr *e = (Expr*)sqlite3DbMallocZero(db, sizeof(Expr));25  if( e ) e->op = (u8)op;26  return e;27}28 29static ExprList* makeExprListWithExpr(sqlite3 *db, Expr *e){30  ExprList *el = (ExprList*)sqlite3DbMallocZero(db, sizeof(ExprList));31  if( el ){32    el->nExpr = 1;33    el->nAlloc = 1;34    el->a = (struct ExprList_item*)sqlite3DbMallocZero(db, sizeof(struct ExprList_item));35    if( el->a ){36      el->a[0].pExpr = e;37    }38  }39  return el;40}41 42static Select* makeSelectStar(sqlite3 *db, SrcList *pSrc){43  Select *s = (Select*)sqlite3DbMallocZero(db, sizeof(Select));44  if( s ){45    Expr *star = makeExprOp(db, TK_ASTERISK);46    ExprList *elist = makeExprListWithExpr(db, star);47    s->pEList = elist;48    s->pSrc = pSrc;49  }50  return s;51}52 53static void freeSelectLite(sqlite3 *db, Select *s){54  if( !s ) return;55  if( s->pEList ){56    if( s->pEList->a ){57      if( s->pEList->a[0].pExpr ){58        sqlite3DbFree(db, s->pEList->a[0].pExpr);59      }60      sqlite3DbFree(db, s->pEList->a);61    }62    sqlite3DbFree(db, s->pEList);63  }64  if( s->pOrderBy ){65    sqlite3DbFree(db, s->pOrderBy);66  }67  if( s->pGroupBy ){68    sqlite3DbFree(db, s->pGroupBy);69  }70  if( s->pLimit ){71    sqlite3DbFree(db, s->pLimit);72  }73  if( s->pWhere ){74    sqlite3DbFree(db, s->pWhere);75  }76  if( s->pWith ){77    sqlite3DbFree(db, s->pWith);78  }79  if( s->pPrior ){80    /* pPrior may be a tiny allocated Select used just as a non-NULL marker */81    sqlite3DbFree(db, s->pPrior);82  }83  if( s->pSrc ){84    int i;85    for(i=0; i<s->pSrc->nSrc; i++){86      if( s->pSrc->a[i].zName ){87        sqlite3DbFree(db, s->pSrc->a[i].zName);88      }89      if( s->pSrc->a[i].zDatabase ){90        sqlite3DbFree(db, s->pSrc->a[i].zDatabase);91      }92    }93    sqlite3DbFree(db, s->pSrc);94  }95  sqlite3DbFree(db, s);96}97 98static Table* makeDummyDestTable(sqlite3 *db){99  Table *p = (Table*)sqlite3DbMallocZero(db, sizeof(Table));100  if( p ){101    p->zName = "dummy_dest";102    p->tabFlags = 0; /* Ensure not virtual */103  }104  return p;105}106 107/* Unity fixtures */108void setUp(void) {109  int rc = sqlite3_open(":memory:", &gDb);110  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);111  memset(&gParse, 0, sizeof(gParse));112  gParse.db = gDb;113}114 115void tearDown(void) {116  if( gDb ){117    sqlite3_close(gDb);118    gDb = NULL;119  }120}121 122/* Tests for early-return syntactic constraints */123 124void test_xferOptimization_parse_with_clause_returns_0(void){125  Table *pDest = makeDummyDestTable(gDb);126  SrcList *src = makeSrcList(gDb, 1);127  Select *sel = makeSelectStar(gDb, src);128 129  gParse.pWith = (With*)sqlite3DbMallocZero(gDb, sizeof(With)); /* non-NULL marker */130 131  int rc = test_xferOptimization(&gParse, pDest, sel, OE_Abort, 0);132  TEST_ASSERT_EQUAL_INT(0, rc);133 134  sqlite3DbFree(gDb, gParse.pWith); gParse.pWith = NULL;135  sqlite3DbFree(gDb, pDest);136  freeSelectLite(gDb, sel);137}138 139void test_xferOptimization_select_with_clause_returns_0(void){140  Table *pDest = makeDummyDestTable(gDb);141  SrcList *src = makeSrcList(gDb, 1);142  Select *sel = makeSelectStar(gDb, src);143  sel->pWith = (With*)sqlite3DbMallocZero(gDb, sizeof(With));144 145  int rc = test_xferOptimization(&gParse, pDest, sel, OE_Abort, 0);146  TEST_ASSERT_EQUAL_INT(0, rc);147 148  sqlite3DbFree(gDb, pDest);149  freeSelectLite(gDb, sel);150}151 152void test_xferOptimization_from_clause_count_not_one_returns_0(void){153  Table *pDest = makeDummyDestTable(gDb);154  SrcList *src = makeSrcList(gDb, 2); /* nSrc != 1 */155  Select *sel = makeSelectStar(gDb, src);156 157  int rc = test_xferOptimization(&gParse, pDest, sel, OE_Abort, 0);158  TEST_ASSERT_EQUAL_INT(0, rc);159 160  sqlite3DbFree(gDb, pDest);161  freeSelectLite(gDb, sel);162}163 164void test_xferOptimization_from_subquery_returns_0(void){165  Table *pDest = makeDummyDestTable(gDb);166  SrcList *src = makeSrcList(gDb, 1);167  src->a[0].fg.isSubquery = 1; /* FROM contains subquery */168  Select *sel = makeSelectStar(gDb, src);169 170  int rc = test_xferOptimization(&gParse, pDest, sel, OE_Abort, 0);171  TEST_ASSERT_EQUAL_INT(0, rc);172 173  sqlite3DbFree(gDb, pDest);174  freeSelectLite(gDb, sel);175}176 177void test_xferOptimization_with_where_returns_0(void){178  Table *pDest = makeDummyDestTable(gDb);179  SrcList *src = makeSrcList(gDb, 1);180  Select *sel = makeSelectStar(gDb, src);181  sel->pWhere = makeExprOp(gDb, TK_INTEGER); /* non-NULL */182 183  int rc = test_xferOptimization(&gParse, pDest, sel, OE_Abort, 0);184  TEST_ASSERT_EQUAL_INT(0, rc);185 186  sqlite3DbFree(gDb, pDest);187  freeSelectLite(gDb, sel);188}189 190void test_xferOptimization_with_orderby_returns_0(void){191  Table *pDest = makeDummyDestTable(gDb);192  SrcList *src = makeSrcList(gDb, 1);193  Select *sel = makeSelectStar(gDb, src);194  sel->pOrderBy = (ExprList*)sqlite3DbMallocZero(gDb, sizeof(ExprList));195 196  int rc = test_xferOptimization(&gParse, pDest, sel, OE_Abort, 0);197  TEST_ASSERT_EQUAL_INT(0, rc);198 199  sqlite3DbFree(gDb, pDest);200  freeSelectLite(gDb, sel);201}202 203void test_xferOptimization_with_groupby_returns_0(void){204  Table *pDest = makeDummyDestTable(gDb);205  SrcList *src = makeSrcList(gDb, 1);206  Select *sel = makeSelectStar(gDb, src);207  sel->pGroupBy = (ExprList*)sqlite3DbMallocZero(gDb, sizeof(ExprList));208 209  int rc = test_xferOptimization(&gParse, pDest, sel, OE_Abort, 0);210  TEST_ASSERT_EQUAL_INT(0, rc);211 212  sqlite3DbFree(gDb, pDest);213  freeSelectLite(gDb, sel);214}215 216void test_xferOptimization_with_limit_returns_0(void){217  Table *pDest = makeDummyDestTable(gDb);218  SrcList *src = makeSrcList(gDb, 1);219  Select *sel = makeSelectStar(gDb, src);220  sel->pLimit = makeExprOp(gDb, TK_INTEGER);221 222  int rc = test_xferOptimization(&gParse, pDest, sel, OE_Abort, 0);223  TEST_ASSERT_EQUAL_INT(0, rc);224 225  sqlite3DbFree(gDb, pDest);226  freeSelectLite(gDb, sel);227}228 229void test_xferOptimization_compound_select_returns_0(void){230  Table *pDest = makeDummyDestTable(gDb);231  SrcList *src = makeSrcList(gDb, 1);232  Select *sel = makeSelectStar(gDb, src);233  sel->pPrior = (Select*)sqlite3DbMallocZero(gDb, sizeof(Select));234 235  int rc = test_xferOptimization(&gParse, pDest, sel, OE_Abort, 0);236  TEST_ASSERT_EQUAL_INT(0, rc);237 238  sqlite3DbFree(gDb, pDest);239  freeSelectLite(gDb, sel);240}241 242void test_xferOptimization_distinct_returns_0(void){243  Table *pDest = makeDummyDestTable(gDb);244  SrcList *src = makeSrcList(gDb, 1);245  Select *sel = makeSelectStar(gDb, src);246  sel->selFlags |= SF_Distinct;247 248  int rc = test_xferOptimization(&gParse, pDest, sel, OE_Abort, 0);249  TEST_ASSERT_EQUAL_INT(0, rc);250 251  sqlite3DbFree(gDb, pDest);252  freeSelectLite(gDb, sel);253}254 255void test_xferOptimization_result_not_asterisk_returns_0(void){256  Table *pDest = makeDummyDestTable(gDb);257  SrcList *src = makeSrcList(gDb, 1);258  Select *sel = makeSelectStar(gDb, src);259  /* Replace '*' with a non-asterisk expression to trigger early return */260  if( sel->pEList && sel->pEList->a && sel->pEList->a[0].pExpr ){261    sel->pEList->a[0].pExpr->op = TK_INTEGER;262  }263 264  int rc = test_xferOptimization(&gParse, pDest, sel, OE_Abort, 0);265  TEST_ASSERT_EQUAL_INT(0, rc);266 267  sqlite3DbFree(gDb, pDest);268  freeSelectLite(gDb, sel);269}270 271/* Tests that exercise sqlite3LocateTableItem semantics but still return early */272 273void test_xferOptimization_locate_table_missing_returns_0(void){274  Table *pDest = makeDummyDestTable(gDb);275  SrcList *src = makeSrcList(gDb, 1);276  src->a[0].zName = sqlite3DbStrDup(gDb, "no_such_table");277  Select *sel = makeSelectStar(gDb, src);278 279  int rc = test_xferOptimization(&gParse, pDest, sel, OE_Abort, 0);280  TEST_ASSERT_EQUAL_INT(0, rc);281 282  sqlite3DbFree(gDb, pDest);283  freeSelectLite(gDb, sel);284}285 286void test_xferOptimization_same_table_returns_0(void){287  /* Create a real table t1 and use it as both src and dest */288  int rcExec = sqlite3_exec(gDb, "CREATE TABLE t1(a TEXT, b INT);", 0, 0, 0);289  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rcExec);290 291  Table *t1 = sqlite3FindTable(gDb, "t1", "main");292  TEST_ASSERT_NOT_NULL(t1);293 294  SrcList *src = makeSrcList(gDb, 1);295  src->a[0].zName = sqlite3DbStrDup(gDb, "t1");296  Select *sel = makeSelectStar(gDb, src);297 298  int iDbDest = sqlite3SchemaToIndex(gDb, t1->pSchema);299  int rc = test_xferOptimization(&gParse, t1, sel, OE_Abort, iDbDest);300  TEST_ASSERT_EQUAL_INT(0, rc);301 302  freeSelectLite(gDb, sel);303}304 305/* Semantic checks leading to success and to empty-dest-only case */306 307void test_xferOptimization_valid_simple_tables_returns_1(void){308  int rcExec = sqlite3_exec(gDb,309    "CREATE TABLE src(a TEXT, b INT);"310    "CREATE TABLE dest(a TEXT, b INT);",311    0, 0, 0312  );313  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rcExec);314 315  Table *pDest = sqlite3FindTable(gDb, "dest", "main");316  Table *pSrcTab = sqlite3FindTable(gDb, "src", "main");317  TEST_ASSERT_NOT_NULL(pDest);318  TEST_ASSERT_NOT_NULL(pSrcTab);319 320  SrcList *src = makeSrcList(gDb, 1);321  src->a[0].zName = sqlite3DbStrDup(gDb, "src");322  Select *sel = makeSelectStar(gDb, src);323 324  int iDbDest = sqlite3SchemaToIndex(gDb, pDest->pSchema);325  int rc = test_xferOptimization(&gParse, pDest, sel, OE_Abort, iDbDest);326 327  TEST_ASSERT_EQUAL_INT(1, rc);328 329  freeSelectLite(gDb, sel);330}331 332void test_xferOptimization_valid_but_requires_empty_dest_returns_0(void){333  int rcExec = sqlite3_exec(gDb,334    "CREATE TABLE srcX(a TEXT, b INT);"335    "CREATE TABLE destX(a TEXT, b INT);",336    0, 0, 0337  );338  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rcExec);339 340  Table *pDest = sqlite3FindTable(gDb, "destX", "main");341  TEST_ASSERT_NOT_NULL(pDest);342 343  SrcList *src = makeSrcList(gDb, 1);344  src->a[0].zName = sqlite3DbStrDup(gDb, "srcX");345  Select *sel = makeSelectStar(gDb, src);346 347  int iDbDest = sqlite3SchemaToIndex(gDb, pDest->pSchema);348  /* Use onError = OE_Ignore to trigger the "destination must be empty" path,349     which causes xferOptimization to return 0 after generating VDBE code. */350  int rc = test_xferOptimization(&gParse, pDest, sel, OE_Ignore, iDbDest);351 352  TEST_ASSERT_EQUAL_INT(0, rc);353 354  freeSelectLite(gDb, sel);355}356 357int main(void){358  UNITY_BEGIN();359 360  RUN_TEST(test_xferOptimization_parse_with_clause_returns_0);361  RUN_TEST(test_xferOptimization_select_with_clause_returns_0);362  RUN_TEST(test_xferOptimization_from_clause_count_not_one_returns_0);363  RUN_TEST(test_xferOptimization_from_subquery_returns_0);364  RUN_TEST(test_xferOptimization_with_where_returns_0);365  RUN_TEST(test_xferOptimization_with_orderby_returns_0);366  RUN_TEST(test_xferOptimization_with_groupby_returns_0);367  RUN_TEST(test_xferOptimization_with_limit_returns_0);368  RUN_TEST(test_xferOptimization_compound_select_returns_0);369  RUN_TEST(test_xferOptimization_distinct_returns_0);370  RUN_TEST(test_xferOptimization_result_not_asterisk_returns_0);371  RUN_TEST(test_xferOptimization_locate_table_missing_returns_0);372  RUN_TEST(test_xferOptimization_same_table_returns_0);373  RUN_TEST(test_xferOptimization_valid_simple_tables_returns_1);374  RUN_TEST(test_xferOptimization_valid_but_requires_empty_dest_returns_0);375 376  return UNITY_END();377}