Skip to content

Commit

Permalink
Add json array tail function
Browse files Browse the repository at this point in the history
  • Loading branch information
PhictionalOne committed Feb 22, 2024
1 parent ede83fc commit f666530
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 1 deletion.
1 change: 1 addition & 0 deletions extension/json/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ set(JSON_EXTENSION_FILES
json_functions/json_serialize_sql.cpp
json_functions/read_json.cpp
json_functions/read_json_objects.cpp
json_functions/json_array_tail.cpp
json_functions/json_array_append.cpp
${YYJSON_OBJECT_FILES})

Expand Down
3 changes: 2 additions & 1 deletion extension/json/include/json_functions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ class JSONFunctions {
static ScalarFunctionSet GetSerializeSqlFunction();
static ScalarFunctionSet GetDeserializeSqlFunction();

static ScalarFunctionSet GetArrayAppendFunction();
static ScalarFunctionSet GetArrayTailFunction();
static ScalarFunctionSet GetArrayAppendFunction();
static PragmaFunctionSet GetExecuteJsonSerializedSqlPragmaFunction();

template <class FUNCTION_INFO>
Expand Down
1 change: 1 addition & 0 deletions extension/json/json_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
'extension/json/json_serializer.cpp',
'extension/json/json_deserializer.cpp',
'extension/json/serialize_json.cpp',
'extension/json/json_array_tail.cpp',
'extension/json/json_array_append.cpp',
]
]
33 changes: 33 additions & 0 deletions extension/json/json_functions/json_array_tail.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "json_executors.hpp"

namespace duckdb {

static void ArrayTailFunction(DataChunk &args, ExpressionState &state, Vector &result) {
JSONExecutors::UnaryMutExecute(args, state, result,
[](yyjson_mut_val *arr, yyjson_mut_doc *doc, yyjson_alc *alc, Vector &result) {
if (!yyjson_mut_is_arr(arr)) {
throw InvalidInputException("JSON input not an JSON Array");
}

if (yyjson_mut_arr_size(arr) == 0) {
return yyjson_mut_arr(doc);
}

yyjson_mut_arr_remove_first(arr);
return arr;
});
}

static void GetArrayTailFunctionInternal(ScalarFunctionSet &set, const LogicalType &input_type) {
set.AddFunction(ScalarFunction("json_array_tail", {input_type}, JSONCommon::JSONType(), ArrayTailFunction, nullptr,
nullptr, nullptr, JSONFunctionLocalState::Init));
}

ScalarFunctionSet JSONFunctions::GetArrayTailFunction() {
ScalarFunctionSet set("json_array_tail");
GetArrayTailFunctionInternal(set, LogicalType::VARCHAR);
GetArrayTailFunctionInternal(set, JSONCommon::JSONType());
return set;
}

} // namespace duckdb
47 changes: 47 additions & 0 deletions test/sql/json/scalar/test_json_array_tail.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# name: test/sql/json/scalar/test_json_array_tail.test
# description: Checks whether a given JSON Array's tail is correct
# group: [scalar]

require json

statement ok
PRAGMA enable_verification

# list with varchar to json
statement ok
create table test (j json)

statement ok
insert into test values('[]'), ('[42]'), ('["a", 42, true]')

query I
SELECT json_array_tail(j) FROM test
----
[]
[]
[42,true]

statement error
SELECT json_array_tail('')
---
Error: Invalid Input Error: Malformed JSON at byte 0 of input: input length is 0. Input:

statement error
SELECT json_array_tail('{}')
---
Error: Invalid Input Error: JSON input not a JSON Array

statement error
SELECT json_array_tail('true')
---
Error: Invalid Input Error: JSON input not a JSON Array

statement error
SELECT json_array_tail('"Hello"')
---
Error: Invalid Input Error: JSON input not a JSON Array

statement error
SELECT json_array_tail('42')
---
Error: Invalid Input Error: JSON input not a JSON Array

0 comments on commit f666530

Please sign in to comment.