Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_insert_sqlite3TableAffinity.c181 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4 5/* Global database handle for Vdbe creation */6static sqlite3 *gDb = NULL;7 8static Vdbe* newVdbe(void){9  Parse pParse;10  memset(&pParse, 0, sizeof(pParse));11  pParse.db = gDb;12  Vdbe *v = sqlite3VdbeCreate(&pParse);13  TEST_ASSERT_NOT_NULL_MESSAGE(v, "sqlite3VdbeCreate returned NULL");14  return v;15}16 17void setUp(void) {18  int rc = sqlite3_open(":memory:", &gDb);19  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed");20}21 22void tearDown(void) {23  if( gDb ){24    sqlite3_close(gDb);25    gDb = NULL;26  }27}28 29/* STRICT table, iReg==0: transform previous MakeRecord into TypeCheck and append new MakeRecord */30void test_sqlite3TableAffinity_strict_iReg0_inserts_TypeCheck_before_MakeRecord(void){31  Vdbe *v = newVdbe();32 33  /* Create a STRICT table descriptor */34  Table tab;35  memset(&tab, 0, sizeof(tab));36  tab.tabFlags = TF_Strict;37  tab.nNVCol = 3; /* not used in iReg==0 path, but set anyway */38 39  /* Seed with an OP_MakeRecord so iReg==0 path can transform it */40  int p1 = 10, p2 = 20, p3 = 30;41  int addrMake = sqlite3VdbeAddOp3(v, OP_MakeRecord, p1, p2, p3);42  TEST_ASSERT_TRUE(addrMake >= 0);43 44  /* Under STRICT, iReg==0 should turn the existing MakeRecord into TypeCheck and append new MakeRecord */45  sqlite3TableAffinity(v, &tab, 0);46 47  /* The opcode at addrMake should now be OP_TypeCheck with same p1/p2, p3 cleared to 0.48     Its P4 should be P4_TABLE pointing to &tab. */49  VdbeOp *opType = sqlite3VdbeGetOp(v, addrMake);50  TEST_ASSERT_NOT_NULL(opType);51  TEST_ASSERT_EQUAL_INT(OP_TypeCheck, opType->opcode);52  TEST_ASSERT_EQUAL_INT(p1, opType->p1);53  TEST_ASSERT_EQUAL_INT(p2, opType->p2);54  TEST_ASSERT_EQUAL_INT(0, opType->p3);55  TEST_ASSERT_EQUAL_UINT8(P4_TABLE, opType->p4type);56  TEST_ASSERT_EQUAL_PTR(&tab, opType->p4.p);57 58  /* The last opcode should be a new OP_MakeRecord with original p1/p2/p3 */59  VdbeOp *opLast = sqlite3VdbeGetLastOp(v);60  TEST_ASSERT_NOT_NULL(opLast);61  TEST_ASSERT_EQUAL_INT(OP_MakeRecord, opLast->opcode);62  TEST_ASSERT_EQUAL_INT(p1, opLast->p1);63  TEST_ASSERT_EQUAL_INT(p2, opLast->p2);64  TEST_ASSERT_EQUAL_INT(p3, opLast->p3);65 66  sqlite3VdbeDelete(v);67}68 69/* STRICT table, iReg>0: add isolated OP_TypeCheck with p1=iReg, p2=nNVCol and P4_TABLE set */70void test_sqlite3TableAffinity_strict_with_registers_adds_TypeCheck_with_p4_table(void){71  Vdbe *v = newVdbe();72 73  Table tab;74  memset(&tab, 0, sizeof(tab));75  tab.tabFlags = TF_Strict;76  tab.nNVCol = 4;77 78  int iReg = 7;79  sqlite3TableAffinity(v, &tab, iReg);80 81  VdbeOp *op = sqlite3VdbeGetLastOp(v);82  TEST_ASSERT_NOT_NULL(op);83  TEST_ASSERT_EQUAL_INT(OP_TypeCheck, op->opcode);84  TEST_ASSERT_EQUAL_INT(iReg, op->p1);85  TEST_ASSERT_EQUAL_INT(tab.nNVCol, op->p2);86  TEST_ASSERT_EQUAL_UINT8(P4_TABLE, op->p4type);87  TEST_ASSERT_EQUAL_PTR(&tab, op->p4.p);88 89  sqlite3VdbeDelete(v);90}91 92/* Legacy (non-STRICT), iReg>0: add OP_Affinity with correct p1/p2 and P4 string */93void test_sqlite3TableAffinity_legacy_iReg_sets_Affinity_on_registers(void){94  Vdbe *v = newVdbe();95 96  Table tab;97  memset(&tab, 0, sizeof(tab));98  tab.tabFlags = 0; /* legacy */99  const char *aff = "DEC"; /* 3 columns: REAL/INTEGER/TEXT in SQLite's mapping comment */100  tab.zColAff = (char*)aff;101 102  int iReg = 2;103  sqlite3TableAffinity(v, &tab, iReg);104 105  VdbeOp *op = sqlite3VdbeGetLastOp(v);106  TEST_ASSERT_NOT_NULL(op);107  TEST_ASSERT_EQUAL_INT(OP_Affinity, op->opcode);108  TEST_ASSERT_EQUAL_INT(iReg, op->p1);109  TEST_ASSERT_EQUAL_INT((int)strlen(aff), op->p2);110  /* The affinity string may be stored with exact length; compare prefix */111  TEST_ASSERT_NOT_NULL(op->p4.z);112  TEST_ASSERT_EQUAL_INT(0, strncmp(op->p4.z, aff, (int)strlen(aff)));113 114  sqlite3VdbeDelete(v);115}116 117/* Legacy (non-STRICT), iReg==0: set P4 of existing MakeRecord to affinity string */118void test_sqlite3TableAffinity_legacy_iReg0_sets_affinity_on_MakeRecord_p4(void){119  Vdbe *v = newVdbe();120 121  Table tab;122  memset(&tab, 0, sizeof(tab));123  tab.tabFlags = 0; /* legacy */124  const char *aff = "BCD"; /* TEXT/NUMERIC/INTEGER affinity codes mapping from comments */125  tab.zColAff = (char*)aff;126 127  /* Seed a MakeRecord */128  int addr = sqlite3VdbeAddOp3(v, OP_MakeRecord, 1, 2, 3);129  TEST_ASSERT_TRUE(addr >= 0);130 131  sqlite3TableAffinity(v, &tab, 0);132 133  VdbeOp *op = sqlite3VdbeGetOp(v, addr);134  TEST_ASSERT_NOT_NULL(op);135  TEST_ASSERT_EQUAL_INT(OP_MakeRecord, op->opcode);136  TEST_ASSERT_NOT_NULL(op->p4.z);137  TEST_ASSERT_EQUAL_INT(0, strncmp(op->p4.z, aff, (int)strlen(aff)));138 139  sqlite3VdbeDelete(v);140}141 142/* Legacy (non-STRICT), empty affinity string => no-op (do not alter previous op or P4) */143void test_sqlite3TableAffinity_legacy_empty_affinity_noop(void){144  Vdbe *v = newVdbe();145 146  Table tab;147  memset(&tab, 0, sizeof(tab));148  tab.tabFlags = 0; /* legacy */149  const char *aff = ""; /* empty -> no-op */150  tab.zColAff = (char*)aff;151 152  /* Seed a MakeRecord without P4 */153  int addr = sqlite3VdbeAddOp3(v, OP_MakeRecord, 5, 6, 7);154  TEST_ASSERT_TRUE(addr >= 0);155 156  /* Capture initial p4type (should be 0 / none) */157  VdbeOp *before = sqlite3VdbeGetOp(v, addr);158  TEST_ASSERT_NOT_NULL(before);159  unsigned char p4type_before = before->p4type;160  void *p4ptr_before = before->p4.p;161 162  sqlite3TableAffinity(v, &tab, 0);163 164  VdbeOp *after = sqlite3VdbeGetOp(v, addr);165  TEST_ASSERT_NOT_NULL(after);166  TEST_ASSERT_EQUAL_INT(OP_MakeRecord, after->opcode);167  TEST_ASSERT_EQUAL_UINT8(p4type_before, after->p4type);168  TEST_ASSERT_EQUAL_PTR(p4ptr_before, after->p4.p);169 170  sqlite3VdbeDelete(v);171}172 173int main(void) {174  UNITY_BEGIN();175  RUN_TEST(test_sqlite3TableAffinity_strict_iReg0_inserts_TypeCheck_before_MakeRecord);176  RUN_TEST(test_sqlite3TableAffinity_strict_with_registers_adds_TypeCheck_with_p4_table);177  RUN_TEST(test_sqlite3TableAffinity_legacy_iReg_sets_Affinity_on_registers);178  RUN_TEST(test_sqlite3TableAffinity_legacy_iReg0_sets_affinity_on_MakeRecord_p4);179  RUN_TEST(test_sqlite3TableAffinity_legacy_empty_affinity_noop);180  return UNITY_END();181}