Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_insert_sqlite3ExprReferencesUpdatedColumn.c176 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5 6/* Helper: open an in-memory database and assert success */7static sqlite3* open_memory_db(void){8  sqlite3 *db = 0;9  int rc = sqlite3_open(":memory:", &db);10  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed");11  TEST_ASSERT_NOT_NULL(db);12  return db;13}14 15/* Helper: exec SQL and assert success */16static void exec_sql_or_fail(sqlite3 *db, const char *zSql){17  int rc = sqlite3_exec(db, zSql, 0, 0, 0);18  if( rc!=SQLITE_OK ){19    const char *zErr = sqlite3_errmsg(db);20    TEST_FAIL_MESSAGE(zErr ? zErr : "sqlite3_exec failed");21  }22}23 24/* Helper: fetch first CHECK expression for a table */25static Expr* first_check_expr(sqlite3 *db, const char *zTab){26  Table *pTab = sqlite3FindTable(db, zTab, "main");27  TEST_ASSERT_NOT_NULL_MESSAGE(pTab, "Table not found");28  TEST_ASSERT_NOT_NULL_MESSAGE(pTab->pCheck, "No CHECK constraints found");29  TEST_ASSERT_TRUE_MESSAGE(pTab->pCheck->nExpr >= 1, "Empty CHECK list");30  Expr *pExpr = pTab->pCheck->a[0].pExpr;31  TEST_ASSERT_NOT_NULL_MESSAGE(pExpr, "CHECK expression is NULL");32  return pExpr;33}34 35void setUp(void) {36  /* no-op */37}38 39void tearDown(void) {40  /* no-op */41}42 43/* Unchanged column referenced by CHECK => should return false */44void test_sqlite3ExprReferencesUpdatedColumn_unchanged_column_false(void){45  sqlite3 *db = open_memory_db();46  exec_sql_or_fail(db, "CREATE TABLE t1(a, b, CHECK(a > 0));");47 48  Expr *pExpr = first_check_expr(db, "t1");49 50  int aiChng[2] = { -1, -1 }; /* neither a nor b changed */51  int rc;52 53  rc = sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, 0);54  TEST_ASSERT_FALSE(rc);55 56  sqlite3_close(db);57}58 59/* Changed column referenced by CHECK => should return true */60void test_sqlite3ExprReferencesUpdatedColumn_changed_column_true(void){61  sqlite3 *db = open_memory_db();62  exec_sql_or_fail(db, "CREATE TABLE t2(a, b, CHECK(a > 0));");63 64  Expr *pExpr = first_check_expr(db, "t2");65 66  int aiChng[2] = { 0, -1 }; /* a changed, b unchanged */67  int rc = sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, 0);68  TEST_ASSERT_TRUE(rc);69 70  sqlite3_close(db);71}72 73/* Rowid reference: depends on chngRowid flag */74void test_sqlite3ExprReferencesUpdatedColumn_rowid_respected_by_flag(void){75  sqlite3 *db = open_memory_db();76  exec_sql_or_fail(db, "CREATE TABLE t3(a, b, CHECK(rowid > 5));");77 78  Expr *pExpr = first_check_expr(db, "t3");79 80  int aiChng[2] = { -1, -1 }; /* no columns changed */81 82  int rc = sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, 0 /* chngRowid=false */);83  TEST_ASSERT_FALSE(rc);84 85  rc = sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, 1 /* chngRowid=true */);86  TEST_ASSERT_TRUE(rc);87 88  sqlite3_close(db);89}90 91/* Mixed: expression references rowid and a column ("b") */92void test_sqlite3ExprReferencesUpdatedColumn_mixed_rowid_and_column_cases(void){93  sqlite3 *db = open_memory_db();94  exec_sql_or_fail(db, "CREATE TABLE t4(a, b, CHECK(rowid > 5 AND b < 10));");95 96  Expr *pExpr = first_check_expr(db, "t4");97  int aiChng[2];98 99  /* Case A: b changed, rowid not changed => true */100  aiChng[0] = -1; aiChng[1] = 0;101  int rc = sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, 0 /* chngRowid=false */);102  TEST_ASSERT_TRUE(rc);103 104  /* Case B: b unchanged, rowid changed => true */105  aiChng[0] = -1; aiChng[1] = -1;106  rc = sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, 1 /* chngRowid=true */);107  TEST_ASSERT_TRUE(rc);108 109  /* Case C: neither b nor rowid changed => false */110  aiChng[0] = -1; aiChng[1] = -1;111  rc = sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, 0 /* chngRowid=false */);112  TEST_ASSERT_FALSE(rc);113 114  sqlite3_close(db);115}116 117/* Constant CHECK expression references no columns or rowid => always false */118void test_sqlite3ExprReferencesUpdatedColumn_constant_expr_false(void){119  sqlite3 *db = open_memory_db();120  exec_sql_or_fail(db, "CREATE TABLE t5(a, b, CHECK(1));");121 122  Expr *pExpr = first_check_expr(db, "t5");123  int aiChng[2] = { 0, 0 };124 125  int rc = sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, 1);126  TEST_ASSERT_FALSE(rc);127 128  sqlite3_close(db);129}130 131/* NULL expression => treated as no reference => false */132void test_sqlite3ExprReferencesUpdatedColumn_null_expr_false(void){133  int aiChng[2] = { 0, 0 };134  int rc = sqlite3ExprReferencesUpdatedColumn(NULL, aiChng, 1);135  TEST_ASSERT_FALSE(rc);136}137 138/* OR expression referencing different columns: any changed should trigger true */139void test_sqlite3ExprReferencesUpdatedColumn_or_expression_any_changed_triggers_true(void){140  sqlite3 *db = open_memory_db();141  exec_sql_or_fail(db, "CREATE TABLE t6(a, b, CHECK(a > 10 OR b < 5));");142 143  Expr *pExpr = first_check_expr(db, "t6");144 145  int aiChng[2];146  int rc;147 148  /* Neither a nor b changed => false */149  aiChng[0] = -1; aiChng[1] = -1;150  rc = sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, 0);151  TEST_ASSERT_FALSE(rc);152 153  /* a changed => true */154  aiChng[0] = 0; aiChng[1] = -1;155  rc = sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, 0);156  TEST_ASSERT_TRUE(rc);157 158  /* b changed => true */159  aiChng[0] = -1; aiChng[1] = 0;160  rc = sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, 0);161  TEST_ASSERT_TRUE(rc);162 163  sqlite3_close(db);164}165 166int main(void) {167  UNITY_BEGIN();168  RUN_TEST(test_sqlite3ExprReferencesUpdatedColumn_unchanged_column_false);169  RUN_TEST(test_sqlite3ExprReferencesUpdatedColumn_changed_column_true);170  RUN_TEST(test_sqlite3ExprReferencesUpdatedColumn_rowid_respected_by_flag);171  RUN_TEST(test_sqlite3ExprReferencesUpdatedColumn_mixed_rowid_and_column_cases);172  RUN_TEST(test_sqlite3ExprReferencesUpdatedColumn_constant_expr_false);173  RUN_TEST(test_sqlite3ExprReferencesUpdatedColumn_null_expr_false);174  RUN_TEST(test_sqlite3ExprReferencesUpdatedColumn_or_expression_any_changed_triggers_true);175  return UNITY_END();176}