Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_expr_exprCompareVariable.c237 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6extern int test_exprCompareVariable(const Parse *pParse, const Expr *pVar, const Expr *pExpr);7 8static Expr *makeVarExpr(sqlite3 *db, int iVar){9  Expr *e = (Expr*)sqlite3DbMallocZero(db, sizeof(Expr));10  TEST_ASSERT_NOT_NULL_MESSAGE(e, "Failed to allocate Expr for variable");11  e->op = TK_VARIABLE;12  e->iColumn = iVar; /* Variable index is stored in iColumn for TK_VARIABLE */13  return e;14}15 16static Expr *makeIntExpr(sqlite3 *db, const char *zNum){17  Expr *e = (Expr*)sqlite3DbMallocZero(db, sizeof(Expr));18  TEST_ASSERT_NOT_NULL_MESSAGE(e, "Failed to allocate Expr for integer");19  e->op = TK_INTEGER;20  e->u.zToken = sqlite3DbStrDup(db, zNum);21  TEST_ASSERT_NOT_NULL_MESSAGE(e->u.zToken, "Failed to allocate zToken for integer");22  return e;23}24 25static Expr *makeTextExpr(sqlite3 *db, const char *zText){26  Expr *e = (Expr*)sqlite3DbMallocZero(db, sizeof(Expr));27  TEST_ASSERT_NOT_NULL_MESSAGE(e, "Failed to allocate Expr for string");28  e->op = TK_STRING;29  e->u.zToken = sqlite3DbStrDup(db, zText);30  TEST_ASSERT_NOT_NULL_MESSAGE(e->u.zToken, "Failed to allocate zToken for string");31  return e;32}33 34static void freeExpr(sqlite3 *db, Expr *e){35  if( !e ) return;36  if( (e->op==TK_INTEGER || e->op==TK_STRING || e->op==TK_FLOAT || e->op==TK_BLOB) && e->u.zToken ){37    sqlite3DbFree(db, e->u.zToken);38  }39  sqlite3DbFree(db, e);40}41 42void setUp(void) {43  /* No global setup */44}45void tearDown(void) {46  /* No global teardown */47}48 49/* Test: early return when pExpr is the same variable as pVar */50void test_exprCompareVariable_same_variable_returns_0(void){51  Parse p;52  memset(&p, 0, sizeof(p));53  /* p.db not needed due to early return path */54  /* Create variable expressions */55  sqlite3 *db;56  TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));57  Expr *pVar = makeVarExpr(db, 1);58  Expr *pExpr = makeVarExpr(db, 1);59 60  int rc = test_exprCompareVariable(&p, pVar, pExpr);61  TEST_ASSERT_EQUAL_INT(0, rc);62 63  freeExpr(db, pVar);64  freeExpr(db, pExpr);65  sqlite3_close(db);66}67 68/* Test: SQLITE_EnableQPSG flag forces return 2 regardless of expression */69void test_exprCompareVariable_qpsg_flag_forces_2(void){70  sqlite3 *db = 0;71  TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));72  Parse p;73  memset(&p, 0, sizeof(p));74  p.db = db;75 76  /* Set the flag */77  db->flags |= SQLITE_EnableQPSG;78 79  Expr *pVar = makeVarExpr(db, 1);80  Expr *pExpr = makeIntExpr(db, "5"); /* simple constant */81 82  int rc = test_exprCompareVariable(&p, pVar, pExpr);83  TEST_ASSERT_EQUAL_INT(2, rc);84 85  /* Cleanup */86  db->flags &= ~SQLITE_EnableQPSG;87  freeExpr(db, pVar);88  freeExpr(db, pExpr);89  sqlite3_close(db);90}91 92/* Helper to initialize Parse with pVdbe and a pReprepare statement "SELECT ?1" */93static void initParseWithReprepare(sqlite3 **pDbOut, Parse *pOut, sqlite3_stmt **pStmtOut){94  sqlite3 *db = 0;95  TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));96  memset(pOut, 0, sizeof(*pOut));97  pOut->db = db;98 99  /* Create a VDBE for pVdbe (needed for sqlite3VdbeSetVarmask) */100  Vdbe *pv = sqlite3VdbeCreate(pOut);101  TEST_ASSERT_NOT_NULL_MESSAGE(pv, "sqlite3VdbeCreate failed");102  pOut->pVdbe = pv;103 104  /* Prepare a statement with 1 parameter; this will be used as pReprepare */105  sqlite3_stmt *stmt = 0;106  TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_prepare_v2(db, "SELECT ?1", -1, &stmt, 0));107  TEST_ASSERT_NOT_NULL_MESSAGE(stmt, "prepare failed");108  pOut->pReprepare = (Vdbe*)stmt;109 110  *pDbOut = db;111  *pStmtOut = stmt;112}113 114/* Test: simple integer constant equal to bound value returns 0 */115void test_exprCompareVariable_equal_integer_constant_returns_0(void){116  sqlite3 *db = 0;117  Parse p;118  sqlite3_stmt *stmt = 0;119  initParseWithReprepare(&db, &p, &stmt);120 121  /* Bind variable ?1 = 55 */122  TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_bind_int(stmt, 1, 55));123 124  Expr *pVar = makeVarExpr(db, 1);125  Expr *pExpr = makeIntExpr(db, "55");126 127  int rc = test_exprCompareVariable(&p, pVar, pExpr);128  TEST_ASSERT_EQUAL_INT(0, rc);129 130  /* Cleanup */131  freeExpr(db, pVar);132  freeExpr(db, pExpr);133  sqlite3_finalize(stmt);134  sqlite3VdbeDelete(p.pVdbe);135  sqlite3_close(db);136}137 138/* Test: simple integer constant different from bound value returns 2 */139void test_exprCompareVariable_unequal_integer_constant_returns_2(void){140  sqlite3 *db = 0;141  Parse p;142  sqlite3_stmt *stmt = 0;143  initParseWithReprepare(&db, &p, &stmt);144 145  TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_bind_int(stmt, 1, 99));146 147  Expr *pVar = makeVarExpr(db, 1);148  Expr *pExpr = makeIntExpr(db, "55");149 150  int rc = test_exprCompareVariable(&p, pVar, pExpr);151  TEST_ASSERT_EQUAL_INT(2, rc);152 153  /* Cleanup */154  freeExpr(db, pVar);155  freeExpr(db, pExpr);156  sqlite3_finalize(stmt);157  sqlite3VdbeDelete(p.pVdbe);158  sqlite3_close(db);159}160 161/* Test: when variable is unbound (no bind), result should be 2 */162void test_exprCompareVariable_unbound_variable_returns_2(void){163  sqlite3 *db = 0;164  Parse p;165  sqlite3_stmt *stmt = 0;166  initParseWithReprepare(&db, &p, &stmt);167 168  /* No bind for ?1 */169 170  Expr *pVar = makeVarExpr(db, 1);171  Expr *pExpr = makeIntExpr(db, "123");172 173  int rc = test_exprCompareVariable(&p, pVar, pExpr);174  TEST_ASSERT_EQUAL_INT(2, rc);175 176  /* Cleanup */177  freeExpr(db, pVar);178  freeExpr(db, pExpr);179  sqlite3_finalize(stmt);180  sqlite3VdbeDelete(p.pVdbe);181  sqlite3_close(db);182}183 184/* Test: simple text constant equal to bound text returns 0 */185void test_exprCompareVariable_equal_text_constant_returns_0(void){186  sqlite3 *db = 0;187  Parse p;188  sqlite3_stmt *stmt = 0;189  initParseWithReprepare(&db, &p, &stmt);190 191  const char *txt = "hello";192  TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_bind_text(stmt, 1, txt, -1, SQLITE_TRANSIENT));193 194  Expr *pVar = makeVarExpr(db, 1);195  Expr *pExpr = makeTextExpr(db, txt);196 197  int rc = test_exprCompareVariable(&p, pVar, pExpr);198  TEST_ASSERT_EQUAL_INT(0, rc);199 200  /* Cleanup */201  freeExpr(db, pVar);202  freeExpr(db, pExpr);203  sqlite3_finalize(stmt);204  sqlite3VdbeDelete(p.pVdbe);205  sqlite3_close(db);206}207 208/* Test: pExpr is a different variable (?2) - not a simple constant, returns 2 */209void test_exprCompareVariable_expr_is_different_variable_returns_2(void){210  sqlite3 *db = 0;211  TEST_ASSERT_EQUAL(SQLITE_OK, sqlite3_open(":memory:", &db));212  Parse p;213  memset(&p, 0, sizeof(p));214  p.db = db;215 216  Expr *pVar = makeVarExpr(db, 1);   /* ?1 */217  Expr *pExpr = makeVarExpr(db, 2);  /* ?2 */218 219  int rc = test_exprCompareVariable(&p, pVar, pExpr);220  TEST_ASSERT_EQUAL_INT(2, rc);221 222  freeExpr(db, pVar);223  freeExpr(db, pExpr);224  sqlite3_close(db);225}226 227int main(void){228  UNITY_BEGIN();229  RUN_TEST(test_exprCompareVariable_same_variable_returns_0);230  RUN_TEST(test_exprCompareVariable_qpsg_flag_forces_2);231  RUN_TEST(test_exprCompareVariable_equal_integer_constant_returns_0);232  RUN_TEST(test_exprCompareVariable_unequal_integer_constant_returns_2);233  RUN_TEST(test_exprCompareVariable_unbound_variable_returns_2);234  RUN_TEST(test_exprCompareVariable_equal_text_constant_returns_0);235  RUN_TEST(test_exprCompareVariable_expr_is_different_variable_returns_2);236  return UNITY_END();237}