Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_expr_sqlite3ExprCanBeNull.c157 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.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 to allocate a Table with nCol columns and provided notNull flags.15   notNullFlags must have length nCol. */16static Table* makeTableWithNotNulls(int nCol, const u8 *notNullFlags){17  Table *pTab = (Table*)malloc(sizeof(Table));18  TEST_ASSERT_NOT_NULL(pTab);19  memset(pTab, 0, sizeof(Table));20  pTab->nCol = (i16)nCol;21  if( nCol>0 ){22    Column *aCol = (Column*)malloc(sizeof(Column)*nCol);23    TEST_ASSERT_NOT_NULL(aCol);24    memset(aCol, 0, sizeof(Column)*nCol);25    for(int i=0; i<nCol; i++){26      aCol[i].notNull = notNullFlags ? notNullFlags[i] : 0;27    }28    pTab->aCol = aCol;29  }30  return pTab;31}32 33static void freeTable(Table *pTab){34  if( pTab ){35    if( pTab->aCol ) free(pTab->aCol);36    free(pTab);37  }38}39 40/* 1) Constants should be detected as non-nullable (return 0) */41void test_sqlite3ExprCanBeNull_constants_return_false(void){42  Expr eInt; memset(&eInt, 0, sizeof(eInt)); eInt.op = TK_INTEGER;43  Expr eStr; memset(&eStr, 0, sizeof(eStr)); eStr.op = TK_STRING;44  Expr eFlt; memset(&eFlt, 0, sizeof(eFlt)); eFlt.op = TK_FLOAT;45  Expr eBlob; memset(&eBlob, 0, sizeof(eBlob)); eBlob.op = TK_BLOB;46 47  TEST_ASSERT_EQUAL_INT(0, sqlite3ExprCanBeNull(&eInt));48  TEST_ASSERT_EQUAL_INT(0, sqlite3ExprCanBeNull(&eStr));49  TEST_ASSERT_EQUAL_INT(0, sqlite3ExprCanBeNull(&eFlt));50  TEST_ASSERT_EQUAL_INT(0, sqlite3ExprCanBeNull(&eBlob));51}52 53/* 2) Unary operators should be skipped and the child inspected */54void test_sqlite3ExprCanBeNull_unary_skips_to_child(void){55  Expr child; memset(&child, 0, sizeof(child)); child.op = TK_INTEGER;56 57  Expr unaryMinus; memset(&unaryMinus, 0, sizeof(unaryMinus));58  unaryMinus.op = TK_UMINUS;59  unaryMinus.pLeft = &child;60 61  Expr unaryPlus; memset(&unaryPlus, 0, sizeof(unaryPlus));62  unaryPlus.op = TK_UPLUS;63  unaryPlus.pLeft = &unaryMinus; /* Chain two unary ops */64 65  TEST_ASSERT_EQUAL_INT(0, sqlite3ExprCanBeNull(&unaryMinus));66  TEST_ASSERT_EQUAL_INT(0, sqlite3ExprCanBeNull(&unaryPlus));67}68 69/* 3) TK_REGISTER should resolve to op2 and be treated accordingly */70void test_sqlite3ExprCanBeNull_register_resolves_op2(void){71  Expr e; memset(&e, 0, sizeof(e));72  e.op = TK_REGISTER;73  e.op2 = TK_FLOAT; /* Underlying expression is a constant float */74  TEST_ASSERT_EQUAL_INT(0, sqlite3ExprCanBeNull(&e));75 76  e.op2 = TK_BLOB;77  TEST_ASSERT_EQUAL_INT(0, sqlite3ExprCanBeNull(&e));78}79 80/* 4) TK_COLUMN behavior based on column nullability and EP_CanBeNull flag */81void test_sqlite3ExprCanBeNull_column_nullability(void){82  /* Create a table with two columns:83     - col0 allows NULL (notNull=0)84     - col1 is NOT NULL (notNull=1) */85  u8 nn[2] = {0, 1};86  Table *pTab = makeTableWithNotNulls(2, nn);87 88  /* Column 0 (nullable) => function returns 1 (can be null) */89  Expr eCol0; memset(&eCol0, 0, sizeof(eCol0));90  eCol0.op = TK_COLUMN;91  eCol0.y.pTab = pTab;92  eCol0.iColumn = 0;93  eCol0.flags = 0;94  TEST_ASSERT_EQUAL_INT(1, sqlite3ExprCanBeNull(&eCol0));95 96  /* Column 1 (NOT NULL) => function returns 0 (cannot be null) */97  Expr eCol1; memset(&eCol1, 0, sizeof(eCol1));98  eCol1.op = TK_COLUMN;99  eCol1.y.pTab = pTab;100  eCol1.iColumn = 1;101  eCol1.flags = 0;102  TEST_ASSERT_EQUAL_INT(0, sqlite3ExprCanBeNull(&eCol1));103 104  freeTable(pTab);105}106 107/* 5) EP_CanBeNull overrides NOT NULL column constraint */108void test_sqlite3ExprCanBeNull_column_with_EP_CanBeNull_flag(void){109  u8 nn[1] = {1}; /* NOT NULL column */110  Table *pTab = makeTableWithNotNulls(1, nn);111 112  Expr eCol; memset(&eCol, 0, sizeof(eCol));113  eCol.op = TK_COLUMN;114  eCol.y.pTab = pTab;115  eCol.iColumn = 0;116  eCol.flags = EP_CanBeNull; /* Force possible null due to outer join, etc. */117 118  TEST_ASSERT_EQUAL_INT(1, sqlite3ExprCanBeNull(&eCol));119 120  freeTable(pTab);121}122 123/* 6) Rowid (iColumn<0) should be considered non-null */124void test_sqlite3ExprCanBeNull_rowid_nonnull(void){125  u8 nn[1] = {0};126  Table *pTab = makeTableWithNotNulls(1, nn);127 128  Expr eRowid; memset(&eRowid, 0, sizeof(eRowid));129  eRowid.op = TK_COLUMN;130  eRowid.y.pTab = pTab;131  eRowid.iColumn = -1; /* rowid */132  eRowid.flags = 0;133 134  TEST_ASSERT_EQUAL_INT(0, sqlite3ExprCanBeNull(&eRowid));135 136  freeTable(pTab);137}138 139/* 7) Default case: expression types not explicitly handled (e.g., TK_NULL) return 1 */140void test_sqlite3ExprCanBeNull_default_returns_true(void){141  Expr e; memset(&e, 0, sizeof(e));142  e.op = TK_NULL; /* Default case goes to 'return 1' */143  TEST_ASSERT_EQUAL_INT(1, sqlite3ExprCanBeNull(&e));144}145 146/* Main */147int main(void){148  UNITY_BEGIN();149  RUN_TEST(test_sqlite3ExprCanBeNull_constants_return_false);150  RUN_TEST(test_sqlite3ExprCanBeNull_unary_skips_to_child);151  RUN_TEST(test_sqlite3ExprCanBeNull_register_resolves_op2);152  RUN_TEST(test_sqlite3ExprCanBeNull_column_nullability);153  RUN_TEST(test_sqlite3ExprCanBeNull_column_with_EP_CanBeNull_flag);154  RUN_TEST(test_sqlite3ExprCanBeNull_rowid_nonnull);155  RUN_TEST(test_sqlite3ExprCanBeNull_default_returns_true);156  return UNITY_END();157}