Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_expr_sqlite3ExprCode.c156 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include "vdbeInt.h"4#include <string.h>5 6/* Globals for each test */7static sqlite3 *gDb = NULL;8static Parse gParse;9static Vdbe *gVdbe = NULL;10 11/* Helper: get last opcode, or NULL if none */12static Op* getLastOp(void){13  int n = sqlite3VdbeCurrentAddr(gVdbe);14  if( n<=0 ) return NULL;15  return sqlite3VdbeGetOp(gVdbe, n-1);16}17 18void setUp(void) {19  int rc = sqlite3_open(":memory:", &gDb);20  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);21  memset(&gParse, 0, sizeof(gParse));22  gParse.db = gDb;23  gVdbe = sqlite3VdbeCreate(gDb);24  TEST_ASSERT_NOT_NULL(gVdbe);25  gParse.pVdbe = gVdbe;26  gParse.nMem = 100;   /* plenty of registers for tests */27  gParse.iSelfTab = 0; /* default, overridden in specific tests as needed */28}29 30void tearDown(void) {31  if( gVdbe ){32    sqlite3VdbeDelete(gVdbe);33    gVdbe = NULL;34  }35  if( gDb ){36    sqlite3_close(gDb);37    gDb = NULL;38  }39}40 41/* Test: pExpr==NULL results in OP_Null to target */42void test_sqlite3ExprCode_null_expr_emits_OP_Null(void){43  int target = 5;44  sqlite3ExprCode(&gParse, NULL, target);45 46  int nOp = sqlite3VdbeCurrentAddr(gVdbe);47  TEST_ASSERT_EQUAL_INT(1, nOp);48 49  Op *pOp = getLastOp();50  TEST_ASSERT_NOT_NULL(pOp);51  TEST_ASSERT_EQUAL_INT(OP_Null, pOp->opcode);52  /* sqlite3VdbeAddOp2(OP_Null, 0, target) -> p2 is the target */53  TEST_ASSERT_EQUAL_INT(target, pOp->p2);54}55 56/* Test: TK_INTEGER emits OP_Integer directly to target and no copy */57void test_sqlite3ExprCode_TK_INTEGER_no_copy(void){58  int target = 10;59  Expr *p = (Expr*)sqlite3DbMallocZero(gDb, sizeof(Expr));60  TEST_ASSERT_NOT_NULL(p);61  p->op = TK_INTEGER;62  /* Use an inline integer value */63  p->flags = EP_IntValue | EP_TokenOnly;64  p->u.iValue = 12345;65 66  sqlite3ExprCode(&gParse, p, target);67 68  int nOp = sqlite3VdbeCurrentAddr(gVdbe);69  TEST_ASSERT_EQUAL_INT(1, nOp);70 71  Op *pOp = getLastOp();72  TEST_ASSERT_NOT_NULL(pOp);73  TEST_ASSERT_EQUAL_INT(OP_Integer, pOp->opcode);74  TEST_ASSERT_EQUAL_INT(12345, pOp->p1);75  TEST_ASSERT_EQUAL_INT(target, pOp->p2);76 77  sqlite3DbFree(gDb, p);78}79 80/* Test: TK_REGISTER causes OP_Copy from source register to target */81void test_sqlite3ExprCode_TK_REGISTER_emits_OP_Copy(void){82  int sourceReg = 8;83  int target = 3;84  Expr *p = (Expr*)sqlite3DbMallocZero(gDb, sizeof(Expr));85  TEST_ASSERT_NOT_NULL(p);86  p->op = TK_REGISTER;87  p->iTable = sourceReg;88 89  sqlite3ExprCode(&gParse, p, target);90 91  int nOp = sqlite3VdbeCurrentAddr(gVdbe);92  TEST_ASSERT_EQUAL_INT(1, nOp);93 94  Op *pOp = getLastOp();95  TEST_ASSERT_NOT_NULL(pOp);96  TEST_ASSERT_EQUAL_INT(OP_Copy, pOp->opcode);97  TEST_ASSERT_EQUAL_INT(sourceReg, pOp->p1);98  TEST_ASSERT_EQUAL_INT(target, pOp->p2);99 100  sqlite3DbFree(gDb, p);101}102 103/* Test: TK_COLUMN in self-row context (iTable<0, iSelfTab<0) returns a non-target104   register, so sqlite3ExprCode must emit OP_SCopy to move to target. */105void test_sqlite3ExprCode_TK_COLUMN_selftab_negative_emits_OP_SCopy(void){106  int target = 2;107 108  /* Set up self-row context */109  gParse.iSelfTab = -10; /* registers for unpacked row start at 0 - iSelfTab */110 111  /* Minimal table with 1 column */112  Table *pTab = (Table*)sqlite3DbMallocZero(gDb, sizeof(Table));113  TEST_ASSERT_NOT_NULL(pTab);114  pTab->nCol = 1;115  pTab->aCol = (Column*)sqlite3DbMallocZero(gDb, sizeof(Column)*pTab->nCol);116  TEST_ASSERT_NOT_NULL(pTab->aCol);117  pTab->aCol[0].affinity = SQLITE_AFF_BLOB; /* ensure branch does not add RealAffinity */118 119  /* Build the expression: TK_COLUMN referencing column 0 of self-row (iTable<0) */120  Expr *p = (Expr*)sqlite3DbMallocZero(gDb, sizeof(Expr));121  TEST_ASSERT_NOT_NULL(p);122  p->op = TK_COLUMN;123  p->iTable = -1;     /* indicates self-row */124  p->iColumn = 0;     /* first column */125  p->y.pTab = pTab;   /* table metadata needed by the code path */126 127  /* Expected source register computed as:128     sqlite3TableColumnToStorage(pTab,0) - gParse.iSelfTab129     Normally storage index for first column is 0, so src = 0 - (-10) = 10. */130  int expectedSrc = 0 - gParse.iSelfTab;131 132  sqlite3ExprCode(&gParse, p, target);133 134  int nOp = sqlite3VdbeCurrentAddr(gVdbe);135  TEST_ASSERT_EQUAL_INT(1, nOp);136 137  Op *pOp = getLastOp();138  TEST_ASSERT_NOT_NULL(pOp);139  TEST_ASSERT_EQUAL_INT(OP_SCopy, pOp->opcode);140  TEST_ASSERT_EQUAL_INT(expectedSrc, pOp->p1);141  TEST_ASSERT_EQUAL_INT(target, pOp->p2);142 143  /* Cleanup */144  sqlite3DbFree(gDb, p);145  sqlite3DbFree(gDb, pTab->aCol);146  sqlite3DbFree(gDb, pTab);147}148 149int main(void) {150  UNITY_BEGIN();151  RUN_TEST(test_sqlite3ExprCode_null_expr_emits_OP_Null);152  RUN_TEST(test_sqlite3ExprCode_TK_INTEGER_no_copy);153  RUN_TEST(test_sqlite3ExprCode_TK_REGISTER_emits_OP_Copy);154  RUN_TEST(test_sqlite3ExprCode_TK_COLUMN_selftab_negative_emits_OP_SCopy);155  return UNITY_END();156}