diff --git a/extension/json/json_functions/json_array_append.cpp b/extension/json/json_functions/json_array_append.cpp index 5ab2b48a0c83..d2cb2ce96603 100644 --- a/extension/json/json_functions/json_array_append.cpp +++ b/extension/json/json_functions/json_array_append.cpp @@ -3,8 +3,8 @@ namespace duckdb { //! Append String or JSON value to an array -yyjson_mut_val *ArrayAppendStringOrJSON(yyjson_mut_val *arr, yyjson_mut_doc *doc, string_t element, yyjson_alc *alc, - Vector &result) { +yyjson_mut_val *ArrayAppendJSON(yyjson_mut_val *arr, yyjson_mut_doc *doc, string_t element, yyjson_alc *alc, + Vector &result) { if (!yyjson_mut_is_arr(arr)) { throw InvalidInputException("JSON input not an JSON Array"); } @@ -16,108 +16,24 @@ yyjson_mut_val *ArrayAppendStringOrJSON(yyjson_mut_val *arr, yyjson_mut_doc *doc return arr; } -//! Append boolean value to an array -yyjson_mut_val *ArrayAppendBoolean(yyjson_mut_val *arr, yyjson_mut_doc *doc, bool element, yyjson_alc *alc, - Vector &result) { - if (!yyjson_mut_is_arr(arr)) { - throw InvalidInputException("JSON input not a JSON Array"); - } - - yyjson_mut_arr_add_bool(doc, arr, element); - return arr; -} - -//! Append unsigned Integers to an array -yyjson_mut_val *ArrayAppendUnsignedIntegers(yyjson_mut_val *arr, yyjson_mut_doc *doc, uint64_t element, yyjson_alc *alc, - Vector &result) { - if (!yyjson_mut_is_arr(arr)) { - throw InvalidInputException("JSON input not a JSON Array"); - } - - yyjson_mut_arr_add_uint(doc, arr, element); - return arr; -} - -//! Append signed Integers to an array -yyjson_mut_val *ArrayAppendSignedIntegers(yyjson_mut_val *arr, yyjson_mut_doc *doc, int64_t element, yyjson_alc *alc, - Vector &result) { - if (!yyjson_mut_is_arr(arr)) { - throw InvalidInputException("JSON input not a JSON Array"); - } - - yyjson_mut_arr_add_int(doc, arr, element); - return arr; -} - -//! Append floating values to an array -yyjson_mut_val *ArrayAppendFloating(yyjson_mut_val *arr, yyjson_mut_doc *doc, double element, yyjson_alc *alc, - Vector &result) { - if (!yyjson_mut_is_arr(arr)) { - throw InvalidInputException("JSON input not a JSON Array"); - } - - yyjson_mut_arr_add_real(doc, arr, element); - return arr; -} - //! Append function wrapper static void ArrayAppendFunction(DataChunk &args, ExpressionState &state, Vector &result) { auto left_type = args.data[0].GetType(); D_ASSERT(left_type == LogicalType::VARCHAR || left_type == LogicalType::JSON()); - auto right_type = args.data[1].GetType(); + D_ASSERT(right_type == LogicalType::VARCHAR || right_type == LogicalType::JSON()); - switch (right_type.id()) { - case LogicalType::VARCHAR: - JSONExecutors::BinaryMutExecute(args, state, result, ArrayAppendStringOrJSON); - break; - case LogicalType::BOOLEAN: - JSONExecutors::BinaryMutExecute(args, state, result, ArrayAppendBoolean); - break; - case LogicalType::UBIGINT: - JSONExecutors::BinaryMutExecute(args, state, result, ArrayAppendUnsignedIntegers); - break; - case LogicalType::BIGINT: - JSONExecutors::BinaryMutExecute(args, state, result, ArrayAppendSignedIntegers); - break; - case LogicalType::DOUBLE: - JSONExecutors::BinaryMutExecute(args, state, result, ArrayAppendFloating); - break; - default: - // Shouldn't be thrown except implicit casting changes - throw InvalidInputException("Not a valid input type"); - } + JSONExecutors::BinaryMutExecute(args, state, result, ArrayAppendJSON); } static void GetArrayAppendFunctionInternal(ScalarFunctionSet &set, const LogicalType &lhs, const LogicalType &rhs) { - set.AddFunction(ScalarFunction("json_array_append", {lhs, rhs}, LogicalType::JSON(), ArrayAppendFunction, - nullptr, nullptr, nullptr, JSONFunctionLocalState::Init)); + set.AddFunction(ScalarFunction("json_array_append", {lhs, rhs}, LogicalType::JSON(), ArrayAppendFunction, nullptr, + nullptr, nullptr, JSONFunctionLocalState::Init)); } ScalarFunctionSet JSONFunctions::GetArrayAppendFunction() { ScalarFunctionSet set("json_array_append"); - - // Use different executor for these - // Allows booleans directly - // GetArrayAppendFunctionInternal(set, LogicalType::JSON(), LogicalType::BOOLEAN); - - // Allows for Integer types - // TINYINT, SMALLINT, INTEGER, UTINYINT, USMALLINT, UINTEGER are captured by UBIGINT and BIGINT respecively - // relies on consistant casting strategy upfront - - // unsigned - // GetArrayAppendFunctionInternal(set, LogicalType::JSON(), LogicalType::UBIGINT); - - // signed - // GetArrayAppendFunctionInternal(set, LogicalType::JSON(), LogicalType::BIGINT); - - // Allows for floating types - // FLOAT is covered by automatic upfront casting to double - // GetArrayAppendFunctionInternal(set, LogicalType::JSON(), LogicalType::DOUBLE); - - // Allows for json and string values GetArrayAppendFunctionInternal(set, LogicalType::JSON(), LogicalType::JSON()); - GetArrayAppendFunctionInternal(set, LogicalType::JSON(), LogicalType::VARCHAR); return set; } diff --git a/extension/json/json_functions/json_array_insert.cpp b/extension/json/json_functions/json_array_insert.cpp index 29495b95d4ba..309fd8abed55 100644 --- a/extension/json/json_functions/json_array_insert.cpp +++ b/extension/json/json_functions/json_array_insert.cpp @@ -3,8 +3,8 @@ namespace duckdb { //! Insert String or JSON value to an array -yyjson_mut_val *ArrayInsertStringOrJSON(yyjson_mut_val *arr, yyjson_mut_doc *doc, string_t element, int64_t idx, - yyjson_alc *alc, Vector &result) { +yyjson_mut_val *ArrayInsertJSON(yyjson_mut_val *arr, yyjson_mut_doc *doc, string_t element, int64_t idx, + yyjson_alc *alc, Vector &result) { if (!yyjson_mut_is_arr(arr)) { throw InvalidInputException("JSON input not an JSON Array"); } @@ -22,58 +22,16 @@ yyjson_mut_val *ArrayInsertStringOrJSON(yyjson_mut_val *arr, yyjson_mut_doc *doc return arr; } -//! Insert any yyjson_mut_ELEMENT_TYPE type and function -template -std::function -ArrayInsert(std::function fconvert) { - return [&](yyjson_mut_val *arr, yyjson_mut_doc *doc, ELEMENT_TYPE element, int64_t idx, yyjson_alc *alc, - Vector &result) { - if (!yyjson_mut_is_arr(arr)) { - throw InvalidInputException("JSON input not a JSON Array"); - } - - size_t index = DetermineArrayIndex(arr, idx); - - // Fill remaining indeces with null until element index - for (size_t entries = yyjson_mut_arr_size(arr); entries < index; ++entries) { - yyjson_mut_arr_add_null(doc, arr); - } - auto mut_value = fconvert(doc, element); - yyjson_mut_arr_insert(arr, mut_value, index); - return arr; - }; -} - //! Insert function wrapper static void ArrayInsertFunction(DataChunk &args, ExpressionState &state, Vector &result) { auto json_type = args.data[0].GetType(); D_ASSERT(json_type == LogicalType::VARCHAR || json_type == LogicalType::JSON()); + auto element_type = args.data[1].GetType(); + D_ASSERT(element_type == LogicalType::VARCHAR || element_type == LogicalType::JSON()); auto idx_type = args.data[2].GetType(); D_ASSERT(idx_type == LogicalType::BIGINT); - auto element_type = args.data[1].GetType(); - - switch (element_type.id()) { - case LogicalType::VARCHAR: - JSONExecutors::TernaryMutExecute(args, state, result, ArrayInsertStringOrJSON); - break; - case LogicalType::BOOLEAN: - JSONExecutors::TernaryMutExecute(args, state, result, ArrayInsert(yyjson_mut_bool)); - break; - case LogicalType::UBIGINT: - JSONExecutors::TernaryMutExecute(args, state, result, - ArrayInsert(yyjson_mut_uint)); - break; - case LogicalType::BIGINT: - JSONExecutors::TernaryMutExecute(args, state, result, ArrayInsert(yyjson_mut_sint)); - break; - case LogicalType::DOUBLE: - JSONExecutors::TernaryMutExecute(args, state, result, ArrayInsert(yyjson_mut_real)); - break; - default: - // Shouldn't be thrown except implicit casting changes - throw InvalidInputException("Not a valid input type"); - } + JSONExecutors::TernaryMutExecute(args, state, result, ArrayInsertJSON); } static void GetArrayInsertFunctionInternal(ScalarFunctionSet &set, const LogicalType &fst, const LogicalType &snd, @@ -84,28 +42,7 @@ static void GetArrayInsertFunctionInternal(ScalarFunctionSet &set, const Logical ScalarFunctionSet JSONFunctions::GetArrayInsertFunction() { ScalarFunctionSet set("json_array_insert"); - - // Use different executor for these - // Allows booleans directly - // GetArrayInsertFunctionInternal(set, LogicalType::JSON(), LogicalType::BOOLEAN, LogicalType::BIGINT); - - // Allows for Integer types - // TINYINT, SMALLINT, INTEGER, UTINYINT, USMALLINT, UINTEGER are captured by UBIGINT and BIGINT respecively - // relies on consistant casting strategy upfront - - // unsigned - // GetArrayInsertFunctionInternal(set, LogicalType::JSON(), LogicalType::UBIGINT, LogicalType::BIGINT); - - // signed - // GetArrayInsertFunctionInternal(set, LogicalType::JSON(), LogicalType::BIGINT, LogicalType::BIGINT); - - // Allows for floating types - // FLOAT is covered by automatic upfront casting to double - // GetArrayInsertFunctionInternal(set, LogicalType::JSON(), LogicalType::DOUBLE, LogicalType::BIGINT); - - // Allows for json and string values GetArrayInsertFunctionInternal(set, LogicalType::JSON(), LogicalType::JSON(), LogicalType::BIGINT); - GetArrayInsertFunctionInternal(set, LogicalType::JSON(), LogicalType::VARCHAR, LogicalType::BIGINT); return set; } diff --git a/extension/json/json_functions/json_array_prepend.cpp b/extension/json/json_functions/json_array_prepend.cpp index 8d3ffb579964..64839c690966 100644 --- a/extension/json/json_functions/json_array_prepend.cpp +++ b/extension/json/json_functions/json_array_prepend.cpp @@ -3,8 +3,8 @@ namespace duckdb { //! Prepend String or JSON value to an array -yyjson_mut_val *ArrayPrependStringOrJSON(yyjson_mut_val *arr, yyjson_mut_doc *doc, string_t element, yyjson_alc *alc, - Vector &result) { +yyjson_mut_val *ArrayPrependJSON(yyjson_mut_val *arr, yyjson_mut_doc *doc, string_t element, yyjson_alc *alc, + Vector &result) { if (!yyjson_mut_is_arr(arr)) { throw InvalidInputException("JSON input not an JSON Array"); } @@ -16,112 +16,24 @@ yyjson_mut_val *ArrayPrependStringOrJSON(yyjson_mut_val *arr, yyjson_mut_doc *do return arr; } -//! Prepend boolean value to an array -yyjson_mut_val *ArrayPrependBoolean(yyjson_mut_val *arr, yyjson_mut_doc *doc, bool element, yyjson_alc *alc, - Vector &result) { - if (!yyjson_mut_is_arr(arr)) { - throw InvalidInputException("JSON input not a JSON Array"); - } - - auto mut_value = yyjson_mut_bool(doc, element); - yyjson_mut_arr_prepend(arr, mut_value); - return arr; -} - -//! Prepend unsigned Integers to an array -yyjson_mut_val *ArrayPrependUnsignedIntegers(yyjson_mut_val *arr, yyjson_mut_doc *doc, uint64_t element, - yyjson_alc *alc, Vector &result) { - if (!yyjson_mut_is_arr(arr)) { - throw InvalidInputException("JSON input not a JSON Array"); - } - - auto mut_value = yyjson_mut_uint(doc, element); - yyjson_mut_arr_prepend(arr, mut_value); - return arr; -} - -//! Prepend signed Integers to an array -yyjson_mut_val *ArrayPrependSignedIntegers(yyjson_mut_val *arr, yyjson_mut_doc *doc, int64_t element, yyjson_alc *alc, - Vector &result) { - if (!yyjson_mut_is_arr(arr)) { - throw InvalidInputException("JSON input not a JSON Array"); - } - - auto mut_value = yyjson_mut_sint(doc, element); - yyjson_mut_arr_prepend(arr, mut_value); - return arr; -} - -//! Prepend floating values to an array -yyjson_mut_val *ArrayPrependFloating(yyjson_mut_val *arr, yyjson_mut_doc *doc, double element, yyjson_alc *alc, - Vector &result) { - if (!yyjson_mut_is_arr(arr)) { - throw InvalidInputException("JSON input not a JSON Array"); - } - - auto mut_value = yyjson_mut_real(doc, element); - yyjson_mut_arr_prepend(arr, mut_value); - return arr; -} - //! Prepend function wrapper static void ArrayPrependFunction(DataChunk &args, ExpressionState &state, Vector &result) { + auto left_type = args.data[0].GetType(); + D_ASSERT(left_type == LogicalType::VARCHAR || left_type == LogicalType::JSON()); auto right_type = args.data[1].GetType(); D_ASSERT(right_type == LogicalType::VARCHAR || right_type == LogicalType::JSON()); - auto left_type = args.data[0].GetType(); - - switch (left_type.id()) { - case LogicalType::VARCHAR: - JSONExecutors::BinaryMutExecuteFlip(args, state, result, ArrayPrependStringOrJSON); - break; - case LogicalType::BOOLEAN: - JSONExecutors::BinaryMutExecuteFlip(args, state, result, ArrayPrependBoolean); - break; - case LogicalType::UBIGINT: - JSONExecutors::BinaryMutExecuteFlip(args, state, result, ArrayPrependUnsignedIntegers); - break; - case LogicalType::BIGINT: - JSONExecutors::BinaryMutExecuteFlip(args, state, result, ArrayPrependSignedIntegers); - break; - case LogicalType::DOUBLE: - JSONExecutors::BinaryMutExecuteFlip(args, state, result, ArrayPrependFloating); - break; - default: - // Shouldn't be thrown except implicit casting changes - throw InvalidInputException("Not a valid input type"); - } + JSONExecutors::BinaryMutExecuteFlip(args, state, result, ArrayPrependJSON); } static void GetArrayPrependFunctionInternal(ScalarFunctionSet &set, const LogicalType &lhs, const LogicalType &rhs) { - set.AddFunction(ScalarFunction("json_array_prepend", {lhs, rhs}, LogicalType::JSON(), ArrayPrependFunction, - nullptr, nullptr, nullptr, JSONFunctionLocalState::Init)); + set.AddFunction(ScalarFunction("json_array_prepend", {lhs, rhs}, LogicalType::JSON(), ArrayPrependFunction, nullptr, + nullptr, nullptr, JSONFunctionLocalState::Init)); } ScalarFunctionSet JSONFunctions::GetArrayPrependFunction() { ScalarFunctionSet set("json_array_prepend"); - - // Use different executor for these - // Allows booleans directly - // GetArrayPrependFunctionInternal(set, LogicalType::BOOLEAN, LogicalType::JSON()); - - // Allows for Integer types - // TINYINT, SMALLINT, INTEGER, UTINYINT, USMALLINT, UINTEGER are captured by UBIGINT and BIGINT respecively - // relies on consistant casting strategy upfront - - // unsigned - // GetArrayPrependFunctionInternal(set, LogicalType::UBIGINT, LogicalType::JSON()); - - // signed - // GetArrayPrependFunctionInternal(set, LogicalType::BIGINT, LogicalType::JSON()); - - // Allows for floating types - // FLOAT is covered by automatic upfront casting to double - // GetArrayPrependFunctionInternal(set, LogicalType::DOUBLE, LogicalType::JSON()); - - // Allows for json and string values GetArrayPrependFunctionInternal(set, LogicalType::JSON(), LogicalType::JSON()); - GetArrayPrependFunctionInternal(set, LogicalType::VARCHAR, LogicalType::JSON()); return set; } diff --git a/extension/json/json_functions/json_array_remove.cpp b/extension/json/json_functions/json_array_remove.cpp index bf9ba092a3ea..84589c13f694 100644 --- a/extension/json/json_functions/json_array_remove.cpp +++ b/extension/json/json_functions/json_array_remove.cpp @@ -84,8 +84,8 @@ static void GetArrayRemoveElementFunctionInternal(ScalarFunctionSet &set, const static void GetArrayRemoveRangeFunctionInternal(ScalarFunctionSet &set, const LogicalType &fst, const LogicalType &snd, const LogicalType &thrd) { - set.AddFunction(ScalarFunction("json_array_remove", {fst, snd, thrd}, LogicalType::JSON(), - ArrayRemoveRangeFunction, nullptr, nullptr, nullptr, JSONFunctionLocalState::Init)); + set.AddFunction(ScalarFunction("json_array_remove", {fst, snd, thrd}, LogicalType::JSON(), ArrayRemoveRangeFunction, + nullptr, nullptr, nullptr, JSONFunctionLocalState::Init)); } ScalarFunctionSet JSONFunctions::GetArrayRemoveFunction() { diff --git a/extension/json/json_functions/json_array_rotate.cpp b/extension/json/json_functions/json_array_rotate.cpp index e6d777afe68d..247e099b1d23 100644 --- a/extension/json/json_functions/json_array_rotate.cpp +++ b/extension/json/json_functions/json_array_rotate.cpp @@ -49,8 +49,8 @@ static void ArrayRotateFunction(DataChunk &args, ExpressionState &state, Vector } static void GetArrayRotateFunctionInternal(ScalarFunctionSet &set, const LogicalType &fst, const LogicalType &snd) { - set.AddFunction(ScalarFunction("json_array_rotate", {fst, snd}, LogicalType::JSON(), ArrayRotateFunction, - nullptr, nullptr, nullptr, JSONFunctionLocalState::Init)); + set.AddFunction(ScalarFunction("json_array_rotate", {fst, snd}, LogicalType::JSON(), ArrayRotateFunction, nullptr, + nullptr, nullptr, JSONFunctionLocalState::Init)); } ScalarFunctionSet JSONFunctions::GetArrayRotateFunction() { diff --git a/extension/json/json_functions/json_object_add.cpp b/extension/json/json_functions/json_object_add.cpp index 7c49c673a82c..c99dc88ef4cc 100644 --- a/extension/json/json_functions/json_object_add.cpp +++ b/extension/json/json_functions/json_object_add.cpp @@ -3,8 +3,8 @@ namespace duckdb { //! Add a JSON Object or String to an object -yyjson_mut_val *ObjectAddStringOrJSON(yyjson_mut_val *obj, yyjson_mut_doc *doc, string_t key, string_t value, - yyjson_alc *alc, Vector &result) { +yyjson_mut_val *ObjectAddJSON(yyjson_mut_val *obj, yyjson_mut_doc *doc, string_t key, string_t value, yyjson_alc *alc, + Vector &result) { if (!yyjson_mut_is_obj(obj)) { throw InvalidInputException("JSON input not an JSON Object"); } @@ -19,56 +19,16 @@ yyjson_mut_val *ObjectAddStringOrJSON(yyjson_mut_val *obj, yyjson_mut_doc *doc, return obj; } -//! Add any yyjson_mut_ELEMENT_TYPE type and function -template -std::function -ObjectAdd(std::function fconvert) { - return [&](yyjson_mut_val *obj, yyjson_mut_doc *doc, string_t key, ELEMENT_TYPE element, yyjson_alc *alc, - Vector &result) { - if (!yyjson_mut_is_obj(obj)) { - throw InvalidInputException("JSON input not an JSON Object"); - } - - const char *_key = key.GetDataWriteable(); - auto mut_key = yyjson_mut_strcpy(doc, _key); - auto k = yyjson_mut_get_str(mut_key); - - auto mut_value = fconvert(doc, element); - yyjson_mut_obj_add_val(doc, obj, k, mut_value); - return obj; - }; -} - //! Add key-value pairs to a json object static void ObjectAddFunction(DataChunk &args, ExpressionState &state, Vector &result) { auto obj_type = args.data[0].GetType(); D_ASSERT(obj_type == LogicalType::VARCHAR || obj_type == LogicalType::JSON()); auto first_type = args.data[1].GetType(); D_ASSERT(first_type == LogicalType::VARCHAR); - auto second_type = args.data[2].GetType(); + D_ASSERT(second_type == LogicalType::JSON()); - switch (second_type.id()) { - case LogicalType::VARCHAR: - JSONExecutors::TernaryMutExecute(args, state, result, ObjectAddStringOrJSON); - break; - case LogicalType::BOOLEAN: - JSONExecutors::TernaryMutExecute(args, state, result, ObjectAdd(yyjson_mut_bool)); - break; - case LogicalType::UBIGINT: - JSONExecutors::TernaryMutExecute(args, state, result, - ObjectAdd(yyjson_mut_uint)); - break; - case LogicalType::BIGINT: - JSONExecutors::TernaryMutExecute(args, state, result, ObjectAdd(yyjson_mut_sint)); - break; - case LogicalType::DOUBLE: - JSONExecutors::TernaryMutExecute(args, state, result, ObjectAdd(yyjson_mut_real)); - break; - default: - // Shouldn't be thrown except implicit casting changes - throw InvalidInputException("Not a valid input type"); - } + JSONExecutors::TernaryMutExecute(args, state, result, ObjectAddJSON); } static void GetObjectAddFunctionInternal(ScalarFunctionSet &set, const LogicalType &obj, const LogicalType &first, @@ -79,26 +39,7 @@ static void GetObjectAddFunctionInternal(ScalarFunctionSet &set, const LogicalTy ScalarFunctionSet JSONFunctions::GetObjectAddFunction() { ScalarFunctionSet set("json_obj_add"); - - // Use different executor for these - - // Boolean - // GetObjectAddFunctionInternal(set, LogicalType::JSON(), LogicalType::VARCHAR, LogicalType::BOOLEAN); - - // Integer Types - - // unsigned - // GetObjectAddFunctionInternal(set, LogicalType::JSON(), LogicalType::VARCHAR, LogicalType::UBIGINT); - - // signed - // GetObjectAddFunctionInternal(set, LogicalType::JSON(), LogicalType::VARCHAR, LogicalType::BIGINT); - - // Floating Types - // GetObjectAddFunctionInternal(set, LogicalType::JSON(), LogicalType::VARCHAR, LogicalType::DOUBLE); - - // JSON values GetObjectAddFunctionInternal(set, LogicalType::JSON(), LogicalType::VARCHAR, LogicalType::JSON()); - // GetObjectAddFunctionInternal(set, LogicalType::JSON(), LogicalType::VARCHAR, LogicalType::VARCHAR); return set; } diff --git a/extension/json/json_functions/json_object_replace.cpp b/extension/json/json_functions/json_object_replace.cpp index f3b8da2bdc72..9d3b4eed999a 100644 --- a/extension/json/json_functions/json_object_replace.cpp +++ b/extension/json/json_functions/json_object_replace.cpp @@ -3,8 +3,8 @@ namespace duckdb { //! Replace String or JSON value of a key in JSON object -yyjson_mut_val *ObjectReplaceStringOrJSON(yyjson_mut_val *obj, yyjson_mut_doc *doc, string_t key, string_t element, - yyjson_alc *alc, Vector &result) { +yyjson_mut_val *ObjectReplaceJSON(yyjson_mut_val *obj, yyjson_mut_doc *doc, string_t key, string_t element, + yyjson_alc *alc, Vector &result) { if (!yyjson_mut_is_obj(obj)) { throw InvalidInputException("JSON input not an JSON Object"); } @@ -19,88 +19,27 @@ yyjson_mut_val *ObjectReplaceStringOrJSON(yyjson_mut_val *obj, yyjson_mut_doc *d return obj; } -//! Replace any yyjson_mut_ELEMENT_TYPE and function -template -std::function -ObjectReplace(std::function fconvert) { - return [&](yyjson_mut_val *obj, yyjson_mut_doc *doc, string_t key, ELEMENT_TYPE value, yyjson_alc *alc, - Vector &result) { - if (!yyjson_mut_is_obj(obj)) { - throw InvalidInputException("JSON input not an JSON Object"); - } - - const char *_key = key.GetDataWriteable(); - auto mut_key = yyjson_mut_strcpy(doc, _key); - - auto mut_value = fconvert(doc, value); - - yyjson_mut_obj_replace(obj, mut_key, mut_value); - return obj; - }; -} - //! Replace key-value pairs to a json object static void ObjectReplaceFunction(DataChunk &args, ExpressionState &state, Vector &result) { auto obj_type = args.data[0].GetType(); D_ASSERT(obj_type == LogicalType::VARCHAR || obj_type == LogicalType::JSON()); auto first_type = args.data[1].GetType(); D_ASSERT(first_type == LogicalType::VARCHAR); - auto second_type = args.data[2].GetType(); + D_ASSERT(second_type == LogicalType::VARCHAR || second_type == LogicalType::JSON()); - switch (second_type.id()) { - case LogicalType::VARCHAR: - JSONExecutors::TernaryMutExecute(args, state, result, ObjectReplaceStringOrJSON); - break; - case LogicalType::BOOLEAN: - JSONExecutors::TernaryMutExecute(args, state, result, ObjectReplace(yyjson_mut_bool)); - break; - case LogicalType::UBIGINT: - JSONExecutors::TernaryMutExecute(args, state, result, - ObjectReplace(yyjson_mut_uint)); - break; - case LogicalType::BIGINT: - JSONExecutors::TernaryMutExecute(args, state, result, - ObjectReplace(yyjson_mut_sint)); - break; - case LogicalType::DOUBLE: - JSONExecutors::TernaryMutExecute(args, state, result, ObjectReplace(yyjson_mut_real)); - break; - default: - // Shouldn't be thrown except implicit casting changes - throw InvalidInputException("Not a valid input type"); - } + JSONExecutors::TernaryMutExecute(args, state, result, ObjectReplaceJSON); } static void GetObjectReplaceFunctionInternal(ScalarFunctionSet &set, const LogicalType &obj, const LogicalType &first, const LogicalType &second) { - set.AddFunction(ScalarFunction("json_obj_replace", {obj, first, second}, LogicalType::JSON(), - ObjectReplaceFunction, nullptr, nullptr, nullptr, JSONFunctionLocalState::Init)); + set.AddFunction(ScalarFunction("json_obj_replace", {obj, first, second}, LogicalType::JSON(), ObjectReplaceFunction, + nullptr, nullptr, nullptr, JSONFunctionLocalState::Init)); } ScalarFunctionSet JSONFunctions::GetObjectReplaceFunction() { ScalarFunctionSet set("json_obj_replace"); - - // Use different executor for these - - // Boolean - // GetObjectReplaceFunctionInternal(set, LogicalType::JSON(), LogicalType::VARCHAR, LogicalType::BOOLEAN); - - // Integer Types - - // unsigned - // GetObjectReplaceFunctionInternal(set, LogicalType::JSON(), LogicalType::VARCHAR, LogicalType::UBIGINT); - - // signed - // GetObjectReplaceFunctionInternal(set, LogicalType::JSON(), LogicalType::VARCHAR, LogicalType::BIGINT); - - // Floating Types - // GetObjectReplaceFunctionInternal(set, LogicalType::JSON(), LogicalType::VARCHAR, LogicalType::DOUBLE); - - // JSON values GetObjectReplaceFunctionInternal(set, LogicalType::JSON(), LogicalType::VARCHAR, LogicalType::JSON()); - // GetObjectReplaceFunctionInternal(set, LogicalType::JSON(), LogicalType::VARCHAR, LogicalType::VARCHAR); return set; }