Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_expr_sqlite3ExprCodeTemp.c136 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Helper: create a Parse with an associated Vdbe */7static void initParse(sqlite3 **ppDb, Parse *pParse, int okConstFactor){8  int rc = sqlite3_open(":memory:", ppDb);9  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed");10  memset(pParse, 0, sizeof(*pParse));11  pParse->db = *ppDb;12  pParse->pVdbe = sqlite3VdbeCreate(*ppDb);13  TEST_ASSERT_NOT_NULL_MESSAGE(pParse->pVdbe, "sqlite3VdbeCreate returned NULL");14  pParse->okConstFactor = (u8)okConstFactor;15}16 17/* Helper: cleanup Parse and db */18static void cleanupParse(sqlite3 *db, Parse *pParse){19  if( pParse->pConstExpr ){20    sqlite3ExprListDelete(db, pParse->pConstExpr);21    pParse->pConstExpr = 0;22  }23  if( pParse->pVdbe ){24    sqlite3VdbeDelete(pParse->pVdbe);25    pParse->pVdbe = 0;26  }27  if( db ){28    sqlite3_close(db);29  }30}31 32/* Helper: build a TK_INTEGER Expr using sqlite3ExprAlloc */33static Expr* makeIntExpr(sqlite3 *db, const char *zNum){34  Token t;35  memset(&t, 0, sizeof(t));36  t.z = zNum;37  t.n = (int)strlen(zNum);38  return sqlite3ExprAlloc(db, TK_INTEGER, &t, 0);39}40 41void setUp(void) {42  /* No global setup required */43}44 45void tearDown(void) {46  /* No global teardown required */47}48 49/* Test 1: Constant factoring enabled, constant integer expression.50   Expect: *pReg==0 and result register is reused across calls. */51void test_sqlite3ExprCodeTemp_constant_factoring_reuse(void){52  sqlite3 *db = 0;53  Parse parse;54  initParse(&db, &parse, 1);55 56  Expr *pExpr = makeIntExpr(db, "42");57  TEST_ASSERT_NOT_NULL(pExpr);58 59  int regOut1 = -999;60  int r1 = sqlite3ExprCodeTemp(&parse, pExpr, &regOut1);61  TEST_ASSERT_GREATER_THAN_INT(0, 0); /* keep Unity happy about type promotion */62  TEST_ASSERT_TRUE_MESSAGE(r1 > 0, "Returned register should be > 0");63  TEST_ASSERT_EQUAL_INT_MESSAGE(0, regOut1, "*pReg should be 0 for factored constants");64 65  /* Second call with the same expression should reuse the same register */66  int regOut2 = -999;67  int r2 = sqlite3ExprCodeTemp(&parse, pExpr, &regOut2);68  TEST_ASSERT_EQUAL_INT_MESSAGE(0, regOut2, "*pReg should be 0 for factored constants (2nd call)");69  TEST_ASSERT_EQUAL_INT_MESSAGE(r1, r2, "Constant factoring should reuse the same register");70 71  sqlite3ExprDelete(db, pExpr);72  cleanupParse(db, &parse);73}74 75/* Test 2: Constant factoring disabled, constant integer expression.76   Expect: temp register allocated and returned, *pReg equals the returned reg. */77void test_sqlite3ExprCodeTemp_no_const_factor_temp_reg_returned(void){78  sqlite3 *db = 0;79  Parse parse;80  initParse(&db, &parse, 0); /* okConstFactor = 0 */81 82  Expr *pExpr = makeIntExpr(db, "7");83  TEST_ASSERT_NOT_NULL(pExpr);84 85  int tempReg = 0;86  int r = sqlite3ExprCodeTemp(&parse, pExpr, &tempReg);87  TEST_ASSERT_TRUE_MESSAGE(r > 0, "Returned register should be > 0");88  TEST_ASSERT_EQUAL_INT_MESSAGE(r, tempReg, "When not factored, *pReg should be the temp register used");89  TEST_ASSERT_NULL_MESSAGE(parse.pConstExpr, "pConstExpr list should remain NULL when factoring is disabled");90 91  sqlite3ExprDelete(db, pExpr);92  cleanupParse(db, &parse);93}94 95/* Test 3: NULL expression pointer. Expect: handled as TK_NULL, temp reg used and returned; *pReg equals returned reg. */96void test_sqlite3ExprCodeTemp_null_expr(void){97  sqlite3 *db = 0;98  Parse parse;99  initParse(&db, &parse, 1); /* factoring setting shouldn't matter for NULL */100 101  int tempReg = 0;102  int r = sqlite3ExprCodeTemp(&parse, NULL, &tempReg);103  TEST_ASSERT_TRUE_MESSAGE(r > 0, "Returned register should be > 0 for NULL expr");104  TEST_ASSERT_EQUAL_INT_MESSAGE(r, tempReg, "*pReg should equal the temp register for NULL expr");105 106  cleanupParse(db, &parse);107}108 109/* Test 4: TK_REGISTER expression returns a different register than the temp target.110   Expect: sqlite3ExprCodeTemp releases the temp and sets *pReg==0. */111void test_sqlite3ExprCodeTemp_register_expr_returns_non_target_register(void){112  sqlite3 *db = 0;113  Parse parse;114  initParse(&db, &parse, 1);115 116  Expr e;117  memset(&e, 0, sizeof(e));118  e.op = TK_REGISTER;119  e.iTable = 123; /* Force a register different from the temp one */120 121  int outReg = -1;122  int r = sqlite3ExprCodeTemp(&parse, &e, &outReg);123  TEST_ASSERT_EQUAL_INT_MESSAGE(123, r, "Expected sqlite3ExprCodeTarget to return Expr.iTable for TK_REGISTER");124  TEST_ASSERT_EQUAL_INT_MESSAGE(0, outReg, "*pReg should be 0 when result is not stored in the temp target");125 126  cleanupParse(db, &parse);127}128 129int main(void){130  UNITY_BEGIN();131  RUN_TEST(test_sqlite3ExprCodeTemp_constant_factoring_reuse);132  RUN_TEST(test_sqlite3ExprCodeTemp_no_const_factor_temp_reg_returned);133  RUN_TEST(test_sqlite3ExprCodeTemp_null_expr);134  RUN_TEST(test_sqlite3ExprCodeTemp_register_expr_returns_non_target_register);135  return UNITY_END();136}