[fix](function)return NULL rather than 'null' if path not found (#25880)
fix json_extract not return NULL but null
This commit is contained in:
@ -815,7 +815,7 @@ struct FunctionJsonExtractImpl {
|
||||
}
|
||||
|
||||
static void execute(const std::vector<const ColumnString*>& data_columns,
|
||||
ColumnString& result_column, size_t input_rows_count) {
|
||||
ColumnString& result_column, NullMap& null_map, size_t input_rows_count) {
|
||||
rapidjson::Document document;
|
||||
rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
|
||||
rapidjson::StringBuffer buf;
|
||||
@ -835,11 +835,16 @@ struct FunctionJsonExtractImpl {
|
||||
}
|
||||
}
|
||||
|
||||
// write value as string
|
||||
buf.Clear();
|
||||
writer.Reset(buf);
|
||||
value.Accept(writer);
|
||||
result_column.insert_data(buf.GetString(), buf.GetSize());
|
||||
if (value.IsNull()) {
|
||||
null_map[row] = 1;
|
||||
result_column.insert_default();
|
||||
} else {
|
||||
// write value as string
|
||||
buf.Clear();
|
||||
writer.Reset(buf);
|
||||
value.Accept(writer);
|
||||
result_column.insert_data(buf.GetString(), buf.GetSize());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -880,6 +885,37 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Impl>
|
||||
class FunctionJsonNullable : public IFunction {
|
||||
public:
|
||||
static constexpr auto name = Impl::name;
|
||||
static FunctionPtr create() { return std::make_shared<FunctionJsonNullable<Impl>>(); }
|
||||
String get_name() const override { return name; }
|
||||
size_t get_number_of_arguments() const override { return 0; }
|
||||
bool is_variadic() const override { return true; }
|
||||
bool use_default_implementation_for_constants() const override { return true; }
|
||||
DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
|
||||
return make_nullable(std::make_shared<DataTypeString>());
|
||||
}
|
||||
Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
|
||||
size_t result, size_t input_rows_count) const override {
|
||||
auto result_column = ColumnString::create();
|
||||
auto null_map = ColumnUInt8::create(input_rows_count, 0);
|
||||
std::vector<ColumnPtr> column_ptrs; // prevent converted column destruct
|
||||
std::vector<const ColumnString*> data_columns;
|
||||
for (int i = 0; i < arguments.size(); i++) {
|
||||
column_ptrs.push_back(
|
||||
block.get_by_position(arguments[i]).column->convert_to_full_column_if_const());
|
||||
data_columns.push_back(assert_cast<const ColumnString*>(column_ptrs.back().get()));
|
||||
}
|
||||
Impl::execute(data_columns, *assert_cast<ColumnString*>(result_column.get()),
|
||||
null_map->get_data(), input_rows_count);
|
||||
block.replace_by_position(
|
||||
result, ColumnNullable::create(std::move(result_column), std::move(null_map)));
|
||||
return Status::OK();
|
||||
}
|
||||
};
|
||||
|
||||
using FunctionGetJsonDouble = FunctionBinaryStringOperateToNullType<GetJsonDouble>;
|
||||
using FunctionGetJsonInt = FunctionBinaryStringOperateToNullType<GetJsonInt>;
|
||||
using FunctionGetJsonBigInt = FunctionBinaryStringOperateToNullType<GetJsonBigInt>;
|
||||
@ -1476,7 +1512,7 @@ void register_function_json(SimpleFunctionFactory& factory) {
|
||||
factory.register_function<FunctionJsonAlwaysNotNullable<FunctionJsonArrayImpl>>();
|
||||
factory.register_function<FunctionJsonAlwaysNotNullable<FunctionJsonObjectImpl>>();
|
||||
factory.register_function<FunctionJson<FunctionJsonQuoteImpl>>();
|
||||
factory.register_function<FunctionJson<FunctionJsonExtractImpl>>();
|
||||
factory.register_function<FunctionJsonNullable<FunctionJsonExtractImpl>>();
|
||||
|
||||
factory.register_function<FunctionJsonValid>();
|
||||
factory.register_function<FunctionJsonContains>();
|
||||
|
||||
Reference in New Issue
Block a user