Skip to content

Commit 6d30e64

Browse files
Backport ClickHouse#88008 to 25.8: Fix reading mixed array of Floats and Bools in JSON
1 parent cca7f5c commit 6d30e64

File tree

5 files changed

+19
-19
lines changed

5 files changed

+19
-19
lines changed

src/Formats/JSONExtractTree.cpp

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ void jsonElementToString(const typename JSONParser::Element & element, WriteBuff
131131

132132
template <typename JSONParser, typename NumberType>
133133
bool tryGetNumericValueFromJSONElement(
134-
NumberType & value, const typename JSONParser::Element & element, bool convert_bool_to_integer, bool allow_type_conversion, String & error)
134+
NumberType & value, const typename JSONParser::Element & element, bool convert_bool_to_number, bool allow_type_conversion, String & error)
135135
{
136136
switch (element.type())
137137
{
@@ -164,13 +164,10 @@ bool tryGetNumericValueFromJSONElement(
164164
}
165165
break;
166166
case ElementType::BOOL:
167-
if constexpr (is_integer<NumberType>)
167+
if (convert_bool_to_number && allow_type_conversion)
168168
{
169-
if (convert_bool_to_integer && allow_type_conversion)
170-
{
171-
value = static_cast<NumberType>(element.getBool());
172-
break;
173-
}
169+
value = static_cast<NumberType>(element.getBool());
170+
break;
174171
}
175172
error = fmt::format("cannot convert bool value to {}", TypeName<NumberType>);
176173
return false;
@@ -262,7 +259,7 @@ class NumericNode : public JSONExtractTreeNode<JSONParser>
262259
}
263260

264261
NumberType value;
265-
if (!tryGetNumericValueFromJSONElement<JSONParser, NumberType>(value, element, insert_settings.convert_bool_to_integer || is_bool_type, insert_settings.allow_type_conversion, error))
262+
if (!tryGetNumericValueFromJSONElement<JSONParser, NumberType>(value, element, /*convert_bool_to_number=*/ true, insert_settings.allow_type_conversion, error))
266263
{
267264
if (error.empty())
268265
error = fmt::format("cannot read {} value from JSON element: {}", TypeName<NumberType>, jsonElementToString<JSONParser>(element, format_settings));
@@ -319,7 +316,7 @@ class LowCardinalityNumericNode : public NumericNode<JSONParser, NumberType>
319316
}
320317

321318
NumberType value;
322-
if (!tryGetNumericValueFromJSONElement<JSONParser, NumberType>(value, element, insert_settings.convert_bool_to_integer || this->is_bool_type, insert_settings.allow_type_conversion, error))
319+
if (!tryGetNumericValueFromJSONElement<JSONParser, NumberType>(value, element, /*convert_bool_to_number=*/ true, insert_settings.allow_type_conversion, error))
323320
{
324321
if (error.empty())
325322
error = fmt::format("cannot read {} value from JSON element: {}", TypeName<NumberType>, jsonElementToString<JSONParser>(element, format_settings));
@@ -2218,13 +2215,13 @@ template std::unique_ptr<JSONExtractTreeNode<SimdJSONParser>> buildJSONExtractTr
22182215
#if USE_RAPIDJSON
22192216
template void jsonElementToString<RapidJSONParser>(const RapidJSONParser::Element & element, WriteBuffer & buf, const FormatSettings & format_settings);
22202217
template std::unique_ptr<JSONExtractTreeNode<RapidJSONParser>> buildJSONExtractTree<RapidJSONParser>(const DataTypePtr & type, const char * source_for_exception_message);
2221-
template bool tryGetNumericValueFromJSONElement<RapidJSONParser, Float64>(Float64 & value, const RapidJSONParser::Element & element, bool convert_bool_to_integer, bool allow_type_conversion, String & error);
2218+
template bool tryGetNumericValueFromJSONElement<RapidJSONParser, Float64>(Float64 & value, const RapidJSONParser::Element & element, bool convert_bool_to_number, bool allow_type_conversion, String & error);
22222219
#else
22232220
template void jsonElementToString<DummyJSONParser>(const DummyJSONParser::Element & element, WriteBuffer & buf, const FormatSettings & format_settings);
22242221
template std::unique_ptr<JSONExtractTreeNode<DummyJSONParser>> buildJSONExtractTree<DummyJSONParser>(const DataTypePtr & type, const char * source_for_exception_message);
2225-
template bool tryGetNumericValueFromJSONElement<DummyJSONParser, Float64>(Float64 & value, const DummyJSONParser::Element & element, bool convert_bool_to_integer, bool allow_type_conversion, String & error);
2226-
template bool tryGetNumericValueFromJSONElement<DummyJSONParser, Int64>(Int64 & value, const DummyJSONParser::Element & element, bool convert_bool_to_integer, bool allow_type_conversion, String & error);
2227-
template bool tryGetNumericValueFromJSONElement<DummyJSONParser, UInt64>(UInt64 & value, const DummyJSONParser::Element & element, bool convert_bool_to_integer, bool allow_type_conversion, String & error);
2222+
template bool tryGetNumericValueFromJSONElement<DummyJSONParser, Float64>(Float64 & value, const DummyJSONParser::Element & element, bool convert_bool_to_number, bool allow_type_conversion, String & error);
2223+
template bool tryGetNumericValueFromJSONElement<DummyJSONParser, Int64>(Int64 & value, const DummyJSONParser::Element & element, bool convert_bool_to_number, bool allow_type_conversion, String & error);
2224+
template bool tryGetNumericValueFromJSONElement<DummyJSONParser, UInt64>(UInt64 & value, const DummyJSONParser::Element & element, bool convert_bool_to_number, bool allow_type_conversion, String & error);
22282225
#endif
22292226

22302227
}

src/Formats/JSONExtractTree.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ struct FormatSettings;
99

1010
struct JSONExtractInsertSettings
1111
{
12-
/// If false, JSON boolean values won't be inserted into columns with integer types
13-
/// It's used in JSONExtractInt64/JSONExtractUInt64/... functions.
14-
bool convert_bool_to_integer = true;
1512
/// If true, when complex type like Array/Map has both valid and invalid elements,
1613
/// the default value will be inserted on invalid elements.
1714
/// For example, if we have [1, "hello", 2] and type Array(UInt32),
@@ -44,6 +41,6 @@ template <typename JSONParser>
4441
void jsonElementToString(const typename JSONParser::Element & element, WriteBuffer & buf, const FormatSettings & format_settings);
4542

4643
template <typename JSONParser, typename NumberType>
47-
bool tryGetNumericValueFromJSONElement(NumberType & value, const typename JSONParser::Element & element, bool convert_bool_to_integer, bool allow_type_conversion, String & error);
44+
bool tryGetNumericValueFromJSONElement(NumberType & value, const typename JSONParser::Element & element, bool convert_bool_to_number, bool allow_type_conversion, String & error);
4845

4946
}

src/Functions/FunctionsJSON.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,7 @@ class JSONTypeImpl
772772
};
773773

