This commit is contained in:
Nikolay Degterinsky 2023-05-17 13:13:57 +00:00
parent d9be88a36a
commit 194ce2d881
2 changed files with 31 additions and 11 deletions

View File

@ -202,6 +202,8 @@ void preparePostgreSQLArrayInfo(
parser = [](std::string & field) -> Field { return pqxx::from_string<float>(field); };
else if (which.isFloat64())
parser = [](std::string & field) -> Field { return pqxx::from_string<double>(field); };
else if (which.isUUID())
parser = [](std::string & field) -> Field { return parse<UUID>(field); };
else if (which.isString() || which.isFixedString())
parser = [](std::string & field) -> Field { return field; };
else if (which.isDate())

View File

@ -197,7 +197,7 @@ public:
/// Cannot just use serializeAsText for array data type even though it converts perfectly
/// any dimension number array into text format, because it encloses in '[]' and for postgres it must be '{}'.
/// Check if array[...] syntax from PostgreSQL will be applicable.
void parseArray(const Field & array_field, const DataTypePtr & data_type, WriteBuffer & ostr)
static void parseArray(const Field & array_field, const DataTypePtr & data_type, WriteBuffer & ostr)
{
const auto * array_type = typeid_cast<const DataTypeArray *>(data_type.get());
const auto & nested = array_type->getNestedType();
@ -205,7 +205,7 @@ public:
if (!isArray(nested))
{
writeText(clickhouseToPostgresArray(array, data_type), ostr);
parseArrayContent(array, data_type, ostr);
return;
}
@ -219,7 +219,7 @@ public:
if (!isArray(nested_array_type->getNestedType()))
{
writeText(clickhouseToPostgresArray(iter->get<Array>(), nested), ostr);
parseArrayContent(iter->get<Array>(), nested, ostr);
}
else
{
@ -232,17 +232,35 @@ public:
/// Conversion is done via column casting because with writeText(Array..) got incorrect conversion
/// of Date and DateTime data types and it added extra quotes for values inside array.
static std::string clickhouseToPostgresArray(const Array & array_field, const DataTypePtr & data_type)
static void parseArrayContent(const Array & array_field, const DataTypePtr & data_type, WriteBuffer & ostr)
{
auto nested = typeid_cast<const DataTypeArray *>(data_type.get())->getNestedType();
auto array_column = ColumnArray::create(createNested(nested));
auto nested_type = typeid_cast<const DataTypeArray *>(data_type.get())->getNestedType();
auto array_column = ColumnArray::create(createNested(nested_type));
array_column->insert(array_field);
WriteBufferFromOwnString ostr;
data_type->getDefaultSerialization()->serializeText(*array_column, 0, ostr, FormatSettings{});
/// ostr is guaranteed to be at least '[]', i.e. size is at least 2 and 2 only if ostr.str() == '[]'
assert(ostr.str().size() >= 2);
return '{' + std::string(ostr.str().begin() + 1, ostr.str().end() - 1) + '}';
const IColumn & nested_column = array_column->getData();
const auto serialization = nested_type->getDefaultSerialization();
FormatSettings settings;
settings.pretty.charset = FormatSettings::Pretty::Charset::ASCII;
if (nested_type->isNullable())
nested_type = static_cast<const DataTypeNullable *>(nested_type.get())->getNestedType();
const bool quoted = !isUUID(nested_type);
writeChar('{', ostr);
for (size_t i = 0, size = array_field.size(); i < size; ++i)
{
if (i != 0)
writeChar(',', ostr);
if (quoted)
serialization->serializeTextQuoted(nested_column, i, ostr, settings);
else
serialization->serializeText(nested_column, i, ostr, settings);
}
writeChar('}', ostr);
}
static MutableColumnPtr createNested(DataTypePtr nested)