2019-09-03 10:07:31 +00:00
|
|
|
#include <Interpreters/FillingRow.h>
|
2020-06-14 18:42:10 +00:00
|
|
|
#include <Common/FieldVisitorsAccurateComparison.h>
|
|
|
|
|
2019-09-02 14:29:51 +00:00
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
|
|
|
bool less(const Field & lhs, const Field & rhs, int direction)
|
|
|
|
{
|
|
|
|
if (direction == -1)
|
|
|
|
return applyVisitor(FieldVisitorAccurateLess(), rhs, lhs);
|
|
|
|
|
|
|
|
return applyVisitor(FieldVisitorAccurateLess(), lhs, rhs);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool equals(const Field & lhs, const Field & rhs)
|
|
|
|
{
|
|
|
|
return applyVisitor(FieldVisitorAccurateEquals(), lhs, rhs);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-03-24 19:29:29 +00:00
|
|
|
FillingRow::FillingRow(const SortDescription & sort_description_, InterpolateDescriptionPtr interpolate_description_)
|
|
|
|
: sort_description(sort_description_)
|
2022-03-17 05:51:35 +00:00
|
|
|
, interpolate_description(interpolate_description_)
|
2019-09-02 14:29:51 +00:00
|
|
|
{
|
2022-03-24 19:29:29 +00:00
|
|
|
std::unordered_set<std::string> col_set;
|
|
|
|
for (const auto & col : sort_description)
|
|
|
|
col_set.insert(col.column_name);
|
|
|
|
if (interpolate_description)
|
|
|
|
for (const auto & name : interpolate_description->columns_full_set)
|
|
|
|
col_set.insert(name);
|
|
|
|
row.resize(col_set.size());
|
2019-09-02 14:29:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool FillingRow::operator<(const FillingRow & other) const
|
|
|
|
{
|
2022-03-24 19:29:29 +00:00
|
|
|
for (size_t i = 0; i < sort_description.size(); ++i)
|
2019-09-02 14:29:51 +00:00
|
|
|
{
|
2022-03-24 19:29:29 +00:00
|
|
|
if (row[i].isNull() || other.row[i].isNull() || equals(row[i], other.row[i]))
|
2019-09-02 14:29:51 +00:00
|
|
|
continue;
|
2022-03-24 19:29:29 +00:00
|
|
|
return less(row[i], other.row[i], getDirection(i));
|
2019-09-02 14:29:51 +00:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FillingRow::operator==(const FillingRow & other) const
|
|
|
|
{
|
2022-03-24 19:29:29 +00:00
|
|
|
for (size_t i = 0; i < sort_description.size(); ++i)
|
|
|
|
if (!equals(row[i], other.row[i]))
|
2019-09-02 14:29:51 +00:00
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FillingRow::next(const FillingRow & to_row)
|
|
|
|
{
|
|
|
|
size_t pos = 0;
|
|
|
|
|
|
|
|
/// Find position we need to increment for generating next row.
|
2022-03-24 19:29:29 +00:00
|
|
|
for (; pos < size(); ++pos)
|
|
|
|
if (!row[pos].isNull() && !to_row.row[pos].isNull() && !equals(row[pos], to_row.row[pos]))
|
2019-09-02 14:29:51 +00:00
|
|
|
break;
|
|
|
|
|
2022-03-24 19:29:29 +00:00
|
|
|
if (pos == size() || less(to_row.row[pos], row[pos], getDirection(pos)))
|
2019-09-02 14:29:51 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
/// If we have any 'fill_to' value at position greater than 'pos',
|
|
|
|
/// we need to generate rows up to 'fill_to' value.
|
2022-03-24 19:29:29 +00:00
|
|
|
for (size_t i = size() - 1; i > pos; --i)
|
2019-09-02 14:29:51 +00:00
|
|
|
{
|
2022-03-24 19:29:29 +00:00
|
|
|
if (getFillDescription(i).fill_to.isNull() || row[i].isNull())
|
2019-09-02 14:29:51 +00:00
|
|
|
continue;
|
|
|
|
|
2022-03-24 19:29:29 +00:00
|
|
|
auto next_value = row[i];
|
2021-10-31 19:48:12 +00:00
|
|
|
getFillDescription(i).step_func(next_value);
|
2019-09-02 14:29:51 +00:00
|
|
|
if (less(next_value, getFillDescription(i).fill_to, getDirection(i)))
|
|
|
|
{
|
2022-03-24 19:29:29 +00:00
|
|
|
row[i] = next_value;
|
2019-09-02 14:29:51 +00:00
|
|
|
initFromDefaults(i + 1);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-24 19:29:29 +00:00
|
|
|
auto next_value = row[pos];
|
2021-10-31 16:22:20 +00:00
|
|
|
getFillDescription(pos).step_func(next_value);
|
2019-09-02 14:29:51 +00:00
|
|
|
|
2022-03-24 19:29:29 +00:00
|
|
|
if (less(to_row.row[pos], next_value, getDirection(pos)))
|
2019-09-02 14:29:51 +00:00
|
|
|
return false;
|
|
|
|
|
2022-03-24 19:29:29 +00:00
|
|
|
row[pos] = next_value;
|
|
|
|
if (equals(row[pos], to_row.row[pos]))
|
2019-09-02 14:29:51 +00:00
|
|
|
{
|
|
|
|
bool is_less = false;
|
2022-03-24 19:29:29 +00:00
|
|
|
size_t i = pos + 1;
|
|
|
|
for (; i < size(); ++i)
|
2019-09-02 14:29:51 +00:00
|
|
|
{
|
|
|
|
const auto & fill_from = getFillDescription(i).fill_from;
|
|
|
|
if (!fill_from.isNull())
|
2022-03-24 19:29:29 +00:00
|
|
|
row[i] = fill_from;
|
2019-09-02 14:29:51 +00:00
|
|
|
else
|
2022-03-24 19:29:29 +00:00
|
|
|
row[i] = to_row.row[i];
|
|
|
|
is_less |= less(row[i], to_row.row[i], getDirection(i));
|
2019-09-02 14:29:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return is_less;
|
|
|
|
}
|
|
|
|
|
|
|
|
initFromDefaults(pos + 1);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FillingRow::initFromDefaults(size_t from_pos)
|
|
|
|
{
|
2022-03-24 19:29:29 +00:00
|
|
|
for (size_t i = from_pos; i < sort_description.size(); ++i)
|
|
|
|
row[i] = getFillDescription(i).fill_from;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FillingRow::interpolate()
|
|
|
|
{
|
|
|
|
if (!interpolate_description)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Block block;
|
|
|
|
if (interpolate_description->input_map.size())
|
|
|
|
{
|
|
|
|
for (const auto & [row_pos, name_type] : interpolate_description->input_map)
|
|
|
|
{
|
|
|
|
if (row[row_pos].isNull())
|
|
|
|
return;
|
|
|
|
block.insert({name_type.type->createColumnConst(1, row[row_pos]), name_type.type, name_type.name});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else /// INTERPOLATE contains only constants
|
|
|
|
{
|
|
|
|
/// dirty hack - we need at least one column with one row to execute actions on block
|
|
|
|
DataTypePtr dt = std::make_shared<DataTypeUInt64>();
|
|
|
|
block.insert({dt->createColumnConst(1, dt->getDefault()), dt, "dummy"});
|
|
|
|
}
|
|
|
|
|
|
|
|
interpolate_description->actions->execute(block);
|
|
|
|
|
|
|
|
for (auto [col_pos, row_pos] : interpolate_description->output_map)
|
|
|
|
block.getByPosition(col_pos).column->get(0, row[row_pos]);
|
|
|
|
|
|
|
|
for (const auto & [row_pos, col_type] : interpolate_description->reset_map)
|
|
|
|
row[row_pos] = col_type->getDefault();
|
2019-09-02 14:29:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void insertFromFillingRow(MutableColumns & filling_columns, MutableColumns & other_columns, const FillingRow & filling_row)
|
|
|
|
{
|
|
|
|
for (size_t i = 0; i < filling_columns.size(); ++i)
|
|
|
|
{
|
|
|
|
if (filling_row[i].isNull())
|
|
|
|
filling_columns[i]->insertDefault();
|
|
|
|
else
|
|
|
|
filling_columns[i]->insert(filling_row[i]);
|
|
|
|
}
|
|
|
|
|
2020-03-09 00:08:02 +00:00
|
|
|
for (const auto & other_column : other_columns)
|
|
|
|
other_column->insertDefault();
|
2019-09-02 14:29:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void copyRowFromColumns(MutableColumns & dest, const Columns & source, size_t row_num)
|
|
|
|
{
|
|
|
|
for (size_t i = 0; i < source.size(); ++i)
|
|
|
|
dest[i]->insertFrom(*source[i], row_num);
|
|
|
|
}
|
|
|
|
|
2019-09-02 17:18:44 +00:00
|
|
|
}
|