| 1339 | } |
| 1340 | |
| 1341 | FunctionCast::WrapperType FunctionCast::createObjectWrapper(const DataTypePtr & from_type, const DataTypeObject * to_object, bool requested_result_is_nullable) const |
| 1342 | { |
| 1343 | if (checkAndGetDataType<DataTypeString>(from_type.get())) |
| 1344 | { |
| 1345 | return [this, requested_result_is_nullable](ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, const ColumnNullable * nullable_source, size_t input_rows_count) |
| 1346 | { |
| 1347 | if (requested_result_is_nullable && cast_type == CastType::accurateOrNull) |
| 1348 | return ConvertImplGenericFromString<false>::execute(arguments, makeNullable(result_type), nullable_source, input_rows_count, settings); |
| 1349 | |
| 1350 | return ConvertImplGenericFromString<true>::execute(arguments, result_type, nullable_source, input_rows_count, settings); |
| 1351 | }; |
| 1352 | } |
| 1353 | |
| 1354 | /// Cast Tuple/Object/Map/JSON to JSON type through serializing into JSON string and parsing back into JSON column. |
| 1355 | /// Potentially we can do smarter conversion Tuple -> JSON with type preservation, but it's questionable how exactly Tuple should be |
| 1356 | /// converted to JSON (for example, should we recursively convert nested Array(Tuple) to Array(JSON) or not, should we infer types from String fields, etc). |
| 1357 | /// Proper implementation of a conversion between 2 different JSON types is really complex, because different JSON types |
| 1358 | /// can have different parameters: |
| 1359 | /// - set of typed paths |
| 1360 | /// - set of skip rules |
| 1361 | /// - max_dynamic_paths/max_dynamic_types parameters |
| 1362 | /// Also max_dynamic_paths/max_dynamic_types parameters of nested JSON types depend on current max_dynamic_paths/max_dynamic_types, |
| 1363 | /// so if these parameters are changed, we have to recursively find all nested JSON types and change their parameters as well. |
| 1364 | /// It's all complicates the implementation and last attempt to implement it led to several bugs. |
| 1365 | /// So for now let's perform this conversion through cast to String and parsing new JSON back from it. |
| 1366 | /// It's not effective, but 100% accurate. |
| 1367 | if (checkAndGetDataType<DataTypeTuple>(from_type.get()) |
| 1368 | || checkAndGetDataType<DataTypeMap>(from_type.get()) || checkAndGetDataType<DataTypeObject>(from_type.get())) |
| 1369 | { |
| 1370 | return [this, requested_result_is_nullable](ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, const ColumnNullable * nullable_source, size_t input_rows_count) |
| 1371 | { |
| 1372 | auto json_string = ColumnString::create(); |
| 1373 | ColumnStringHelpers::WriteHelper<ColumnString> write_helper(assert_cast<ColumnString &>(*json_string), input_rows_count); |
| 1374 | auto & write_buffer = write_helper.getWriteBuffer(); |
| 1375 | FormatSettings format_settings = settings.format_settings; |
| 1376 | auto serialization = arguments[0].type->getDefaultSerialization(); |
| 1377 | format_settings.json.quote_64bit_integers = false; |
| 1378 | for (size_t i = 0; i < input_rows_count; ++i) |
| 1379 | { |
| 1380 | serialization->serializeTextJSON(*arguments[0].column, i, write_buffer, format_settings); |
| 1381 | write_helper.finishRow(); |
| 1382 | } |
| 1383 | write_helper.finalize(); |
| 1384 | |
| 1385 | ColumnsWithTypeAndName args_with_json_string = {ColumnWithTypeAndName(json_string->getPtr(), std::make_shared<DataTypeString>(), "")}; |
| 1386 | if (requested_result_is_nullable && cast_type == CastType::accurateOrNull) |
| 1387 | return ConvertImplGenericFromString<false>::execute(args_with_json_string, makeNullable(result_type), nullable_source, input_rows_count, settings); |
| 1388 | |
| 1389 | return ConvertImplGenericFromString<true>::execute(args_with_json_string, result_type, nullable_source, input_rows_count, settings); |
| 1390 | }; |
| 1391 | } |
| 1392 | |
| 1393 | throw Exception( |
| 1394 | ErrorCodes::TYPE_MISMATCH, |
| 1395 | "Cast to {} can be performed only from String/Map/Object/Tuple/JSON. Got: {}", |
| 1396 | to_object->getSchemaFormatString(), |
| 1397 | from_type->getName()); |
| 1398 | } |
nothing calls this directly
no test coverage detected