Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_main_sqlite3_create_function16.c209 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5#include <stdint.h>6 7/* Helper: Build a UTF-16 native-endian string from a UTF-8 (ASCII) C-string.8** Returns malloc'd buffer that must be freed by caller. */9static void *make_utf16_native(const char *z){10  size_t n = strlen(z);11  /* Allocate 2 bytes per character + 2 bytes for terminator */12  unsigned char *buf = (unsigned char*)sqlite3_malloc64((n + 1) * 2);13  TEST_ASSERT_NOT_NULL_MESSAGE(buf, "Failed to allocate UTF16 buffer");14  /* Determine endianness */15  union { uint16_t s; unsigned char b[2]; } u;16  u.s = 0x0102;17  int is_be = (u.b[0] == 0x01);18 19  for(size_t i=0; i<n; i++){20    unsigned char c = (unsigned char)z[i];21    if( is_be ){22      buf[2*i+0] = 0x00;23      buf[2*i+1] = c;24    }else{25      buf[2*i+0] = c;26      buf[2*i+1] = 0x00;27    }28  }29  /* Terminator */30  buf[2*n+0] = 0x00;31  buf[2*n+1] = 0x00;32  return (void*)buf;33}34 35/* Scalar function: add 1 to integer argument, or return NULL if arg is NULL */36static void xAdd1(sqlite3_context *ctx, int argc, sqlite3_value **argv){37  if( argc<1 || sqlite3_value_type(argv[0])==SQLITE_NULL ){38    sqlite3_result_null(ctx);39    return;40  }41  sqlite3_int64 v = sqlite3_value_int64(argv[0]);42  sqlite3_result_int64(ctx, v + 1);43}44 45/* Aggregate sum: sums integer values (NULLs treated as 0) */46static void xSumStep(sqlite3_context *ctx, int argc, sqlite3_value **argv){47  sqlite3_int64 *pSum = (sqlite3_int64*)sqlite3_aggregate_context(ctx, sizeof(sqlite3_int64));48  if( pSum==0 ) return; /* OOM handled by SQLite */49  if( argc>0 && sqlite3_value_type(argv[0])!=SQLITE_NULL ){50    *pSum += sqlite3_value_int64(argv[0]);51  }52}53static void xSumFinal(sqlite3_context *ctx){54  sqlite3_int64 *pSum = (sqlite3_int64*)sqlite3_aggregate_context(ctx, 0);55  if( pSum ){56    sqlite3_result_int64(ctx, *pSum);57  }else{58    sqlite3_result_int64(ctx, 0);59  }60}61 62void setUp(void) {63  /* no-op */64}65void tearDown(void) {66  /* no-op */67}68 69/* Helper: prepare single-step query returning single integer result.70   Asserts success and returns the int64 result. */71static sqlite3_int64 run_single_int64(sqlite3 *db, const char *sql){72  sqlite3_stmt *pStmt = 0;73  int rc = sqlite3_prepare_v2(db, sql, -1, &pStmt, 0);74  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, sqlite3_errmsg(db));75  rc = sqlite3_step(pStmt);76  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_ROW, rc, "Expected one row");77  sqlite3_int64 v = sqlite3_column_int64(pStmt, 0);78  rc = sqlite3_step(pStmt);79  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_DONE, rc, "Expected exactly one row");80  sqlite3_finalize(pStmt);81  return v;82}83 84void test_sqlite3_create_function16_scalar_ok(void){85  sqlite3 *db = 0;86  int rc = sqlite3_open(":memory:", &db);87  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);88 89  void *name16 = make_utf16_native("x_add1");90  rc = sqlite3_create_function16(91    db, name16, 1, SQLITE_UTF8 | SQLITE_DETERMINISTIC,92    NULL, xAdd1, NULL, NULL93  );94  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);95 96  sqlite3_int64 v = run_single_int64(db, "SELECT x_add1(41)");97  TEST_ASSERT_EQUAL_INT64(42, v);98 99  sqlite3_free(name16);100  sqlite3_close(db);101}102 103void test_sqlite3_create_function16_aggregate_ok(void){104  sqlite3 *db = 0;105  int rc = sqlite3_open(":memory:", &db);106  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);107 108  void *name16 = make_utf16_native("mysum");109  rc = sqlite3_create_function16(110    db, name16, 1, SQLITE_UTF8, NULL, NULL, xSumStep, xSumFinal111  );112  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);113 114  sqlite3_int64 v = run_single_int64(db,115    "SELECT mysum(x) FROM (VALUES(1),(2),(3)) AS t(x)"116  );117  TEST_ASSERT_EQUAL_INT64(6, v);118 119  sqlite3_free(name16);120  sqlite3_close(db);121}122 123void test_sqlite3_create_function16_misuse_flags(void){124  sqlite3 *db = 0;125  int rc = sqlite3_open(":memory:", &db);126  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);127 128  /* Both xSFunc and xFinal non-NULL is misuse */129  void *name16a = make_utf16_native("badfunc1");130  rc = sqlite3_create_function16(131    db, name16a, 1, SQLITE_UTF8, NULL, xAdd1, NULL, xSumFinal132  );133  TEST_ASSERT_EQUAL_INT(SQLITE_MISUSE, rc);134  sqlite3_free(name16a);135 136  /* xStep without xFinal is misuse */137  void *name16b = make_utf16_native("badfunc2");138  rc = sqlite3_create_function16(139    db, name16b, 1, SQLITE_UTF8, NULL, NULL, xSumStep, NULL140  );141  TEST_ASSERT_EQUAL_INT(SQLITE_MISUSE, rc);142  sqlite3_free(name16b);143 144  sqlite3_close(db);145}146 147void test_sqlite3_create_function16_nArg_invalid(void){148  sqlite3 *db = 0;149  int rc = sqlite3_open(":memory:", &db);150  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);151 152  /* nArg < -1 is invalid */153  void *name16 = make_utf16_native("negarg");154  rc = sqlite3_create_function16(155    db, name16, -2, SQLITE_UTF8, NULL, xAdd1, NULL, NULL156  );157  TEST_ASSERT_EQUAL_INT(SQLITE_MISUSE, rc);158  sqlite3_free(name16);159 160  sqlite3_close(db);161}162 163void test_sqlite3_create_function16_delete_function(void){164  sqlite3 *db = 0;165  int rc = sqlite3_open(":memory:", &db);166  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);167 168  void *name16 = make_utf16_native("toDelete");169 170  /* Create */171  rc = sqlite3_create_function16(172    db, name16, 1, SQLITE_UTF8, NULL, xAdd1, NULL, NULL173  );174  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);175 176  /* Verify works */177  sqlite3_int64 v = run_single_int64(db, "SELECT toDelete(5)");178  TEST_ASSERT_EQUAL_INT64(6, v);179 180  /* Delete by passing NULL xSFunc and NULL xFinal */181  rc = sqlite3_create_function16(182    db, name16, 1, SQLITE_UTF8, NULL, NULL, NULL, NULL183  );184  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);185 186  /* Now preparing a statement that uses the deleted function should fail */187  sqlite3_stmt *pStmt = 0;188  rc = sqlite3_prepare_v2(db, "SELECT toDelete(5)", -1, &pStmt, 0);189  TEST_ASSERT_NOT_EQUAL_MESSAGE(SQLITE_OK, rc, "Expected error preparing unknown function");190  if( pStmt ) sqlite3_finalize(pStmt);191 192  /* Error message should mention 'no such function' */193  const char *zErr = sqlite3_errmsg(db);194  TEST_ASSERT_NOT_NULL(zErr);195  TEST_ASSERT_NOT_NULL_MESSAGE(strstr(zErr, "no such function"), "Expected 'no such function' in error message");196 197  sqlite3_free(name16);198  sqlite3_close(db);199}200 201int main(void){202  UNITY_BEGIN();203  RUN_TEST(test_sqlite3_create_function16_scalar_ok);204  RUN_TEST(test_sqlite3_create_function16_aggregate_ok);205  RUN_TEST(test_sqlite3_create_function16_misuse_flags);206  RUN_TEST(test_sqlite3_create_function16_nArg_invalid);207  RUN_TEST(test_sqlite3_create_function16_delete_function);208  return UNITY_END();209}