mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 16:50:48 +00:00
Replace null fields in tuple during parsing with default values
This commit is contained in:
parent
6946514c0b
commit
8520fc3e4c
@ -36,6 +36,7 @@ namespace ErrorCodes
|
|||||||
{
|
{
|
||||||
extern const int LOGICAL_ERROR;
|
extern const int LOGICAL_ERROR;
|
||||||
extern const int SYNTAX_ERROR;
|
extern const int SYNTAX_ERROR;
|
||||||
|
extern const int TYPE_MISMATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -209,6 +210,14 @@ private:
|
|||||||
if (map.size() % 2)
|
if (map.size() % 2)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else if (literal->value.getType() == Field::Types::Tuple)
|
||||||
|
{
|
||||||
|
const Tuple & tuple = literal->value.get<Tuple>();
|
||||||
|
|
||||||
|
for (const auto & value : tuple)
|
||||||
|
if (value.isNull())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
String column_name = "_dummy_" + std::to_string(replaced_literals.size());
|
String column_name = "_dummy_" + std::to_string(replaced_literals.size());
|
||||||
replaced_literals.emplace_back(literal, column_name, force_nullable);
|
replaced_literals.emplace_back(literal, column_name, force_nullable);
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <common/find_symbols.h>
|
#include <common/find_symbols.h>
|
||||||
#include <Parsers/ASTLiteral.h>
|
#include <Parsers/ASTLiteral.h>
|
||||||
#include <DataTypes/DataTypeNullable.h>
|
#include <DataTypes/DataTypeNullable.h>
|
||||||
|
#include <DataTypes/DataTypeTuple.h>
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
@ -181,6 +182,35 @@ bool ValuesBlockInputFormat::tryReadValue(IColumn & column, size_t column_idx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
void tryToReplaceNullFieldsInTupleWithDefaultValues(Field & value, const IDataType & type)
|
||||||
|
{
|
||||||
|
const DataTypeTuple * type_tuple = typeid_cast<const DataTypeTuple *>(&type);
|
||||||
|
|
||||||
|
if (!type_tuple || value.getType() != Field::Types::Tuple)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Tuple & tuple_value = value.get<Tuple>();
|
||||||
|
|
||||||
|
size_t src_tuple_size = tuple_value.size();
|
||||||
|
size_t dst_tuple_size = type_tuple->getElements().size();
|
||||||
|
|
||||||
|
if (src_tuple_size != dst_tuple_size)
|
||||||
|
throw Exception("Bad size of tuple. Expected size: " + std::to_string(src_tuple_size) + ", actual size: " + std::to_string(dst_tuple_size), ErrorCodes::TYPE_MISMATCH);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < src_tuple_size; ++i)
|
||||||
|
{
|
||||||
|
const auto & element_type = *(type_tuple->getElements()[i]);
|
||||||
|
|
||||||
|
if (tuple_value[i].isNull() && !element_type.isNullable())
|
||||||
|
tuple_value[i] = element_type.getDefault();
|
||||||
|
|
||||||
|
tryToReplaceNullFieldsInTupleWithDefaultValues(tuple_value[i], element_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ValuesBlockInputFormat::parseExpression(IColumn & column, size_t column_idx)
|
bool ValuesBlockInputFormat::parseExpression(IColumn & column, size_t column_idx)
|
||||||
{
|
{
|
||||||
const Block & header = getPort().getHeader();
|
const Block & header = getPort().getHeader();
|
||||||
@ -298,6 +328,10 @@ bool ValuesBlockInputFormat::parseExpression(IColumn & column, size_t column_idx
|
|||||||
buf.position() = const_cast<char *>(token_iterator->begin);
|
buf.position() = const_cast<char *>(token_iterator->begin);
|
||||||
|
|
||||||
std::pair<Field, DataTypePtr> value_raw = evaluateConstantExpression(ast, *context);
|
std::pair<Field, DataTypePtr> value_raw = evaluateConstantExpression(ast, *context);
|
||||||
|
|
||||||
|
if (format_settings.null_as_default)
|
||||||
|
tryToReplaceNullFieldsInTupleWithDefaultValues(value_raw.first, type);
|
||||||
|
|
||||||
Field value = convertFieldToType(value_raw.first, type, value_raw.second.get());
|
Field value = convertFieldToType(value_raw.first, type, value_raw.second.get());
|
||||||
|
|
||||||
/// Check that we are indeed allowed to insert a NULL.
|
/// Check that we are indeed allowed to insert a NULL.
|
||||||
|
Loading…
Reference in New Issue
Block a user