AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6static sqlite3 *gDb = NULL;7 8/* UDFs that invoke the target wrapper with different isFinal settings */9static void x_call_jsonArrayCompute_final(sqlite3_context *ctx, int argc, sqlite3_value **argv){10 UNUSED_PARAMETER(argc);11 UNUSED_PARAMETER(argv);12 /* In a scalar function context, there is no aggregate context, so13 jsonArrayCompute should return "[]" with JSON subtype. */14 test_jsonArrayCompute(ctx, 1);15}16static void x_call_jsonArrayCompute_value(sqlite3_context *ctx, int argc, sqlite3_value **argv){17 UNUSED_PARAMETER(argc);18 UNUSED_PARAMETER(argv);19 test_jsonArrayCompute(ctx, 0);20}21static void x_call_jsonArrayCompute_final_blob(sqlite3_context *ctx, int argc, sqlite3_value **argv){22 UNUSED_PARAMETER(argc);23 UNUSED_PARAMETER(argv);24 /* User-data (JSON_BLOB) is set at registration time. Since there is25 no aggregate context, it should still return "[]" as TEXT. */26 test_jsonArrayCompute(ctx, 1);27}28 29/* Helpers to execute a scalar SELECT and capture single-row, single-column result */30static void execAndCheckTextAndSubtype(sqlite3 *db, const char *sql, const char *expect){31 sqlite3_stmt *stmt = NULL;32 int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);33 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "prepare failed");34 rc = sqlite3_step(stmt);35 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_ROW, rc, "expected one row");36 int type = sqlite3_column_type(stmt, 0);37 TEST_ASSERT_EQUAL_INT(SQLITE_TEXT, type);38 const unsigned char *z = sqlite3_column_text(stmt, 0);39 int n = sqlite3_column_bytes(stmt, 0);40 TEST_ASSERT_NOT_NULL(z);41 TEST_ASSERT_EQUAL_INT((int)strlen(expect), n);42 TEST_ASSERT_EQUAL_STRING(expect, (const char*)z);43 /* Verify JSON subtype is set */44 int subtype = sqlite3_column_subtype(stmt, 0);45 TEST_ASSERT_EQUAL_INT(JSON_SUBTYPE, subtype);46 rc = sqlite3_step(stmt);47 TEST_ASSERT_EQUAL_INT(SQLITE_DONE, rc);48 sqlite3_finalize(stmt);49}50 51void setUp(void) {52 int rc = sqlite3_open(":memory:", &gDb);53 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed");54 /* Register scalar wrappers that call the target function */55 rc = sqlite3_create_function(gDb, "call_jsonArrayCompute_final", 0, SQLITE_UTF8, NULL,56 x_call_jsonArrayCompute_final, NULL, NULL);57 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);58 rc = sqlite3_create_function(gDb, "call_jsonArrayCompute_value", 0, SQLITE_UTF8, NULL,59 x_call_jsonArrayCompute_value, NULL, NULL);60 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);61 /* Register variant with JSON_BLOB flag in user-data */62 rc = sqlite3_create_function(gDb, "call_jsonArrayCompute_final_blob", 0, SQLITE_UTF8,63 SQLITE_INT_TO_PTR(JSON_BLOB),64 x_call_jsonArrayCompute_final_blob, NULL, NULL);65 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);66}67 68void tearDown(void) {69 if( gDb ){70 sqlite3_close(gDb);71 gDb = NULL;72 }73}74 75/* Tests */76 77void test_jsonArrayCompute_noAggContext_final_returnsEmptyArrayAndSubtype(void){78 execAndCheckTextAndSubtype(gDb, "SELECT call_jsonArrayCompute_final()", "[]");79}80 81void test_jsonArrayCompute_noAggContext_value_returnsEmptyArrayAndSubtype(void){82 execAndCheckTextAndSubtype(gDb, "SELECT call_jsonArrayCompute_value()", "[]");83}84 85void test_jsonArrayCompute_blobFlagIgnoredWithoutContext(void){86 /* Even with JSON_BLOB flag set via user-data, without aggregate context87 the function must return [] as TEXT with JSON subtype. */88 execAndCheckTextAndSubtype(gDb, "SELECT call_jsonArrayCompute_final_blob()", "[]");89}90 91int main(void) {92 UNITY_BEGIN();93 RUN_TEST(test_jsonArrayCompute_noAggContext_final_returnsEmptyArrayAndSubtype);94 RUN_TEST(test_jsonArrayCompute_noAggContext_value_returnsEmptyArrayAndSubtype);95 RUN_TEST(test_jsonArrayCompute_blobFlagIgnoredWithoutContext);96 return UNITY_END();97}