Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_resolve_sqlite3ResolveExprListNames.c253 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3 4#include <string.h>5 6/* Global database handle for tests */7static sqlite3 *gDb = NULL;8 9/* Helper to initialize a Parse object */10static void initParse(Parse *p, sqlite3 *db){11  memset(p, 0, sizeof(*p));12  p->db = db;13}14 15/* Helper: create an integer literal expression */16static Expr* makeIntLiteral(Parse *pParse, const char *z){17  return sqlite3Expr(pParse->db, TK_INTEGER, z);18}19 20/* Helper: create a single-arg function expression, e.g., name(arglit) */21static Expr* makeFunc1(Parse *pParse, const char *zName, const char *arglit){22  Expr *pArg = makeIntLiteral(pParse, arglit);23  ExprList *pArgs = sqlite3ExprListAppend(pParse, 0, pArg);24  Token t;25  t.z = (char*)zName;26  t.n = (int)strlen(zName);27  return sqlite3ExprFunction(pParse, pArgs, &t);28}29 30/* Helper: append an expression to a new or existing list */31static ExprList* listAppend(Parse *pParse, ExprList *pList, Expr *pExpr){32  return sqlite3ExprListAppend(pParse, pList, pExpr);33}34 35void setUp(void) {36  int rc = sqlite3_open(":memory:", &gDb);37  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);38}39 40void tearDown(void) {41  if( gDb ){42    sqlite3_close(gDb);43    gDb = NULL;44  }45}46 47/* Test: pList == NULL should return SQLITE_OK and not modify ncFlags */48void test_sqlite3ResolveExprListNames_null_list(void){49  Parse p;50  initParse(&p, gDb);51 52  NameContext nc;53  memset(&nc, 0, sizeof(nc));54  nc.pParse = &p;55  nc.ncFlags = (u16)(NC_HasAgg | NC_MinMaxAgg | NC_HasWin | NC_OrderAgg);56 57  u16 before = nc.ncFlags;58  int rc = sqlite3ResolveExprListNames(&nc, NULL);59  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);60  TEST_ASSERT_EQUAL_UINT16(before, nc.ncFlags);61}62 63/* Test: simple literal expression should not set EP_Agg/EP_Win and ncFlags remain 0 */64void test_sqlite3ResolveExprListNames_plain_literal(void){65  Parse p;66  initParse(&p, gDb);67 68  NameContext nc;69  memset(&nc, 0, sizeof(nc));70  nc.pParse = &p;71 72  Expr *pOne = makeIntLiteral(&p, "1");73  ExprList *pList = listAppend(&p, NULL, pOne);74 75  int rc = sqlite3ResolveExprListNames(&nc, pList);76  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);77 78  /* First and only expression */79  Expr *pExpr0 = pList->a[0].pExpr;80  TEST_ASSERT_NOT_NULL(pExpr0);81  TEST_ASSERT_EQUAL_INT(0, (pExpr0->flags & (EP_Agg|EP_Win)));82  TEST_ASSERT_EQUAL_UINT16(0, (nc.ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg)));83 84  sqlite3ExprListDelete(p.db, pList);85}86 87/* Test: aggregate function count(1) sets EP_Agg and NC_HasAgg */88void test_sqlite3ResolveExprListNames_simple_agg_count(void){89  Parse p;90  initParse(&p, gDb);91 92  NameContext nc;93  memset(&nc, 0, sizeof(nc));94  nc.pParse = &p;95 96  Expr *pCnt = makeFunc1(&p, "count", "1");97  ExprList *pList = listAppend(&p, NULL, pCnt);98 99  int rc = sqlite3ResolveExprListNames(&nc, pList);100  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);101 102  Expr *pExpr0 = pList->a[0].pExpr;103  TEST_ASSERT_NOT_NULL(pExpr0);104  TEST_ASSERT_NOT_EQUAL(0, (pExpr0->flags & EP_Agg));105  TEST_ASSERT_EQUAL_INT(0, (pExpr0->flags & EP_Win));106  TEST_ASSERT_NOT_EQUAL(0, (nc.ncFlags & NC_HasAgg));107 108  sqlite3ExprListDelete(p.db, pList);109}110 111/* Test: savedHasAgg behavior across multiple expressions: [1, count(1)] */112void test_sqlite3ResolveExprListNames_two_exprs_savedHasAgg(void){113  Parse p;114  initParse(&p, gDb);115 116  NameContext nc;117  memset(&nc, 0, sizeof(nc));118  nc.pParse = &p;119 120  Expr *pOne = makeIntLiteral(&p, "1");121  Expr *pCnt = makeFunc1(&p, "count", "1");122  ExprList *pList = NULL;123  pList = listAppend(&p, pList, pOne);124  pList = listAppend(&p, pList, pCnt);125 126  int rc = sqlite3ResolveExprListNames(&nc, pList);127  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);128 129  Expr *pExpr0 = pList->a[0].pExpr;130  Expr *pExpr1 = pList->a[1].pExpr;131  TEST_ASSERT_NOT_NULL(pExpr0);132  TEST_ASSERT_NOT_NULL(pExpr1);133  TEST_ASSERT_EQUAL_INT(0, (pExpr0->flags & (EP_Agg|EP_Win)));134  TEST_ASSERT_NOT_EQUAL(0, (pExpr1->flags & EP_Agg));135  TEST_ASSERT_NOT_EQUAL(0, (nc.ncFlags & NC_HasAgg));136 137  sqlite3ExprListDelete(p.db, pList);138}139 140/* Test: min(1) should set EP_Agg on expr and NC_MinMaxAgg in ncFlags (and NC_HasAgg) */141void test_sqlite3ResolveExprListNames_minmax_flags(void){142  Parse p;143  initParse(&p, gDb);144 145  NameContext nc;146  memset(&nc, 0, sizeof(nc));147  nc.pParse = &p;148 149  Expr *pMin = makeFunc1(&p, "min", "1");150  ExprList *pList = listAppend(&p, NULL, pMin);151 152  int rc = sqlite3ResolveExprListNames(&nc, pList);153  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);154 155  Expr *pExpr0 = pList->a[0].pExpr;156  TEST_ASSERT_NOT_NULL(pExpr0);157  TEST_ASSERT_NOT_EQUAL(0, (pExpr0->flags & EP_Agg));158  TEST_ASSERT_NOT_EQUAL(0, (nc.ncFlags & NC_HasAgg));159  TEST_ASSERT_NOT_EQUAL(0, (nc.ncFlags & NC_MinMaxAgg));160 161  sqlite3ExprListDelete(p.db, pList);162}163 164/* Test: initial flags (e.g., NC_OrderAgg) are preserved and unioned with found flags */165void test_sqlite3ResolveExprListNames_preserves_initial_flags(void){166  Parse p;167  initParse(&p, gDb);168 169  NameContext nc;170  memset(&nc, 0, sizeof(nc));171  nc.pParse = &p;172  nc.ncFlags = NC_OrderAgg;  /* Pretend we enter with this flag already set */173 174  u16 initial = nc.ncFlags;175 176  Expr *pSum = makeFunc1(&p, "sum", "1");177  ExprList *pList = listAppend(&p, NULL, pSum);178 179  int rc = sqlite3ResolveExprListNames(&nc, pList);180  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);181 182  /* Should keep NC_OrderAgg and also set NC_HasAgg due to sum() */183  TEST_ASSERT_NOT_EQUAL(0, (nc.ncFlags & NC_OrderAgg));184  TEST_ASSERT_NOT_EQUAL(0, (nc.ncFlags & NC_HasAgg));185  /* Initial must still be present */186  TEST_ASSERT_EQUAL_UINT16(NC_OrderAgg, (nc.ncFlags & NC_OrderAgg));187 188  sqlite3ExprListDelete(p.db, pList);189}190 191/* Test: NULL entry in list is skipped and does not crash; non-NULL still processed */192void test_sqlite3ResolveExprListNames_skips_null_entries(void){193  Parse p;194  initParse(&p, gDb);195 196  NameContext nc;197  memset(&nc, 0, sizeof(nc));198  nc.pParse = &p;199 200  Expr *pOne = makeIntLiteral(&p, "1");201  Expr *pCnt = makeFunc1(&p, "count", "1");202  ExprList *pList = NULL;203  pList = listAppend(&p, pList, pOne);204  pList = listAppend(&p, pList, pCnt);205 206  /* Manually null-out first expression to exercise skip path */207  pList->a[0].pExpr = NULL;208 209  int rc = sqlite3ResolveExprListNames(&nc, pList);210  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);211 212  /* The second expression should still be marked as aggregate */213  Expr *pExpr1 = pList->a[1].pExpr;214  TEST_ASSERT_NOT_NULL(pExpr1);215  TEST_ASSERT_NOT_EQUAL(0, (pExpr1->flags & EP_Agg));216  TEST_ASSERT_NOT_EQUAL(0, (nc.ncFlags & NC_HasAgg));217 218  sqlite3ExprListDelete(p.db, pList);219}220 221/* Test: if pParse->nErr > 0, function returns SQLITE_ERROR */222void test_sqlite3ResolveExprListNames_returns_error_on_parse_error(void){223  Parse p;224  initParse(&p, gDb);225 226  NameContext nc;227  memset(&nc, 0, sizeof(nc));228  nc.pParse = &p;229 230  Expr *pOne = makeIntLiteral(&p, "1");231  ExprList *pList = listAppend(&p, NULL, pOne);232 233  p.nErr = 1;  /* Simulate prior parse/resolve error */234 235  int rc = sqlite3ResolveExprListNames(&nc, pList);236  TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);237 238  /* Cleanup */239  sqlite3ExprListDelete(p.db, pList);240}241 242int main(void){243  UNITY_BEGIN();244  RUN_TEST(test_sqlite3ResolveExprListNames_null_list);245  RUN_TEST(test_sqlite3ResolveExprListNames_plain_literal);246  RUN_TEST(test_sqlite3ResolveExprListNames_simple_agg_count);247  RUN_TEST(test_sqlite3ResolveExprListNames_two_exprs_savedHasAgg);248  RUN_TEST(test_sqlite3ResolveExprListNames_minmax_flags);249  RUN_TEST(test_sqlite3ResolveExprListNames_preserves_initial_flags);250  RUN_TEST(test_sqlite3ResolveExprListNames_skips_null_entries);251  RUN_TEST(test_sqlite3ResolveExprListNames_returns_error_on_parse_error);252  return UNITY_END();253}