Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_insert_sqlite3SetMakeRecordP5.c294 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Global DB handle for tests */7static sqlite3 *gdb = NULL;8 9static Vdbe* makeVdbeWithMakeRecord(Parse *pParse, int *pAddr){10  Vdbe *v = sqlite3VdbeCreate(pParse);11  TEST_ASSERT_NOT_NULL_MESSAGE(v, "Failed to create Vdbe");12  int addr = sqlite3VdbeAddOp3(v, OP_MakeRecord, 0, 0, 0);13  if( pAddr ) *pAddr = addr;14  /* Sanity: ensure we added something */15  TEST_ASSERT_TRUE(addr >= 0);16  return v;17}18 19static VdbeOp* getOp(Vdbe *v, int addr){20  VdbeOp *op = sqlite3VdbeGetOp(v, addr);21  TEST_ASSERT_NOT_NULL_MESSAGE(op, "sqlite3VdbeGetOp returned NULL");22  return op;23}24 25void setUp(void) {26  int rc = sqlite3_open(":memory:", &gdb);27  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "Failed to open in-memory sqlite3 DB");28}29 30void tearDown(void) {31  if( gdb ){32    sqlite3_close(gdb);33    gdb = NULL;34  }35}36 37/* Helper to allocate and initialize a Table with N columns and a Schema with given file_format.38   Caller must sqlite3DbFree(gdb, t.aCol) after use if allocated. */39static void initTableAndSchema(Table *pTab, Schema *pSchema, int nCol, int file_format){40  memset(pTab, 0, sizeof(*pTab));41  memset(pSchema, 0, sizeof(*pSchema));42  pSchema->file_format = file_format;43  pTab->pSchema = pSchema;44  pTab->nCol = (u16)nCol;45  pTab->aCol = (Column*)sqlite3DbMallocZero(gdb, sizeof(Column) * (nCol>0?nCol:1));46  TEST_ASSERT_NOT_NULL_MESSAGE(pTab->aCol, "Failed to allocate columns");47}48 49/* Test: file_format < 2 leaves P5 unchanged */50void test_sqlite3SetMakeRecordP5_file_format_lt2_leaves_p5_unchanged(void){51  Parse parse;52  memset(&parse, 0, sizeof(parse));53  parse.db = gdb;54 55  int addr = -1;56  Vdbe *v = makeVdbeWithMakeRecord(&parse, &addr);57 58  /* Pre-set P5 to a sentinel to verify it does not change */59  sqlite3VdbeChangeP5(v, (u16)77);60 61  Schema s;62  Table t;63  initTableAndSchema(&t, &s, 4, 1); /* file_format < 2 */64 65  /* Populate columns with no defaults/PKs; shouldn't matter due to early return */66  for(int i=0; i<4; i++){67    t.aCol[i].iDflt = 0;68    t.aCol[i].colFlags = 0;69  }70 71  sqlite3SetMakeRecordP5(v, &t);72 73  VdbeOp *op = getOp(v, addr);74  TEST_ASSERT_EQUAL_INT(OP_MakeRecord, op->opcode);75  TEST_ASSERT_EQUAL_UINT8(77, op->p5);76 77  sqlite3DbFree(gdb, t.aCol);78  sqlite3VdbeDelete(v);79}80 81/* Test: No defaults or PKs -> P5 becomes 1 */82void test_sqlite3SetMakeRecordP5_no_defaults_no_pk_sets_p5_1(void){83  Parse parse;84  memset(&parse, 0, sizeof(parse));85  parse.db = gdb;86 87  int addr;88  Vdbe *v = makeVdbeWithMakeRecord(&parse, &addr);89 90  Schema s;91  Table t;92  initTableAndSchema(&t, &s, 5, 4); /* file_format >= 2 */93  for(int i=0; i<5; i++){94    t.aCol[i].iDflt = 0;95    t.aCol[i].colFlags = 0;96  }97 98  sqlite3SetMakeRecordP5(v, &t);99 100  VdbeOp *op = getOp(v, addr);101  TEST_ASSERT_EQUAL_INT(OP_MakeRecord, op->opcode);102  TEST_ASSERT_EQUAL_UINT8(1, op->p5);103 104  sqlite3DbFree(gdb, t.aCol);105  sqlite3VdbeDelete(v);106}107 108/* Test: Last column has default -> P5 = nCol */109void test_sqlite3SetMakeRecordP5_last_col_default_sets_p5_ncol(void){110  Parse parse;111  memset(&parse, 0, sizeof(parse));112  parse.db = gdb;113 114  int addr;115  Vdbe *v = makeVdbeWithMakeRecord(&parse, &addr);116 117  const int N = 5;118  Schema s;119  Table t;120  initTableAndSchema(&t, &s, N, 4);121  for(int i=0; i<N; i++){122    t.aCol[i].iDflt = 0;123    t.aCol[i].colFlags = 0;124  }125  t.aCol[N-1].iDflt = 1; /* rightmost column has default */126 127  sqlite3SetMakeRecordP5(v, &t);128 129  VdbeOp *op = getOp(v, addr);130  TEST_ASSERT_EQUAL_INT(OP_MakeRecord, op->opcode);131  TEST_ASSERT_EQUAL_UINT8(N, op->p5);132 133  sqlite3DbFree(gdb, t.aCol);134  sqlite3VdbeDelete(v);135}136 137/* Test: Middle column has default -> P5 = index+1 */138void test_sqlite3SetMakeRecordP5_middle_col_default_sets_p5_index_plus_1(void){139  Parse parse;140  memset(&parse, 0, sizeof(parse));141  parse.db = gdb;142 143  int addr;144  Vdbe *v = makeVdbeWithMakeRecord(&parse, &addr);145 146  const int N = 6;147  const int idx = 3; /* zero-based index of default-bearing column */148  Schema s;149  Table t;150  initTableAndSchema(&t, &s, N, 4);151  for(int i=0; i<N; i++){152    t.aCol[i].iDflt = 0;153    t.aCol[i].colFlags = 0;154  }155  t.aCol[idx].iDflt = 1;156 157  sqlite3SetMakeRecordP5(v, &t);158 159  VdbeOp *op = getOp(v, addr);160  TEST_ASSERT_EQUAL_INT(OP_MakeRecord, op->opcode);161  TEST_ASSERT_EQUAL_UINT8(idx+1, op->p5);162 163  sqlite3DbFree(gdb, t.aCol);164  sqlite3VdbeDelete(v);165}166 167/* Test: Primary key flag in a column -> P5 = index+1 */168void test_sqlite3SetMakeRecordP5_pk_flag_sets_p5_index_plus_1(void){169  Parse parse;170  memset(&parse, 0, sizeof(parse));171  parse.db = gdb;172 173  int addr;174  Vdbe *v = makeVdbeWithMakeRecord(&parse, &addr);175 176  const int N = 4;177  const int pkIdx = 2;178  Schema s;179  Table t;180  initTableAndSchema(&t, &s, N, 4);181  for(int i=0; i<N; i++){182    t.aCol[i].iDflt = 0;183    t.aCol[i].colFlags = 0;184  }185  t.aCol[pkIdx].colFlags |= COLFLAG_PRIMKEY;186 187  sqlite3SetMakeRecordP5(v, &t);188 189  VdbeOp *op = getOp(v, addr);190  TEST_ASSERT_EQUAL_INT(OP_MakeRecord, op->opcode);191  TEST_ASSERT_EQUAL_UINT8(pkIdx+1, op->p5);192 193  sqlite3DbFree(gdb, t.aCol);194  sqlite3VdbeDelete(v);195}196 197/* Test: Only first column has default -> P5 should be 1 */198void test_sqlite3SetMakeRecordP5_only_first_col_default_results_in_p5_1(void){199  Parse parse;200  memset(&parse, 0, sizeof(parse));201  parse.db = gdb;202 203  int addr;204  Vdbe *v = makeVdbeWithMakeRecord(&parse, &addr);205 206  const int N = 5;207  Schema s;208  Table t;209  initTableAndSchema(&t, &s, N, 4);210  for(int i=0; i<N; i++){211    t.aCol[i].iDflt = 0;212    t.aCol[i].colFlags = 0;213  }214  t.aCol[0].iDflt = 1; /* default only on first column */215 216  sqlite3SetMakeRecordP5(v, &t);217 218  VdbeOp *op = getOp(v, addr);219  TEST_ASSERT_EQUAL_INT(OP_MakeRecord, op->opcode);220  TEST_ASSERT_EQUAL_UINT8(1, op->p5);221 222  sqlite3DbFree(gdb, t.aCol);223  sqlite3VdbeDelete(v);224}225 226/* Test: Single-column table -> P5 should be 1 */227void test_sqlite3SetMakeRecordP5_single_column_table_p5_1(void){228  Parse parse;229  memset(&parse, 0, sizeof(parse));230  parse.db = gdb;231 232  int addr;233  Vdbe *v = makeVdbeWithMakeRecord(&parse, &addr);234 235  const int N = 1;236  Schema s;237  Table t;238  initTableAndSchema(&t, &s, N, 4);239  t.aCol[0].iDflt = 0;240  t.aCol[0].colFlags = 0;241 242  sqlite3SetMakeRecordP5(v, &t);243 244  VdbeOp *op = getOp(v, addr);245  TEST_ASSERT_EQUAL_INT(OP_MakeRecord, op->opcode);246  TEST_ASSERT_EQUAL_UINT8(1, op->p5);247 248  sqlite3DbFree(gdb, t.aCol);249  sqlite3VdbeDelete(v);250}251 252/* Test: Multiple flagged columns; rightmost flagged dictates P5 */253void test_sqlite3SetMakeRecordP5_rightmost_flagged_column_dominates(void){254  Parse parse;255  memset(&parse, 0, sizeof(parse));256  parse.db = gdb;257 258  int addr;259  Vdbe *v = makeVdbeWithMakeRecord(&parse, &addr);260 261  const int N = 5;262  Schema s;263  Table t;264  initTableAndSchema(&t, &s, N, 4);265  for(int i=0; i<N; i++){266    t.aCol[i].iDflt = 0;267    t.aCol[i].colFlags = 0;268  }269  /* Set multiple flags: col 2 has PK, col 4 has default. Rightmost (4) should win -> P5=5 */270  t.aCol[2].colFlags |= COLFLAG_PRIMKEY;271  t.aCol[4].iDflt = 1;272 273  sqlite3SetMakeRecordP5(v, &t);274 275  VdbeOp *op = getOp(v, addr);276  TEST_ASSERT_EQUAL_INT(OP_MakeRecord, op->opcode);277  TEST_ASSERT_EQUAL_UINT8(5, op->p5);278 279  sqlite3DbFree(gdb, t.aCol);280  sqlite3VdbeDelete(v);281}282 283int main(void) {284  UNITY_BEGIN();285  RUN_TEST(test_sqlite3SetMakeRecordP5_file_format_lt2_leaves_p5_unchanged);286  RUN_TEST(test_sqlite3SetMakeRecordP5_no_defaults_no_pk_sets_p5_1);287  RUN_TEST(test_sqlite3SetMakeRecordP5_last_col_default_sets_p5_ncol);288  RUN_TEST(test_sqlite3SetMakeRecordP5_middle_col_default_sets_p5_index_plus_1);289  RUN_TEST(test_sqlite3SetMakeRecordP5_pk_flag_sets_p5_index_plus_1);290  RUN_TEST(test_sqlite3SetMakeRecordP5_only_first_col_default_results_in_p5_1);291  RUN_TEST(test_sqlite3SetMakeRecordP5_single_column_table_p5_1);292  RUN_TEST(test_sqlite3SetMakeRecordP5_rightmost_flagged_column_dominates);293  return UNITY_END();294}