Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_main_sqlite3_overload_function.c176 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5#include <stdio.h>6 7/* Simple scalar function that returns constant 42 */8static void xConst42(sqlite3_context *ctx, int argc, sqlite3_value **argv){9  SQLITE_UNUSED_PARAMETER(argc);10  SQLITE_UNUSED_PARAMETER(argv);11  sqlite3_result_int(ctx, 42);12}13 14/* Scalar function that returns the argc it was called with */15static void xCountArgs(sqlite3_context *ctx, int argc, sqlite3_value **argv){16  SQLITE_UNUSED_PARAMETER(argv);17  sqlite3_result_int(ctx, argc);18}19 20void setUp(void) {21  /* no-op */22}23 24void tearDown(void) {25  /* no-op */26}27 28/* Helper: prepare, step once expecting a row, fetch first column int */29static int eval_single_int(sqlite3 *db, const char *sql, int *pOut){30  sqlite3_stmt *pStmt = 0;31  int rc = sqlite3_prepare_v2(db, sql, -1, &pStmt, 0);32  if( rc!=SQLITE_OK ) goto done;33  rc = sqlite3_step(pStmt);34  if( rc==SQLITE_ROW ){35    *pOut = sqlite3_column_int(pStmt, 0);36    rc = SQLITE_OK;37  }else{38    /* Return step rc if not a row */39  }40done:41  sqlite3_finalize(pStmt);42  return rc;43}44 45/* Test: If a function already exists, sqlite3_overload_function is a no-op */46void test_sqlite3_overload_function_noop_when_function_exists(void){47  sqlite3 *db = 0;48  int rc = sqlite3_open(":memory:", &db);49  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);50  TEST_ASSERT_NOT_NULL(db);51 52  /* Create a scalar function 'preexist' with 1 argument that returns 42 */53  rc = sqlite3_create_function(db, "preexist", 1, SQLITE_UTF8, 0, xConst42, 0, 0);54  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);55 56  /* Call sqlite3_overload_function — should be a no-op returning OK */57  rc = sqlite3_overload_function(db, "preexist", 1);58  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);59 60  /* Verify the function still behaves as the user-defined function */61  sqlite3_stmt *pStmt = 0;62  rc = sqlite3_prepare_v2(db, "SELECT preexist(7)", -1, &pStmt, 0);63  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);64  rc = sqlite3_step(pStmt);65  TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);66  TEST_ASSERT_EQUAL_INT(42, sqlite3_column_int(pStmt, 0));67  sqlite3_finalize(pStmt);68 69  sqlite3_close(db);70}71 72/* Test: Creating an overloaded function when none exists (fixed arity) */73void test_sqlite3_overload_function_creates_invalid_function_fixed_arity(void){74  sqlite3 *db = 0;75  int rc = sqlite3_open(":memory:", &db);76  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);77  TEST_ASSERT_NOT_NULL(db);78 79  /* No function 'ovfA' exists yet. Overload should create an invalid function. */80  rc = sqlite3_overload_function(db, "ovfA", 2);81  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);82 83  /* Prepare should succeed because name resolution finds the function */84  sqlite3_stmt *pStmt = 0;85  rc = sqlite3_prepare_v2(db, "SELECT ovfA(1, 2)", -1, &pStmt, 0);86  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);87 88  /* Execution should error because sqlite3InvalidFunction is used */89  rc = sqlite3_step(pStmt);90  TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);91  sqlite3_finalize(pStmt);92 93  /* Now define a real function with same name/arity and confirm it overrides */94  rc = sqlite3_create_function(db, "ovfA", 2, SQLITE_UTF8, 0, xCountArgs, 0, 0);95  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);96 97  int out = 0;98  rc = eval_single_int(db, "SELECT ovfA(10, 20)", &out);99  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);100  TEST_ASSERT_EQUAL_INT(2, out);101 102  sqlite3_close(db);103}104 105/* Test: Any-arity (-1) overloaded function is created and can be overridden */106void test_sqlite3_overload_function_creates_invalid_function_any_arity_and_can_be_overridden(void){107  sqlite3 *db = 0;108  int rc = sqlite3_open(":memory:", &db);109  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);110  TEST_ASSERT_NOT_NULL(db);111 112  /* Create any-arity overloaded function */113  rc = sqlite3_overload_function(db, "ovfAny", -1);114  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);115 116  /* Prepare should succeed for 0 args, but execution should error */117  sqlite3_stmt *pStmt = 0;118  rc = sqlite3_prepare_v2(db, "SELECT ovfAny()", -1, &pStmt, 0);119  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);120  rc = sqlite3_step(pStmt);121  TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);122  sqlite3_finalize(pStmt);123 124  /* Prepare with multiple args should also resolve, but execution should error */125  rc = sqlite3_prepare_v2(db, "SELECT ovfAny(1,2,3)", -1, &pStmt, 0);126  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);127  rc = sqlite3_step(pStmt);128  TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);129  sqlite3_finalize(pStmt);130 131  /* Override ovfAny with a real any-arity function that returns the arg count */132  rc = sqlite3_create_function(db, "ovfAny", -1, SQLITE_UTF8, 0, xCountArgs, 0, 0);133  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);134 135  int out = -1;136  rc = eval_single_int(db, "SELECT ovfAny(5,6,7,8)", &out);137  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);138  TEST_ASSERT_EQUAL_INT(4, out);139 140  sqlite3_close(db);141}142 143/* Test: Idempotent behavior when called again after prior overload creation */144void test_sqlite3_overload_function_idempotent_on_existing_invalid_function(void){145  sqlite3 *db = 0;146  int rc = sqlite3_open(":memory:", &db);147  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);148  TEST_ASSERT_NOT_NULL(db);149 150  /* First call creates the invalid function */151  rc = sqlite3_overload_function(db, "ovfB", 1);152  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);153 154  /* Second call should be a no-op and still return OK */155  rc = sqlite3_overload_function(db, "ovfB", 1);156  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);157 158  /* Behavior should remain the same: prepare OK, execution error */159  sqlite3_stmt *pStmt = 0;160  rc = sqlite3_prepare_v2(db, "SELECT ovfB(123)", -1, &pStmt, 0);161  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);162  rc = sqlite3_step(pStmt);163  TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);164  sqlite3_finalize(pStmt);165 166  sqlite3_close(db);167}168 169int main(void) {170  UNITY_BEGIN();171  RUN_TEST(test_sqlite3_overload_function_noop_when_function_exists);172  RUN_TEST(test_sqlite3_overload_function_creates_invalid_function_fixed_arity);173  RUN_TEST(test_sqlite3_overload_function_creates_invalid_function_any_arity_and_can_be_overridden);174  RUN_TEST(test_sqlite3_overload_function_idempotent_on_existing_invalid_function);175  return UNITY_END();176}