Updated support for Nullable column

This commit is contained in:
Maksim Kita 2021-02-25 11:35:31 +03:00
parent 2eec1d021b
commit 23af53067d
2 changed files with 37 additions and 5 deletions

View File

@ -52,15 +52,34 @@ void CheckConstraintsBlockOutputStream::write(const Block & block)
ColumnWithTypeAndName res_column = block_to_calculate.getByName(constraint_ptr->expr->getColumnName());
auto result_type = removeNullable(removeLowCardinality(res_column.type));
auto result_column = res_column.column->convertToFullColumnIfConst()->convertToFullColumnIfLowCardinality();
if (const auto * column_nullable = checkAndGetColumn<ColumnNullable>(*result_column))
result_column = column_nullable->getNestedColumnPtr();
if (!isUInt8(result_type))
throw Exception(ErrorCodes::UNSUPPORTED_METHOD, "Constraint {} does not return a value of type UInt8",
backQuote(constraint_ptr->name));
auto result_column = res_column.column->convertToFullColumnIfConst()->convertToFullColumnIfLowCardinality();
if (const auto * column_nullable = checkAndGetColumn<ColumnNullable>(*result_column))
{
const auto & nested_column = column_nullable->getNestedColumnPtr();
/// Check if constraint value is nullable
const auto & null_map = column_nullable->getNullMapColumn();
const auto & data = null_map.getData();
bool null_map_contain_null = std::find(data.begin(), data.end(), true);
if (null_map_contain_null)
throw Exception(
ErrorCodes::VIOLATED_CONSTRAINT,
"Constraint {} for table {} is violated. Expression: ({})."\
"Constraint expression returns nullable column that contains null value",
backQuote(constraint_ptr->name),
table_id.getNameForLogs(),
serializeAST(*(constraint_ptr->expr), true));
result_column = nested_column;
}
const ColumnUInt8 & res_column_uint8 = assert_cast<const ColumnUInt8 &>(*result_column);
const UInt8 * data = res_column_uint8.getData().data();

View File

@ -20,8 +20,21 @@ CREATE TABLE constraint_constant_number_expression_non_uint8
CONSTRAINT `c0` CHECK toUInt64(1)
) ENGINE = TinyLog();
INSERT INTO constraint_constant_number_expression_non_uint8 VALUES (1); -- {serverError 1}
INSERT INTO constraint_constant_number_expression_non_uint8 VALUES (2); -- {serverError 1}
SELECT * FROM constraint_constant_number_expression_non_uint8;
DROP TABLE constraint_constant_number_expression_non_uint8;
DROP TABLE IF EXISTS constraint_constant_nullable_expression_that_contains_null;
CREATE TABLE constraint_constant_nullable_expression_that_contains_null
(
id UInt64,
CONSTRAINT `c0` CHECK nullIf(1 % 2, 1)
) ENGINE = TinyLog();
INSERT INTO constraint_constant_nullable_expression_that_contains_null VALUES (3); -- {serverError 469}
SELECT * FROM constraint_constant_nullable_expression_that_contains_null;
DROP TABLE constraint_constant_nullable_expression_that_contains_null;