Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_expr_analyzeAggregate.c457 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4 5/* Helpers */6static void initParseWithDb(sqlite3 **pDb, Parse *pParse){7  int rc = sqlite3_open(":memory:", pDb);8  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);9  memset(pParse, 0, sizeof(Parse));10  pParse->db = *pDb;11}12 13static SrcList* makeSrcList(Parse *pParse, int cursor){14  SrcList *p = (SrcList*)sqlite3DbMallocZero(pParse->db, sizeof(SrcList));15  TEST_ASSERT_NOT_NULL(p);16  p->nSrc = 1;17  p->a = (SrcItem*)sqlite3DbMallocZero(pParse->db, sizeof(SrcItem)*1);18  TEST_ASSERT_NOT_NULL(p->a);19  p->a[0].iCursor = cursor;20  return p;21}22 23static void freeSrcList(Parse *pParse, SrcList *p){24  if( !p ) return;25  sqlite3DbFree(pParse->db, p->a);26  sqlite3DbFree(pParse->db, p);27}28 29static void initAggInfo(AggInfo *p){30  memset(p, 0, sizeof(AggInfo));31  p->iFirstReg = 0;32}33 34/* Unity fixtures */35void setUp(void) { }36void tearDown(void) { }37 38/* Tests */39 40void test_analyzeAggregate_column_in_from_adds_agg_column(void){41  sqlite3 *db = 0;42  Parse parse;43  initParseWithDb(&db, &parse);44 45  /* Setup AggInfo */46  AggInfo agg;47  initAggInfo(&agg);48 49  /* Setup SrcList with cursor 1 */50  SrcList *pSrc = makeSrcList(&parse, 1);51 52  /* Setup NameContext and Walker */53  NameContext nc;54  memset(&nc, 0, sizeof(nc));55  nc.pParse = &parse;56  nc.pSrcList = pSrc;57  nc.uNC.pAggInfo = &agg;58  nc.ncFlags = NC_UAggInfo; /* required by analyzeAggregate() assertions */59 60  Walker w;61  memset(&w, 0, sizeof(w));62  w.u.pNC = &nc;63 64  /* Create a column Expr bound to cursor 1, column 2 */65  Table t; memset(&t, 0, sizeof(t));66  Expr e; memset(&e, 0, sizeof(e));67  e.op = TK_COLUMN;68  e.iTable = 1;69  e.iColumn = 2;70  e.y.pTab = &t; /* used by findOrCreateAggInfoColumn */71 72  int rc = test_analyzeAggregate(&w, &e);73 74  TEST_ASSERT_EQUAL_INT(WRC_Continue, rc);75  TEST_ASSERT_EQUAL_INT(TK_AGG_COLUMN, e.op);76  TEST_ASSERT_EQUAL_PTR(&agg, e.pAggInfo);77  TEST_ASSERT_EQUAL_INT(0, e.iAgg);78  TEST_ASSERT_EQUAL_INT(1, agg.nColumn);79  TEST_ASSERT_NOT_NULL(agg.aCol);80  TEST_ASSERT_EQUAL_INT(1, agg.aCol[0].iTable);81  TEST_ASSERT_EQUAL_INT(2, agg.aCol[0].iColumn);82  TEST_ASSERT_EQUAL_PTR(&e, agg.aCol[0].pCExpr);83  TEST_ASSERT_EQUAL_INT(0, agg.aCol[0].iSorterColumn);84  TEST_ASSERT_EQUAL_INT(1, agg.nSortingColumn);85 86  /* Cleanup */87  sqlite3DbFree(db, agg.aCol);88  freeSrcList(&parse, pSrc);89  sqlite3_close(db);90}91 92void test_analyzeAggregate_column_not_in_from_no_change(void){93  sqlite3 *db = 0;94  Parse parse;95  initParseWithDb(&db, &parse);96 97  AggInfo agg;98  initAggInfo(&agg);99 100  /* SrcList with cursor 2; Expr uses cursor 1 -> no match */101  SrcList *pSrc = makeSrcList(&parse, 2);102 103  NameContext nc;104  memset(&nc, 0, sizeof(nc));105  nc.pParse = &parse;106  nc.pSrcList = pSrc;107  nc.uNC.pAggInfo = &agg;108  nc.ncFlags = NC_UAggInfo;109 110  Walker w;111  memset(&w, 0, sizeof(w));112  w.u.pNC = &nc;113 114  Table t; memset(&t, 0, sizeof(t));115  Expr e; memset(&e, 0, sizeof(e));116  e.op = TK_COLUMN;117  e.iTable = 1;118  e.iColumn = 3;119  e.y.pTab = &t;120 121  int rc = test_analyzeAggregate(&w, &e);122 123  TEST_ASSERT_EQUAL_INT(WRC_Continue, rc);124  TEST_ASSERT_EQUAL_INT(TK_COLUMN, e.op); /* unchanged */125  TEST_ASSERT_NULL(e.pAggInfo);126  TEST_ASSERT_EQUAL_INT(0, agg.nColumn);127 128  freeSrcList(&parse, pSrc);129  sqlite3_close(db);130}131 132void test_analyzeAggregate_default_indexedexpr_inside_agg_prunes(void){133  sqlite3 *db = 0;134  Parse parse;135  initParseWithDb(&db, &parse);136 137  AggInfo agg;138  initAggInfo(&agg);139 140  /* SrcList containing the data cursor that IndexedExpr refers to */141  int dataCur = 4;142  SrcList *pSrc = makeSrcList(&parse, dataCur);143 144  NameContext nc;145  memset(&nc, 0, sizeof(nc));146  nc.pParse = &parse;147  nc.pSrcList = pSrc;148  nc.uNC.pAggInfo = &agg;149  nc.ncFlags = NC_UAggInfo | NC_InAggFunc; /* Inside aggregate function */150 151  Walker w;152  memset(&w, 0, sizeof(w));153  w.u.pNC = &nc;154 155  /* pExpr: integer literal (default case) */156  Expr e; memset(&e, 0, sizeof(e));157  e.op = TK_INTEGER;158  e.flags = EP_IntValue;159  e.u.iValue = 42;160 161  /* Build an IndexedExpr that matches e */162  Expr eIdx; memset(&eIdx, 0, sizeof(eIdx));163  eIdx.op = TK_INTEGER;164  eIdx.flags = EP_IntValue;165  eIdx.u.iValue = 42;166 167  IndexedExpr *pIE = (IndexedExpr*)sqlite3DbMallocZero(db, sizeof(IndexedExpr));168  TEST_ASSERT_NOT_NULL(pIE);169  pIE->iDataCur = dataCur;  /* matches SrcList cursor */170  pIE->iIdxCur = 9;171  pIE->iIdxCol = 7;172  pIE->pExpr = &eIdx;173  pIE->pIENext = 0;174  parse.pIdxEpr = pIE;175 176  int rc = test_analyzeAggregate(&w, &e);177 178  TEST_ASSERT_EQUAL_INT(WRC_Prune, rc);179  TEST_ASSERT_EQUAL_PTR(&agg, e.pAggInfo);180  TEST_ASSERT_EQUAL_INT(0, e.iAgg);181  TEST_ASSERT_EQUAL_INT(1, agg.nColumn);182  TEST_ASSERT_NOT_NULL(agg.aCol);183  TEST_ASSERT_EQUAL_INT(9, agg.aCol[0].iTable);   /* iIdxCur copied */184  TEST_ASSERT_EQUAL_INT(7, agg.aCol[0].iColumn);  /* iIdxCol copied */185  TEST_ASSERT_EQUAL_PTR(&e, agg.aCol[0].pCExpr);  /* pCExpr backref to original expr */186 187  sqlite3DbFree(db, agg.aCol);188  sqlite3DbFree(db, pIE);189  freeSrcList(&parse, pSrc);190  sqlite3_close(db);191}192 193void test_analyzeAggregate_agg_function_new_entry_prunes(void){194  sqlite3 *db = 0;195  Parse parse;196  initParseWithDb(&db, &parse);197 198  AggInfo agg;199  initAggInfo(&agg);200 201  SrcList *pSrc = makeSrcList(&parse, 1);202 203  NameContext nc;204  memset(&nc, 0, sizeof(nc));205  nc.pParse = &parse;206  nc.pSrcList = pSrc;207  nc.uNC.pAggInfo = &agg;208  nc.ncFlags = NC_UAggInfo; /* not inside aggregate function */209 210  Walker w;211  memset(&w, 0, sizeof(w));212  w.u.pNC = &nc;213  w.walkerDepth = 2;214 215  /* Build aggregate function expression: count() */216  Expr e; memset(&e, 0, sizeof(e));217  e.op = TK_AGG_FUNCTION;218  e.u.zToken = "count";219  e.op2 = 2; /* must match walkerDepth */220 221  int rc = test_analyzeAggregate(&w, &e);222 223  TEST_ASSERT_EQUAL_INT(WRC_Prune, rc);224  TEST_ASSERT_EQUAL_PTR(&agg, e.pAggInfo);225  TEST_ASSERT_EQUAL_INT(0, e.iAgg);226  TEST_ASSERT_EQUAL_INT(1, agg.nFunc);227  TEST_ASSERT_NOT_NULL(agg.aFunc);228  TEST_ASSERT_EQUAL_PTR(&e, agg.aFunc[0].pFExpr);229  TEST_ASSERT_EQUAL_INT(-1, agg.aFunc[0].iOBTab);230  TEST_ASSERT_EQUAL_INT(-1, agg.aFunc[0].iDistinct);231 232  sqlite3DbFree(db, agg.aFunc);233  freeSrcList(&parse, pSrc);234  sqlite3_close(db);235}236 237void test_analyzeAggregate_agg_function_duplicate_reuses_entry(void){238  sqlite3 *db = 0;239  Parse parse;240  initParseWithDb(&db, &parse);241 242  AggInfo agg;243  initAggInfo(&agg);244 245  SrcList *pSrc = makeSrcList(&parse, 1);246 247  NameContext nc;248  memset(&nc, 0, sizeof(nc));249  nc.pParse = &parse;250  nc.pSrcList = pSrc;251  nc.uNC.pAggInfo = &agg;252  nc.ncFlags = NC_UAggInfo;253 254  Walker w;255  memset(&w, 0, sizeof(w));256  w.u.pNC = &nc;257  w.walkerDepth = 0;258 259  /* First aggregate function: sum(1) */260  Expr arg1; memset(&arg1, 0, sizeof(arg1));261  arg1.op = TK_INTEGER;262  arg1.flags = EP_IntValue;263  arg1.u.iValue = 1;264 265  ExprList *pList = (ExprList*)sqlite3DbMallocZero(db, sizeof(ExprList));266  TEST_ASSERT_NOT_NULL(pList);267  pList->nExpr = 1;268  pList->a = (struct ExprList_item*)sqlite3DbMallocZero(db, sizeof(struct ExprList_item));269  TEST_ASSERT_NOT_NULL(pList->a);270  pList->a[0].pExpr = &arg1;271 272  Expr e1; memset(&e1, 0, sizeof(e1));273  e1.op = TK_AGG_FUNCTION;274  e1.u.zToken = "sum";275  e1.x.pList = pList;276  e1.op2 = 0;277 278  int rc1 = test_analyzeAggregate(&w, &e1);279  TEST_ASSERT_EQUAL_INT(WRC_Prune, rc1);280  TEST_ASSERT_EQUAL_INT(1, agg.nFunc);281  TEST_ASSERT_EQUAL_INT(0, e1.iAgg);282 283  /* Second aggregate function identical to the first */284  Expr arg2; memset(&arg2, 0, sizeof(arg2));285  arg2.op = TK_INTEGER;286  arg2.flags = EP_IntValue;287  arg2.u.iValue = 1;288 289  ExprList *pList2 = (ExprList*)sqlite3DbMallocZero(db, sizeof(ExprList));290  TEST_ASSERT_NOT_NULL(pList2);291  pList2->nExpr = 1;292  pList2->a = (struct ExprList_item*)sqlite3DbMallocZero(db, sizeof(struct ExprList_item));293  TEST_ASSERT_NOT_NULL(pList2->a);294  pList2->a[0].pExpr = &arg2;295 296  Expr e2; memset(&e2, 0, sizeof(e2));297  e2.op = TK_AGG_FUNCTION;298  e2.u.zToken = "sum";299  e2.x.pList = pList2;300  e2.op2 = 0;301 302  int rc2 = test_analyzeAggregate(&w, &e2);303  TEST_ASSERT_EQUAL_INT(WRC_Prune, rc2);304  TEST_ASSERT_EQUAL_PTR(&agg, e2.pAggInfo);305  TEST_ASSERT_EQUAL_INT(0, e2.iAgg);  /* reuse existing entry */306  TEST_ASSERT_EQUAL_INT(1, agg.nFunc); /* no new entry added */307 308  /* Cleanup allocated arrays */309  sqlite3DbFree(db, pList->a);310  sqlite3DbFree(db, pList);311  sqlite3DbFree(db, pList2->a);312  sqlite3DbFree(db, pList2);313  sqlite3DbFree(db, agg.aFunc);314  freeSrcList(&parse, pSrc);315  sqlite3_close(db);316}317 318void test_analyzeAggregate_agg_function_distinct_sets_iDistinct(void){319  sqlite3 *db = 0;320  Parse parse;321  initParseWithDb(&db, &parse);322 323  AggInfo agg;324  initAggInfo(&agg);325 326  SrcList *pSrc = makeSrcList(&parse, 3);327 328  NameContext nc;329  memset(&nc, 0, sizeof(nc));330  nc.pParse = &parse;331  nc.pSrcList = pSrc;332  nc.uNC.pAggInfo = &agg;333  nc.ncFlags = NC_UAggInfo;334 335  Walker w;336  memset(&w, 0, sizeof(w));337  w.u.pNC = &nc;338  w.walkerDepth = 5;339 340  /* sum(DISTINCT 2) */341  Expr arg; memset(&arg, 0, sizeof(arg));342  arg.op = TK_INTEGER;343  arg.flags = EP_IntValue;344  arg.u.iValue = 2;345 346  ExprList *pList = (ExprList*)sqlite3DbMallocZero(db, sizeof(ExprList));347  TEST_ASSERT_NOT_NULL(pList);348  pList->nExpr = 1;349  pList->a = (struct ExprList_item*)sqlite3DbMallocZero(db, sizeof(struct ExprList_item));350  TEST_ASSERT_NOT_NULL(pList->a);351  pList->a[0].pExpr = &arg;352 353  Expr e; memset(&e, 0, sizeof(e));354  e.op = TK_AGG_FUNCTION;355  e.u.zToken = "sum";356  e.x.pList = pList;357  e.op2 = 5;358  e.flags |= EP_Distinct;359 360  int rc = test_analyzeAggregate(&w, &e);361 362  TEST_ASSERT_EQUAL_INT(WRC_Prune, rc);363  TEST_ASSERT_EQUAL_INT(1, agg.nFunc);364  TEST_ASSERT_TRUE(agg.aFunc[0].iDistinct >= 0); /* distinct table allocated */365  TEST_ASSERT_EQUAL_INT(-1, agg.aFunc[0].iOBTab); /* no ORDER BY payload */366 367  sqlite3DbFree(db, pList->a);368  sqlite3DbFree(db, pList);369  sqlite3DbFree(db, agg.aFunc);370  freeSrcList(&parse, pSrc);371  sqlite3_close(db);372}373 374void test_analyzeAggregate_agg_function_walkerDepth_mismatch_continue(void){375  sqlite3 *db = 0;376  Parse parse;377  initParseWithDb(&db, &parse);378 379  AggInfo agg;380  initAggInfo(&agg);381 382  SrcList *pSrc = makeSrcList(&parse, 1);383 384  NameContext nc;385  memset(&nc, 0, sizeof(nc));386  nc.pParse = &parse;387  nc.pSrcList = pSrc;388  nc.uNC.pAggInfo = &agg;389  nc.ncFlags = NC_UAggInfo;390 391  Walker w;392  memset(&w, 0, sizeof(w));393  w.u.pNC = &nc;394  w.walkerDepth = 0;395 396  Expr e; memset(&e, 0, sizeof(e));397  e.op = TK_AGG_FUNCTION;398  e.u.zToken = "count";399  e.op2 = 1; /* mismatch with walkerDepth */400 401  int rc = test_analyzeAggregate(&w, &e);402 403  TEST_ASSERT_EQUAL_INT(WRC_Continue, rc);404  TEST_ASSERT_EQUAL_INT(0, agg.nFunc);405 406  freeSrcList(&parse, pSrc);407  sqlite3_close(db);408}409 410void test_analyzeAggregate_default_outside_aggfunc_continue(void){411  sqlite3 *db = 0;412  Parse parse;413  initParseWithDb(&db, &parse);414 415  AggInfo agg;416  initAggInfo(&agg);417 418  SrcList *pSrc = makeSrcList(&parse, 1);419 420  NameContext nc;421  memset(&nc, 0, sizeof(nc));422  nc.pParse = &parse;423  nc.pSrcList = pSrc;424  nc.uNC.pAggInfo = &agg;425  nc.ncFlags = NC_UAggInfo; /* not NC_InAggFunc */426 427  Walker w;428  memset(&w, 0, sizeof(w));429  w.u.pNC = &nc;430 431  Expr e; memset(&e, 0, sizeof(e));432  e.op = TK_INTEGER;433  e.flags = EP_IntValue;434  e.u.iValue = 10;435 436  int rc = test_analyzeAggregate(&w, &e);437 438  TEST_ASSERT_EQUAL_INT(WRC_Continue, rc);439  TEST_ASSERT_NULL(e.pAggInfo);440  TEST_ASSERT_EQUAL_INT(0, agg.nColumn);441 442  freeSrcList(&parse, pSrc);443  sqlite3_close(db);444}445 446int main(void){447  UNITY_BEGIN();448  RUN_TEST(test_analyzeAggregate_column_in_from_adds_agg_column);449  RUN_TEST(test_analyzeAggregate_column_not_in_from_no_change);450  RUN_TEST(test_analyzeAggregate_default_indexedexpr_inside_agg_prunes);451  RUN_TEST(test_analyzeAggregate_agg_function_new_entry_prunes);452  RUN_TEST(test_analyzeAggregate_agg_function_duplicate_reuses_entry);453  RUN_TEST(test_analyzeAggregate_agg_function_distinct_sets_iDistinct);454  RUN_TEST(test_analyzeAggregate_agg_function_walkerDepth_mismatch_continue);455  RUN_TEST(test_analyzeAggregate_default_outside_aggfunc_continue);456  return UNITY_END();457}