Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_expr_sqlite3ExprAttachSubtrees.c181 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include "sqlite3.h"4#include "parse.h"5#include <string.h>6#include <stdlib.h>7 8/* Unity setup/teardown */9void setUp(void) {10  /* No-op */11}12void tearDown(void) {13  /* No-op */14}15 16/* Helper: allocate a zeroed Expr with given op, flags and nHeight */17static Expr* allocExpr(sqlite3 *db, int op, unsigned flags, int nHeight){18  Expr *p = (Expr*)sqlite3DbMallocZero(db, sizeof(Expr));19  TEST_ASSERT_NOT_NULL(p);20  p->op = (u8)op;21  p->flags = flags;22#if SQLITE_MAX_EXPR_DEPTH>023  p->nHeight = (u8)nHeight;24#else25  (void)nHeight;26#endif27  return p;28}29 30/* Test: attach both left and right, verify pointers, flag propagation, height */31void test_sqlite3ExprAttachSubtrees_attach_both(void){32  sqlite3 *db = 0;33  int rc = sqlite3_open(":memory:", &db);34  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);35  TEST_ASSERT_NOT_NULL(db);36 37  /* Create root with op that uses x.pList to satisfy internal assert */38  Expr *pRoot  = allocExpr(db, TK_FUNCTION, 0, 0);39  Expr *pLeft  = allocExpr(db, TK_INTEGER, 0, 4);40  Expr *pRight = allocExpr(db, TK_ID,      0, 2);41 42  /* Set flags on children to include EP_Propagate bits */43  pLeft->flags  = EP_Propagate;         /* all EP_Propagate bits set */44  pRight->flags = 0;                    /* no EP_Propagate bits */45 46  sqlite3ExprAttachSubtrees(db, pRoot, pLeft, pRight);47 48  /* Pointers must be attached */49  TEST_ASSERT_EQUAL_PTR(pLeft,  pRoot->pLeft);50  TEST_ASSERT_EQUAL_PTR(pRight, pRoot->pRight);51 52  /* EP_Propagate bits must be ORed from both children into root */53  TEST_ASSERT_EQUAL_UINT((pLeft->flags | pRight->flags) & EP_Propagate,54                         pRoot->flags & EP_Propagate);55 56#if SQLITE_MAX_EXPR_DEPTH>057  /* Height should be max(child.nHeight) + 1. Right initially sets it, left may raise it */58  TEST_ASSERT_EQUAL_UINT((unsigned)(pLeft->nHeight + 1), (unsigned)pRoot->nHeight);59#endif60 61  /* Free the whole tree starting from root */62  sqlite3ExprDelete(db, pRoot);63 64  sqlite3_close(db);65}66 67/* Test: attach only right subtree */68void test_sqlite3ExprAttachSubtrees_attach_only_right(void){69  sqlite3 *db = 0;70  int rc = sqlite3_open(":memory:", &db);71  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);72  TEST_ASSERT_NOT_NULL(db);73 74  Expr *pRoot  = allocExpr(db, TK_FUNCTION, 0, 0);75  Expr *pRight = allocExpr(db, TK_ID, 0, 7);76 77  /* Give right an EP_Propagate subset; here we take them all to make check simple */78  pRight->flags = EP_Propagate;79 80  sqlite3ExprAttachSubtrees(db, pRoot, NULL, pRight);81 82  TEST_ASSERT_NULL(pRoot->pLeft);83  TEST_ASSERT_EQUAL_PTR(pRight, pRoot->pRight);84 85  TEST_ASSERT_EQUAL_UINT(pRight->flags & EP_Propagate,86                         pRoot->flags  & EP_Propagate);87 88#if SQLITE_MAX_EXPR_DEPTH>089  TEST_ASSERT_EQUAL_UINT((unsigned)(pRight->nHeight + 1), (unsigned)pRoot->nHeight);90#endif91 92  sqlite3ExprDelete(db, pRoot);93  sqlite3_close(db);94}95 96/* Test: attach only left subtree */97void test_sqlite3ExprAttachSubtrees_attach_only_left(void){98  sqlite3 *db = 0;99  int rc = sqlite3_open(":memory:", &db);100  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);101  TEST_ASSERT_NOT_NULL(db);102 103  Expr *pRoot = allocExpr(db, TK_FUNCTION, 0, 0);104  Expr *pLeft = allocExpr(db, TK_INTEGER, 0, 3);105 106  /* Put a specific EP_Propagate pattern: half of the bits (simply EP_Propagate again) */107  pLeft->flags = EP_Propagate;108 109  sqlite3ExprAttachSubtrees(db, pRoot, pLeft, NULL);110 111  TEST_ASSERT_EQUAL_PTR(pLeft, pRoot->pLeft);112  TEST_ASSERT_NULL(pRoot->pRight);113 114  TEST_ASSERT_EQUAL_UINT(pLeft->flags & EP_Propagate,115                         pRoot->flags & EP_Propagate);116 117#if SQLITE_MAX_EXPR_DEPTH>0118  /* With no right, initial nHeight is set to 1, then possibly raised by left */119  TEST_ASSERT_EQUAL_UINT((unsigned)(pLeft->nHeight + 1), (unsigned)pRoot->nHeight);120#endif121 122  sqlite3ExprDelete(db, pRoot);123  sqlite3_close(db);124}125 126/* Test: attach only left subtree with left->nHeight == 0 to ensure base case works */127void test_sqlite3ExprAttachSubtrees_attach_left_height_zero(void){128  sqlite3 *db = 0;129  int rc = sqlite3_open(":memory:", &db);130  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);131  TEST_ASSERT_NOT_NULL(db);132 133  Expr *pRoot = allocExpr(db, TK_FUNCTION, 0, 0);134  Expr *pLeft = allocExpr(db, TK_INTEGER, 0, 0);135 136  sqlite3ExprAttachSubtrees(db, pRoot, pLeft, NULL);137 138  TEST_ASSERT_EQUAL_PTR(pLeft, pRoot->pLeft);139  TEST_ASSERT_NULL(pRoot->pRight);140 141#if SQLITE_MAX_EXPR_DEPTH>0142  /* If left->nHeight is 0, root should remain at least 1 (since base is 1) */143  TEST_ASSERT_EQUAL_UINT(1u, (unsigned)pRoot->nHeight);144#endif145 146  sqlite3ExprDelete(db, pRoot);147  sqlite3_close(db);148}149 150/* Test: pRoot == NULL should delete subtrees and not crash; requires db->mallocFailed set */151void test_sqlite3ExprAttachSubtrees_null_root_deletes_children(void){152  sqlite3 *db = 0;153  int rc = sqlite3_open(":memory:", &db);154  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);155  TEST_ASSERT_NOT_NULL(db);156 157  /* Create some non-trivial children */158  Expr *pLeft  = allocExpr(db, TK_INTEGER, 0, 1);159  Expr *pRight = allocExpr(db, TK_ID,      0, 1);160  /* Give left a nested child to exercise delete recursion */161  pLeft->pLeft = allocExpr(db, TK_INTEGER, 0, 1);162 163  /* The function asserts that db->mallocFailed is set when pRoot==NULL */164  db->mallocFailed = 1;165 166  /* Should not crash. Children are expected to be deleted internally. */167  sqlite3ExprAttachSubtrees(db, NULL, pLeft, pRight);168 169  /* Nothing more to free here: ownership was transferred and released. */170  sqlite3_close(db);171}172 173int main(void){174  UNITY_BEGIN();175  RUN_TEST(test_sqlite3ExprAttachSubtrees_attach_both);176  RUN_TEST(test_sqlite3ExprAttachSubtrees_attach_only_right);177  RUN_TEST(test_sqlite3ExprAttachSubtrees_attach_only_left);178  RUN_TEST(test_sqlite3ExprAttachSubtrees_attach_left_height_zero);179  RUN_TEST(test_sqlite3ExprAttachSubtrees_null_root_deletes_children);180  return UNITY_END();181}