774774

775-
template <typename JSONParser, typename NumberType, bool convert_bool_to_integer = false>
775+
template <typename JSONParser, typename NumberType>
776776
class JSONExtractNumericImpl
777777
{
778778
public:
@@ -794,7 +794,7 @@ class JSONExtractNumericImpl
794794
{
795795
NumberType value;
796796

797-
if (!tryGetNumericValueFromJSONElement<JSONParser, NumberType>(value, element, convert_bool_to_integer, /*allow_type_conversion=*/true, error))
797+
if (!tryGetNumericValueFromJSONElement<JSONParser, NumberType>(value, element, /*convert_bool_to_number=*/false, /*allow_type_conversion=*/true, error))
798798
return false;
799799
auto & col_vec = assert_cast<ColumnVector<NumberType> &>(dest);
800800
col_vec.insertValue(value);
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
{"a":[42.42,0]} Array(Nullable(Float64))
2+
{"a":[42.42,false]} Array(Dynamic)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
set enable_analyzer=1;
2+
3+
select '{"a" : [42.42, false]}'::JSON as json, dynamicType(json.a) settings input_format_json_read_bools_as_numbers=1;
4+
select '{"a" : [42.42, false]}'::JSON as json, dynamicType(json.a) settings input_format_json_read_bools_as_numbers=0;

0 commit comments

Comments
 (0)