2019-08-24 13:00:04 +00:00
|
|
|
#include <DataStreams/ExpressionBlockInputStream.h>
|
2019-05-19 05:27:00 +00:00
|
|
|
#include <DataStreams/CheckConstraintsBlockOutputStream.h>
|
2019-06-05 07:33:34 +00:00
|
|
|
#include <Parsers/formatAST.h>
|
2019-06-05 08:05:46 +00:00
|
|
|
#include <Columns/ColumnsCommon.h>
|
2019-08-24 13:00:04 +00:00
|
|
|
#include <Common/assert_cast.h>
|
|
|
|
|
2019-05-19 05:27:00 +00:00
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2019-08-24 13:00:04 +00:00
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
|
|
|
extern const int VIOLATED_CONSTRAINT;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CheckConstraintsBlockOutputStream::CheckConstraintsBlockOutputStream(
|
|
|
|
const String & table_,
|
|
|
|
const BlockOutputStreamPtr & output_,
|
|
|
|
const Block & header_,
|
|
|
|
const ConstraintsDescription & constraints_,
|
|
|
|
const Context & context_)
|
|
|
|
: table(table_),
|
|
|
|
output(output_),
|
|
|
|
header(header_),
|
|
|
|
constraints(constraints_),
|
|
|
|
expressions(constraints_.getExpressions(context_, header.getNamesAndTypesList()))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-05-19 05:27:00 +00:00
|
|
|
void CheckConstraintsBlockOutputStream::write(const Block & block)
|
|
|
|
{
|
2019-08-24 13:00:04 +00:00
|
|
|
if (block.rows() > 0)
|
2019-06-05 07:33:34 +00:00
|
|
|
{
|
2019-08-24 13:00:04 +00:00
|
|
|
for (size_t i = 0; i < expressions.size(); ++i)
|
2019-07-28 12:33:40 +00:00
|
|
|
{
|
2019-08-24 13:00:04 +00:00
|
|
|
Block block_to_calculate = block;
|
|
|
|
auto constraint_expr = expressions[i];
|
|
|
|
|
|
|
|
constraint_expr->execute(block_to_calculate);
|
|
|
|
ColumnWithTypeAndName res_column = block_to_calculate.getByPosition(block_to_calculate.columns() - 1);
|
|
|
|
const ColumnUInt8 & res_column_uint8 = assert_cast<const ColumnUInt8 &>(*res_column.column);
|
|
|
|
|
|
|
|
const UInt8 * data = res_column_uint8.getData().data();
|
|
|
|
size_t size = res_column_uint8.size();
|
|
|
|
|
|
|
|
/// Is violated.
|
|
|
|
if (!memoryIsByte(data, size, 1))
|
2019-07-29 10:05:43 +00:00
|
|
|
{
|
2019-08-24 13:00:04 +00:00
|
|
|
size_t row_idx = 0;
|
|
|
|
for (; row_idx < size; ++row_idx)
|
|
|
|
if (data[row_idx] != 1)
|
|
|
|
break;
|
2019-07-28 12:33:40 +00:00
|
|
|
|
2019-08-24 13:00:04 +00:00
|
|
|
throw Exception{"Violated constraint " + constraints.constraints[i]->name +
|
|
|
|
" in table " + table + " at row " + std::to_string(row_idx) + ", constraint expression: " +
|
|
|
|
serializeAST(*(constraints.constraints[i]->expr), true), ErrorCodes::VIOLATED_CONSTRAINT};
|
|
|
|
}
|
2019-07-28 12:33:40 +00:00
|
|
|
}
|
2019-06-05 07:33:34 +00:00
|
|
|
}
|
2019-08-24 13:00:04 +00:00
|
|
|
|
2019-05-19 05:27:00 +00:00
|
|
|
output->write(block);
|
2019-07-28 12:33:40 +00:00
|
|
|
rows_written += block.rows();
|
2019-05-19 05:27:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CheckConstraintsBlockOutputStream::flush()
|
|
|
|
{
|
|
|
|
output->flush();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CheckConstraintsBlockOutputStream::writePrefix()
|
|
|
|
{
|
|
|
|
output->writePrefix();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CheckConstraintsBlockOutputStream::writeSuffix()
|
|
|
|
{
|
|
|
|
output->writeSuffix();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|