Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_resolve_sqlite3ResolveExprNames.c178 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Unity setUp/tearDown */7void setUp(void) {8  /* Setup code here, or leave empty */9}10void tearDown(void) {11  /* Cleanup code here, or leave empty */12}13 14/* Helper: Create a Parse with an open in-memory DB. Returns 0 on success. */15static int open_db_and_init_parse(sqlite3 **ppDb, Parse *pParse){16  sqlite3 *db = 0;17  int rc = sqlite3_open(":memory:", &db);18  if( rc!=SQLITE_OK ){19    return rc;20  }21  memset(pParse, 0, sizeof(Parse));22  pParse->db = db;23  *ppDb = db;24  return SQLITE_OK;25}26 27/* Helper: Create a simple TK_NULL expression */28static Expr* make_null_expr(sqlite3 *db){29  return sqlite3ExprAlloc(db, TK_NULL, 0, 0);30}31 32/* Helper: Create a TK_INTEGER expression from a literal "1" */33static Expr* make_int1_expr(sqlite3 *db){34  static const char oneStr[] = "1";35  Token tOne;36  tOne.z = (char*)oneStr;37  tOne.n = (int)strlen(oneStr);38  return sqlite3ExprAlloc(db, TK_INTEGER, &tOne, 0);39}40 41/* Helper: Create an aggregate function expression COUNT(1) */42static Expr* make_count1_expr(Parse *pParse){43  sqlite3 *db = pParse->db;44 45  /* Build argument list: (1) */46  Expr *arg = make_int1_expr(db);47  if( arg==0 ) return 0;48 49  ExprList *pList = sqlite3ExprListAppend(pParse, 0, arg);50  if( pList==0 ){51    sqlite3ExprDelete(db, arg);52    return 0;53  }54 55  /* Build function token: "count" */56  static const char cntStr[] = "count";57  Token tFunc;58  tFunc.z = (char*)cntStr;59  tFunc.n = (int)strlen(cntStr);60 61  /* Allocate the function Expr node with TK_FUNCTION and attach the arg list */62  Expr *pFunc = sqlite3ExprAlloc(db, TK_FUNCTION, &tFunc, 0);63  if( pFunc==0 ){64    sqlite3ExprListDelete(db, pList);65    return 0;66  }67  pFunc->x.pList = pList;68 69  return pFunc;70}71 72/* Test 1: NULL expression returns SQLITE_OK and preserves NameContext flags */73void test_sqlite3ResolveExprNames_null_expr_returns_ok_and_preserves_flags(void){74  sqlite3 *db = 0;75  Parse parse;76  int rc;77 78  rc = open_db_and_init_parse(&db, &parse);79  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);80 81  NameContext nc;82  memset(&nc, 0, sizeof(nc));83  nc.pParse = &parse;84 85  /* Seed ncFlags with the flags that the function saves/restores */86  nc.ncFlags = NC_HasAgg | NC_MinMaxAgg | NC_HasWin | NC_OrderAgg;87 88  rc = sqlite3ResolveExprNames(&nc, 0);89  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);90 91  /* Ensure flags are preserved */92  TEST_ASSERT_TRUE((nc.ncFlags & NC_HasAgg) != 0);93  TEST_ASSERT_TRUE((nc.ncFlags & NC_MinMaxAgg) != 0);94  TEST_ASSERT_TRUE((nc.ncFlags & NC_HasWin) != 0);95  TEST_ASSERT_TRUE((nc.ncFlags & NC_OrderAgg) != 0);96 97  sqlite3_close(db);98}99 100/* Test 2: Simple literal expression (TK_NULL) does not set EP_Agg or EP_Win on the expr.101           Pre-existing NC flags are preserved on NameContext but not propagated to expr. */102void test_sqlite3ResolveExprNames_literal_expr_no_agg_no_win_sets_no_flags(void){103  sqlite3 *db = 0;104  Parse parse;105  int rc;106 107  rc = open_db_and_init_parse(&db, &parse);108  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);109 110  Expr *pExpr = make_null_expr(db);111  TEST_ASSERT_NOT_NULL(pExpr);112 113  NameContext nc;114  memset(&nc, 0, sizeof(nc));115  nc.pParse = &parse;116 117  /* Pre-set NC_HasAgg and NC_HasWin to ensure they are not copied to Expr flags */118  nc.ncFlags = NC_HasAgg | NC_HasWin | NC_MinMaxAgg | NC_OrderAgg;119 120  rc = sqlite3ResolveExprNames(&nc, pExpr);121  TEST_ASSERT_EQUAL_INT(0, rc); /* 0 means no errors */122 123  /* The expression should not have aggregate or window properties set */124  TEST_ASSERT_EQUAL_INT(0, (pExpr->flags & EP_Agg));125  TEST_ASSERT_EQUAL_INT(0, (pExpr->flags & EP_Win));126 127  /* NameContext flags should still include the pre-existing ones */128  TEST_ASSERT_TRUE((nc.ncFlags & NC_HasAgg) != 0);129  TEST_ASSERT_TRUE((nc.ncFlags & NC_HasWin) != 0);130  TEST_ASSERT_TRUE((nc.ncFlags & NC_MinMaxAgg) != 0);131  TEST_ASSERT_TRUE((nc.ncFlags & NC_OrderAgg) != 0);132 133  sqlite3ExprDelete(db, pExpr);134  sqlite3_close(db);135}136 137/* Test 3: Aggregate function COUNT(1) sets NC_HasAgg and EP_Agg on the root expression */138void test_sqlite3ResolveExprNames_aggregate_function_sets_flags(void){139  sqlite3 *db = 0;140  Parse parse;141  int rc;142 143  rc = open_db_and_init_parse(&db, &parse);144  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);145 146  Expr *pFunc = make_count1_expr(&parse);147  TEST_ASSERT_NOT_NULL(pFunc);148 149  NameContext nc;150  memset(&nc, 0, sizeof(nc));151  nc.pParse = &parse;152 153  /* Allow aggregates in this context */154  nc.ncFlags = NC_AllowAgg;155 156  rc = sqlite3ResolveExprNames(&nc, pFunc);157  TEST_ASSERT_EQUAL_INT(0, rc); /* success (no errors) */158 159  /* The NameContext should indicate an aggregate was encountered */160  TEST_ASSERT_TRUE((nc.ncFlags & NC_HasAgg) != 0);161 162  /* The root expression should be marked as aggregate */163  TEST_ASSERT_TRUE((pFunc->flags & EP_Agg) != 0);164 165  /* It should not be marked as a window function just from COUNT(1) */166  TEST_ASSERT_EQUAL_INT(0, (pFunc->flags & EP_Win));167 168  sqlite3ExprDelete(db, pFunc);169  sqlite3_close(db);170}171 172int main(void) {173  UNITY_BEGIN();174  RUN_TEST(test_sqlite3ResolveExprNames_null_expr_returns_ok_and_preserves_flags);175  RUN_TEST(test_sqlite3ResolveExprNames_literal_expr_no_agg_no_win_sets_no_flags);176  RUN_TEST(test_sqlite3ResolveExprNames_aggregate_function_sets_flags);177  return UNITY_END();178}