ClickHouse/dbms/src/DataStreams/CheckConstraintsBlockOutputStream.cpp

80 lines
2.3 KiB
C++
Raw Normal View History

2019-05-19 05:27:00 +00:00
#include <DataStreams/CheckConstraintsBlockOutputStream.h>
#include <Functions/FunctionHelpers.h>
#include <common/find_symbols.h>
#include <Parsers/formatAST.h>
#include <Columns/ColumnsCommon.h>
2019-05-19 05:27:00 +00:00
namespace DB
{
void CheckConstraintsBlockOutputStream::write(const Block & block)
{
for (size_t i = 0; i < expressions.size(); ++i)
{
2019-08-11 09:28:15 +00:00
Block res = block;
auto constraint_expr = expressions[i];
2019-08-11 09:28:15 +00:00
auto res_column_uint8 = executeOnBlock(res, constraint_expr);
2019-07-28 12:33:40 +00:00
if (!memoryIsByte(res_column_uint8->getRawDataBegin<1>(), res_column_uint8->byteSize(), 0x1))
{
auto indices_wrong = findAllWrong(res_column_uint8->getRawDataBegin<1>(), res_column_uint8->byteSize());
std::string indices_str = "{";
2019-07-29 10:05:43 +00:00
for (size_t j = 0; j < indices_wrong.size(); ++j)
{
2019-07-28 12:33:40 +00:00
indices_str += std::to_string(indices_wrong[j]);
indices_str += (j != indices_wrong.size() - 1) ? ", " : "}";
}
throw Exception{"Violated constraint " + constraints.constraints[i]->name +
" in table " + table + " at indices " + indices_str + ", constraint expression: " +
2019-08-15 00:53:16 +00:00
serializeAST(*(constraints.constraints[i]->expr), true), ErrorCodes::VIOLATED_CONSTRAINT};
2019-07-28 12:33:40 +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();
}
2019-07-28 12:33:40 +00:00
const ColumnUInt8 *CheckConstraintsBlockOutputStream::executeOnBlock(
2019-08-11 09:28:15 +00:00
Block & block,
2019-07-28 12:33:40 +00:00
const ExpressionActionsPtr & constraint)
{
2019-08-11 09:28:15 +00:00
constraint->execute(block);
ColumnWithTypeAndName res_column = block.safeGetByPosition(block.columns() - 1);
2019-07-28 12:33:40 +00:00
return checkAndGetColumn<ColumnUInt8>(res_column.column.get());
}
2019-07-28 12:33:40 +00:00
std::vector<size_t> CheckConstraintsBlockOutputStream::findAllWrong(const void *data, size_t size)
{
2019-07-28 12:33:40 +00:00
std::vector<size_t> res;
if (size == 0)
return res;
auto ptr = reinterpret_cast<const uint8_t *>(data);
2019-07-28 12:33:40 +00:00
for (size_t i = 0; i < size; ++i)
{
if (*(ptr + i) == 0x0)
{
res.push_back(i);
}
}
return res;
}
2019-05-19 05:27:00 +00:00
}