Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_expr_sqlite3ExprAssignVarNumber.c219 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdio.h>5#include <stdlib.h>6 7/* Globals used by tests */8static sqlite3 *gDb = NULL;9static Parse gParse;10 11/* Helper: allocate an Expr for a variable token using the connection allocator */12static Expr* newVarExpr(const char *zToken){13  Expr *p = (Expr*)sqlite3DbMallocZero(gDb, sizeof(Expr));14  TEST_ASSERT_NOT_NULL_MESSAGE(p, "Failed to allocate Expr");15  p->u.zToken = sqlite3DbStrDup(gDb, zToken);16  TEST_ASSERT_NOT_NULL_MESSAGE(p->u.zToken, "Failed to allocate token string");17  p->op = TK_VARIABLE;       /* Reasonable op for variable tokens */18  p->flags = 0;              /* Ensure not EP_IntValue/EP_Reduced/EP_TokenOnly */19  p->iColumn = 0;20  return p;21}22 23static void freeExpr(Expr *p){24  if( p ){25    if( p->u.zToken ){26      sqlite3DbFree(gDb, (void*)p->u.zToken);27      p->u.zToken = 0;28    }29    sqlite3DbFree(gDb, p);30  }31}32 33static void clearParseError(Parse *pParse){34  if( pParse->zErrMsg ){35    sqlite3DbFree(pParse->db, pParse->zErrMsg);36    pParse->zErrMsg = 0;37  }38}39 40/* Unity setup/teardown */41void setUp(void) {42  int rc = sqlite3_open(":memory:", &gDb);43  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "Failed to open in-memory SQLite DB");44  memset(&gParse, 0, sizeof(gParse));45  gParse.db = gDb;46}47 48void tearDown(void) {49  /* Free Parse-owned allocations we might have produced */50  clearParseError(&gParse);51  if( gParse.pVList ){52    sqlite3DbFree(gDb, gParse.pVList);53    gParse.pVList = 0;54  }55  if( gDb ){56    sqlite3_close(gDb);57    gDb = NULL;58  }59}60 61/* Tests */62 63void test_sqlite3ExprAssignVarNumber_qmark_sequence(void){64  /* First "?" -> var 1 */65  Expr *e1 = newVarExpr("?");66  u32 n1 = (u32)strlen(e1->u.zToken);67  sqlite3ExprAssignVarNumber(&gParse, e1, n1);68  TEST_ASSERT_EQUAL_INT(1, e1->iColumn);69  TEST_ASSERT_EQUAL_INT(1, gParse.nVar);70  TEST_ASSERT_NULL(gParse.pVList);71  TEST_ASSERT_NULL(gParse.zErrMsg);72  freeExpr(e1);73 74  /* Second "?" -> var 2 */75  Expr *e2 = newVarExpr("?");76  u32 n2 = (u32)strlen(e2->u.zToken);77  sqlite3ExprAssignVarNumber(&gParse, e2, n2);78  TEST_ASSERT_EQUAL_INT(2, e2->iColumn);79  TEST_ASSERT_EQUAL_INT(2, gParse.nVar);80  TEST_ASSERT_NULL(gParse.pVList);81  TEST_ASSERT_NULL(gParse.zErrMsg);82  freeExpr(e2);83}84 85void test_sqlite3ExprAssignVarNumber_qnnn_adds_and_mapping(void){86  /* "?3" when nVar==0 should set nVar=3 and add mapping for #3 */87  Expr *e = newVarExpr("?3");88  u32 n = (u32)strlen(e->u.zToken);89 90  sqlite3ExprAssignVarNumber(&gParse, e, n);91  TEST_ASSERT_EQUAL_INT(3, e->iColumn);92  TEST_ASSERT_EQUAL_INT(3, gParse.nVar);93  TEST_ASSERT_NOT_NULL(gParse.pVList);94  const char *z = sqlite3VListNumToName(gParse.pVList, 3);95  TEST_ASSERT_NOT_NULL(z);96  TEST_ASSERT_NULL(gParse.zErrMsg);97  freeExpr(e);98}99 100void test_sqlite3ExprAssignVarNumber_qnnn_lower_than_nVar_adds_missing_mapping(void){101  /* First create mapping for ?3 */102  Expr *e3 = newVarExpr("?3");103  u32 n3 = (u32)strlen(e3->u.zToken);104  sqlite3ExprAssignVarNumber(&gParse, e3, n3);105  TEST_ASSERT_EQUAL_INT(3, gParse.nVar);106  TEST_ASSERT_NOT_NULL(gParse.pVList);107  TEST_ASSERT_NOT_NULL(sqlite3VListNumToName(gParse.pVList, 3));108  freeExpr(e3);109 110  /* Now "?2" should not change nVar but should add mapping for #2 if missing */111  Expr *e2 = newVarExpr("?2");112  u32 n2 = (u32)strlen(e2->u.zToken);113  sqlite3ExprAssignVarNumber(&gParse, e2, n2);114  TEST_ASSERT_EQUAL_INT(2, e2->iColumn);115  TEST_ASSERT_EQUAL_INT(3, gParse.nVar);116  TEST_ASSERT_NOT_NULL(gParse.pVList);117  TEST_ASSERT_NOT_NULL(sqlite3VListNumToName(gParse.pVList, 2));118  TEST_ASSERT_NULL(gParse.zErrMsg);119  freeExpr(e2);120}121 122void test_sqlite3ExprAssignVarNumber_named_reuse_and_prefix_sensitivity(void){123  /* First occurrence of ":abc" -> var 1 */124  Expr *e1 = newVarExpr(":abc");125  u32 n1 = (u32)strlen(e1->u.zToken);126  sqlite3ExprAssignVarNumber(&gParse, e1, n1);127  TEST_ASSERT_EQUAL_INT(1, e1->iColumn);128  TEST_ASSERT_EQUAL_INT(1, gParse.nVar);129  TEST_ASSERT_NOT_NULL(gParse.pVList);130  TEST_ASSERT_EQUAL_INT(1, sqlite3VListNameToNum(gParse.pVList, ":abc", (int)n1));131  freeExpr(e1);132 133  /* Second occurrence of ":abc" -> reuse var 1, nVar unchanged */134  Expr *e2 = newVarExpr(":abc");135  u32 n2 = (u32)strlen(e2->u.zToken);136  sqlite3ExprAssignVarNumber(&gParse, e2, n2);137  TEST_ASSERT_EQUAL_INT(1, e2->iColumn);138  TEST_ASSERT_EQUAL_INT(1, gParse.nVar);139  TEST_ASSERT_EQUAL_INT(1, sqlite3VListNameToNum(gParse.pVList, ":abc", (int)n2));140  freeExpr(e2);141 142  /* Different prefix "$abc" -> different variable number (2) */143  Expr *e3 = newVarExpr("$abc");144  u32 n3 = (u32)strlen(e3->u.zToken);145  sqlite3ExprAssignVarNumber(&gParse, e3, n3);146  TEST_ASSERT_EQUAL_INT(2, e3->iColumn);147  TEST_ASSERT_EQUAL_INT(2, gParse.nVar);148  TEST_ASSERT_EQUAL_INT(2, sqlite3VListNameToNum(gParse.pVList, "$abc", (int)n3));149  freeExpr(e3);150 151  TEST_ASSERT_NULL(gParse.zErrMsg);152}153 154void test_sqlite3ExprAssignVarNumber_qnnn_invalid_zero_sets_error_and_no_change(void){155  int prevNVar = gParse.nVar;156  Expr *e = newVarExpr("?0");157  u32 n = (u32)strlen(e->u.zToken);158 159  sqlite3ExprAssignVarNumber(&gParse, e, n);160 161  TEST_ASSERT_EQUAL_INT(prevNVar, gParse.nVar);162  TEST_ASSERT_EQUAL_INT(0, e->iColumn); /* Not assigned on error */163  TEST_ASSERT_NOT_NULL(gParse.zErrMsg);164  TEST_ASSERT_NOT_EQUAL(0, (int)(strstr(gParse.zErrMsg, "variable number must be between") != NULL));165  freeExpr(e);166  clearParseError(&gParse);167}168 169void test_sqlite3ExprAssignVarNumber_qnnn_over_limit_sets_error_and_no_change(void){170  int limit = sqlite3_limit(gDb, SQLITE_LIMIT_VARIABLE_NUMBER, -1);171  int prevNVar = gParse.nVar;172 173  char *dyn = sqlite3_mprintf("?%d", limit+1);174  TEST_ASSERT_NOT_NULL(dyn);175  Expr *e = newVarExpr(dyn); /* duplicate into db memory */176  sqlite3_free(dyn);177 178  u32 n = (u32)strlen(e->u.zToken);179  sqlite3ExprAssignVarNumber(&gParse, e, n);180 181  TEST_ASSERT_EQUAL_INT(prevNVar, gParse.nVar);182  TEST_ASSERT_EQUAL_INT(0, e->iColumn); /* Not assigned on early-return error */183  TEST_ASSERT_NOT_NULL(gParse.zErrMsg);184  TEST_ASSERT_NOT_EQUAL(0, (int)(strstr(gParse.zErrMsg, "variable number must be between") != NULL));185  freeExpr(e);186  clearParseError(&gParse);187}188 189void test_sqlite3ExprAssignVarNumber_too_many_sql_variables_sequential_qmark(void){190  int limit = sqlite3_limit(gDb, SQLITE_LIMIT_VARIABLE_NUMBER, -1);191 192  /* Force nVar to the limit, then assign one more "?" */193  gParse.nVar = limit;194 195  Expr *e = newVarExpr("?");196  u32 n = (u32)strlen(e->u.zToken);197  sqlite3ExprAssignVarNumber(&gParse, e, n);198 199  TEST_ASSERT_EQUAL_INT(limit+1, e->iColumn);200  TEST_ASSERT_EQUAL_INT(limit+1, gParse.nVar);201  TEST_ASSERT_NOT_NULL(gParse.zErrMsg);202  TEST_ASSERT_NOT_EQUAL(0, (int)(strstr(gParse.zErrMsg, "too many SQL variables") != NULL));203 204  freeExpr(e);205  clearParseError(&gParse);206}207 208/* Main */209int main(void){210  UNITY_BEGIN();211  RUN_TEST(test_sqlite3ExprAssignVarNumber_qmark_sequence);212  RUN_TEST(test_sqlite3ExprAssignVarNumber_qnnn_adds_and_mapping);213  RUN_TEST(test_sqlite3ExprAssignVarNumber_qnnn_lower_than_nVar_adds_missing_mapping);214  RUN_TEST(test_sqlite3ExprAssignVarNumber_named_reuse_and_prefix_sensitivity);215  RUN_TEST(test_sqlite3ExprAssignVarNumber_qnnn_invalid_zero_sets_error_and_no_change);216  RUN_TEST(test_sqlite3ExprAssignVarNumber_qnnn_over_limit_sets_error_and_no_change);217  RUN_TEST(test_sqlite3ExprAssignVarNumber_too_many_sql_variables_sequential_qmark);218  return UNITY_END();219}