Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_expr_sqlite3PExprAddSelect.c163 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Unity setUp/tearDown */7void setUp(void) {8  /* No global setup needed */9}10void tearDown(void) {11  /* No global teardown needed */12}13 14/* Helper: open an in-memory SQLite DB and initialize a Parse object */15static void open_db_and_parse(sqlite3 **pDb, Parse *pParse){16  memset(pParse, 0, sizeof(Parse));17  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", pDb));18  pParse->db = *pDb;19}20 21/* Helper: create a simple leaf Expr (TK_NULL) */22static Expr* make_leaf_expr(sqlite3 *db){23  Expr *p = (Expr*)sqlite3DbMallocZero(db, sizeof(Expr));24  TEST_ASSERT_NOT_NULL(p);25  p->op = TK_NULL;26  return p;27}28 29/* Helper: create a deep left-linked Expr chain of given depth (>=1) */30static Expr* make_deep_left_chain(sqlite3 *db, int depth){31  TEST_ASSERT_TRUE(depth >= 1);32  Expr *root = make_leaf_expr(db);33  Expr *cur = root;34  for(int i=1; i<depth; i++){35    Expr *n = (Expr*)sqlite3DbMallocZero(db, sizeof(Expr));36    TEST_ASSERT_NOT_NULL(n);37    n->op = TK_NULL;38    n->pLeft = cur;39    cur = n;40  }41  return cur; /* return the top-most node */42}43 44/* Test 1: With non-NULL pExpr and NULL pSelect, flags set and height computed */45static void test_sqlite3PExprAddSelect_sets_flags_with_null_select(void){46  sqlite3 *db = NULL;47  Parse parse;48  open_db_and_parse(&db, &parse);49 50  Expr *pExpr = make_leaf_expr(db);51  pExpr->nHeight = 0;52 53  sqlite3PExprAddSelect(&parse, pExpr, NULL);54 55  TEST_ASSERT_NULL(pExpr->x.pSelect);56  TEST_ASSERT_TRUE( (pExpr->flags & EP_xIsSelect) != 0 );57  TEST_ASSERT_TRUE( (pExpr->flags & EP_Subquery) != 0 );58  TEST_ASSERT_GREATER_OR_EQUAL_INT(1, pExpr->nHeight);59  TEST_ASSERT_EQUAL_INT(0, parse.nErr);60 61  sqlite3ExprDelete(db, pExpr);62  sqlite3_close(db);63}64 65/* Test 2: With non-NULL pExpr and non-NULL pSelect, pointer assigned and flags set */66static void test_sqlite3PExprAddSelect_assigns_nonnull_select(void){67  sqlite3 *db = NULL;68  Parse parse;69  open_db_and_parse(&db, &parse);70 71  Expr *pExpr = make_leaf_expr(db);72  Select *pSel = (Select*)sqlite3DbMallocZero(db, sizeof(Select));73  TEST_ASSERT_NOT_NULL(pSel);74 75  sqlite3PExprAddSelect(&parse, pExpr, pSel);76 77  TEST_ASSERT_EQUAL_PTR(pSel, pExpr->x.pSelect);78  TEST_ASSERT_TRUE( (pExpr->flags & EP_xIsSelect) != 0 );79  TEST_ASSERT_TRUE( (pExpr->flags & EP_Subquery) != 0 );80  TEST_ASSERT_GREATER_OR_EQUAL_INT(1, pExpr->nHeight);81  TEST_ASSERT_EQUAL_INT(0, parse.nErr);82 83  /* Freeing the expression should also delete attached Select */84  sqlite3ExprDelete(db, pExpr);85  sqlite3_close(db);86}87 88/* Test 3: If parse.nErr is already non-zero, height is not recomputed */89static void test_sqlite3PExprAddSelect_does_not_set_height_if_parse_has_error(void){90  sqlite3 *db = NULL;91  Parse parse;92  open_db_and_parse(&db, &parse);93 94  Expr *pExpr = make_leaf_expr(db);95  pExpr->nHeight = 0;96  Select *pSel = (Select*)sqlite3DbMallocZero(db, sizeof(Select));97  TEST_ASSERT_NOT_NULL(pSel);98 99  parse.nErr = 1; /* Simulate prior error */100 101  sqlite3PExprAddSelect(&parse, pExpr, pSel);102 103  TEST_ASSERT_EQUAL_PTR(pSel, pExpr->x.pSelect);104  TEST_ASSERT_TRUE( (pExpr->flags & EP_xIsSelect) != 0 );105  TEST_ASSERT_TRUE( (pExpr->flags & EP_Subquery) != 0 );106  /* Since parse.nErr was non-zero, sqlite3ExprSetHeightAndFlags should not update nHeight */107  TEST_ASSERT_EQUAL_INT(0, pExpr->nHeight);108 109  /* Clean up */110  sqlite3ExprDelete(db, pExpr);111  sqlite3_close(db);112}113 114/* Test 4: Deep expression exceeds SQLITE_LIMIT_EXPR_DEPTH, causing an error */115static void test_sqlite3PExprAddSelect_enforces_expr_depth_limit(void){116  sqlite3 *db = NULL;117  Parse parse;118  open_db_and_parse(&db, &parse);119 120  /* Set a low expression depth limit */121  int old = sqlite3_limit(db, SQLITE_LIMIT_EXPR_DEPTH, 5);122  (void)old;123 124  /* Create a chain deeper than the limit */125  Expr *pExpr = make_deep_left_chain(db, 10);126  /* Use NULL Select; flags should still be set */127  sqlite3PExprAddSelect(&parse, pExpr, NULL);128 129  TEST_ASSERT_TRUE( (pExpr->flags & EP_xIsSelect) != 0 );130  TEST_ASSERT_TRUE( (pExpr->flags & EP_Subquery) != 0 );131  TEST_ASSERT_TRUE(parse.nErr > 0);132 133  sqlite3ExprDelete(db, pExpr);134  sqlite3_close(db);135}136 137/* Test 5: NULL pExpr path with mallocFailed set; should not crash and should handle NULL pSelect */138static void test_sqlite3PExprAddSelect_handles_null_expr_with_malloc_failed(void){139  sqlite3 *db = NULL;140  Parse parse;141  open_db_and_parse(&db, &parse);142 143  /* Simulate OOM failure that led to NULL pExpr */144  parse.db->mallocFailed = 1;145 146  /* pSelect is NULL; function should return without issues */147  sqlite3PExprAddSelect(&parse, NULL, NULL);148 149  /* Ensure no additional parse errors introduced */150  TEST_ASSERT_EQUAL_INT(0, parse.nErr);151 152  sqlite3_close(db);153}154 155int main(void) {156  UNITY_BEGIN();157  RUN_TEST(test_sqlite3PExprAddSelect_sets_flags_with_null_select);158  RUN_TEST(test_sqlite3PExprAddSelect_assigns_nonnull_select);159  RUN_TEST(test_sqlite3PExprAddSelect_does_not_set_height_if_parse_has_error);160  RUN_TEST(test_sqlite3PExprAddSelect_enforces_expr_depth_limit);161  RUN_TEST(test_sqlite3PExprAddSelect_handles_null_expr_with_malloc_failed);162  return UNITY_END();163}