Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_resolve_sqlite3ResolveSelfReference.c202 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6static sqlite3 *gDb = NULL;7 8/* Helpers */9static void initParse(Parse *pParse, sqlite3 *db){10  memset(pParse, 0, sizeof(*pParse));11  pParse->db = db;12}13 14static Token makeToken(const char *z){15  Token t;16  t.z = z;17  t.n = (int)strlen(z);18  return t;19}20 21static Expr* makeIdExpr(sqlite3 *db, const char *zId){22  Token t = makeToken(zId);23  return sqlite3ExprAlloc(db, TK_ID, &t, 0);24}25 26static Expr* makeIntExpr(sqlite3 *db, const char *zNum){27  Token t = makeToken(zNum);28  return sqlite3ExprAlloc(db, TK_INTEGER, &t, 0);29}30 31void setUp(void) {32  int rc = sqlite3_open(":memory:", &gDb);33  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);34  /* Create a main-schema table and a temp table for tests */35  rc = sqlite3_exec(gDb,36    "CREATE TABLE t1(a, b);"37    "CREATE TEMP TABLE tt(x);",38    0, 0, 039  );40  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);41}42 43void tearDown(void) {44  if( gDb ){45    sqlite3_close(gDb);46    gDb = NULL;47  }48}49 50/* Test: NULL expression and list -> SQLITE_OK */51void test_sqlite3ResolveSelfReference_NullExprAndList_ReturnsOK(void){52  Parse sParse;53  initParse(&sParse, gDb);54 55  int rc = sqlite3ResolveSelfReference(&sParse, NULL, 0, NULL, NULL);56  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);57  TEST_ASSERT_EQUAL_INT(0, sParse.nErr);58}59 60/* Test: Resolve a simple column in a CHECK-like context */61void test_sqlite3ResolveSelfReference_ResolveColumnInCheckContext(void){62  Parse sParse;63  initParse(&sParse, gDb);64 65  Table *pTab = sqlite3FindTable(gDb, "t1", "main");66  TEST_ASSERT_NOT_NULL(pTab);67 68  /* Build expression referencing column "a" */69  Expr *pExpr = makeIdExpr(gDb, "a");70  TEST_ASSERT_NOT_NULL(pExpr);71 72  int rc = sqlite3ResolveSelfReference(&sParse, pTab, NC_IsCheck, pExpr, NULL);73  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);74  TEST_ASSERT_EQUAL_INT(0, sParse.nErr);75 76  /* After resolution:77     - pExpr->op == TK_COLUMN78     - pExpr->iTable == -1 (special for self-reference contexts)79     - pExpr->iColumn == 0 (column "a")80     - pExpr->pTab == pTab81  */82  TEST_ASSERT_EQUAL_INT(TK_COLUMN, pExpr->op);83  TEST_ASSERT_EQUAL_INT(-1, pExpr->iTable);84  TEST_ASSERT_EQUAL_INT(0, pExpr->iColumn);85  TEST_ASSERT_EQUAL_PTR(pTab, pExpr->pTab);86 87  sqlite3ExprDelete(gDb, pExpr);88}89 90/* Test: No table context (type==0), column reference should be an error */91void test_sqlite3ResolveSelfReference_NoTable_ColumnRefCausesError(void){92  Parse sParse;93  initParse(&sParse, gDb);94 95  /* Column reference "a" with no table in NameContext and type==0 */96  Expr *pExpr = makeIdExpr(gDb, "a");97  TEST_ASSERT_NOT_NULL(pExpr);98 99  int rc = sqlite3ResolveSelfReference(&sParse, NULL, 0, pExpr, NULL);100  TEST_ASSERT_NOT_EQUAL(SQLITE_OK, rc);101  TEST_ASSERT_TRUE(sParse.nErr > 0);102 103  sqlite3ExprDelete(gDb, pExpr);104}105 106/* Test: EP_FromDDL is set on TK_FUNCTION nodes for non-temp schema */107void test_sqlite3ResolveSelfReference_FromDDL_FunctionExpr_MainSchema(void){108  Parse sParse;109  initParse(&sParse, gDb);110 111  Table *pTab = sqlite3FindTable(gDb, "t1", "main");112  TEST_ASSERT_NOT_NULL(pTab);113 114  /* Build function expression: abs(1) */115  ExprList *pArgs = NULL;116  pArgs = sqlite3ExprListAppend(&sParse, pArgs, makeIntExpr(gDb, "1"));117  TEST_ASSERT_NOT_NULL(pArgs);118 119  Token tFunc = makeToken("abs");120  Expr *pFunc = sqlite3ExprFunction(gDb, pArgs, &tFunc);121  TEST_ASSERT_NOT_NULL(pFunc);122 123  int rc = sqlite3ResolveSelfReference(&sParse, pTab, NC_IsCheck, pFunc, NULL);124  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);125  TEST_ASSERT_EQUAL_INT(0, sParse.nErr);126 127  /* EP_FromDDL should be set because pTab is in main (non-temp) schema */128  TEST_ASSERT_TRUE( ExprHasProperty(pFunc, EP_FromDDL) );129 130  sqlite3ExprDelete(gDb, pFunc); /* This also deletes pArgs */131}132 133/* Test: EP_FromDDL is NOT set on TK_FUNCTION nodes for temp schema */134void test_sqlite3ResolveSelfReference_FromDDL_FunctionExpr_TempSchema(void){135  Parse sParse;136  initParse(&sParse, gDb);137 138  Table *pTempTab = sqlite3FindTable(gDb, "tt", "temp");139  TEST_ASSERT_NOT_NULL(pTempTab);140 141  /* Build function expression: abs(1) */142  ExprList *pArgs = NULL;143  pArgs = sqlite3ExprListAppend(&sParse, pArgs, makeIntExpr(gDb, "1"));144  TEST_ASSERT_NOT_NULL(pArgs);145 146  Token tFunc = makeToken("abs");147  Expr *pFunc = sqlite3ExprFunction(gDb, pArgs, &tFunc);148  TEST_ASSERT_NOT_NULL(pFunc);149 150  int rc = sqlite3ResolveSelfReference(&sParse, pTempTab, NC_IsCheck, pFunc, NULL);151  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);152  TEST_ASSERT_EQUAL_INT(0, sParse.nErr);153 154  /* EP_FromDDL should NOT be set because pTab is in TEMP schema */155  TEST_ASSERT_FALSE( ExprHasProperty(pFunc, EP_FromDDL) );156 157  sqlite3ExprDelete(gDb, pFunc); /* This also deletes pArgs */158}159 160/* Test: Resolve an ExprList of multiple columns in a CHECK-like context */161void test_sqlite3ResolveSelfReference_ResolveExprList_MultipleColumns(void){162  Parse sParse;163  initParse(&sParse, gDb);164 165  Table *pTab = sqlite3FindTable(gDb, "t1", "main");166  TEST_ASSERT_NOT_NULL(pTab);167 168  ExprList *pList = NULL;169  pList = sqlite3ExprListAppend(&sParse, pList, makeIdExpr(gDb, "a"));170  TEST_ASSERT_NOT_NULL(pList);171  pList = sqlite3ExprListAppend(&sParse, pList, makeIdExpr(gDb, "b"));172  TEST_ASSERT_NOT_NULL(pList);173 174  int rc = sqlite3ResolveSelfReference(&sParse, pTab, NC_IsCheck, NULL, pList);175  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);176  TEST_ASSERT_EQUAL_INT(0, sParse.nErr);177 178  /* Verify both list expressions resolved to TK_COLUMN with iTable -1 */179  TEST_ASSERT_EQUAL_INT(2, pList->nExpr);180  TEST_ASSERT_EQUAL_INT(TK_COLUMN, pList->a[0].pExpr->op);181  TEST_ASSERT_EQUAL_INT(-1, pList->a[0].pExpr->iTable);182  TEST_ASSERT_EQUAL_INT(0, pList->a[0].pExpr->iColumn); /* "a" -> 0 */183 184  TEST_ASSERT_EQUAL_INT(TK_COLUMN, pList->a[1].pExpr->op);185  TEST_ASSERT_EQUAL_INT(-1, pList->a[1].pExpr->iTable);186  TEST_ASSERT_EQUAL_INT(1, pList->a[1].pExpr->iColumn); /* "b" -> 1 */187 188  sqlite3ExprListDelete(gDb, pList);189}190 191int main(void) {192  UNITY_BEGIN();193 194  RUN_TEST(test_sqlite3ResolveSelfReference_NullExprAndList_ReturnsOK);195  RUN_TEST(test_sqlite3ResolveSelfReference_ResolveColumnInCheckContext);196  RUN_TEST(test_sqlite3ResolveSelfReference_NoTable_ColumnRefCausesError);197  RUN_TEST(test_sqlite3ResolveSelfReference_FromDDL_FunctionExpr_MainSchema);198  RUN_TEST(test_sqlite3ResolveSelfReference_FromDDL_FunctionExpr_TempSchema);199  RUN_TEST(test_sqlite3ResolveSelfReference_ResolveExprList_MultipleColumns);200 201  return UNITY_END();202}