Fix assert in geohashesInBox

This commit is contained in:
Alexey Milovidov 2020-08-02 05:59:09 +03:00
parent 18b21511a9
commit a1c0dd3782
3 changed files with 53 additions and 29 deletions

View File

@ -59,24 +59,39 @@ public:
bool useDefaultImplementationForConstants() const override { return true; }
template <typename LonAndLatType, typename PrecisionType>
void execute(const IColumn * lon_min_column,
void execute(
const IColumn * lon_min_column,
const IColumn * lat_min_column,
const IColumn * lon_max_column,
const IColumn * lat_max_column,
const IColumn * precision_column,
ColumnPtr & result) const
ColumnPtr & result,
size_t input_rows_count) const
{
static constexpr size_t max_array_size = 10'000'000;
const auto * lon_min_const = typeid_cast<const ColumnConst *>(lon_min_column);
const auto * lat_min_const = typeid_cast<const ColumnConst *>(lat_min_column);
const auto * lon_max_const = typeid_cast<const ColumnConst *>(lon_max_column);
const auto * lat_max_const = typeid_cast<const ColumnConst *>(lat_max_column);
const auto * precision_const = typeid_cast<const ColumnConst *>(precision_column);
if (lon_min_const)
lon_min_column = &lon_min_const->getDataColumn();
if (lat_min_const)
lat_min_column = &lat_min_const->getDataColumn();
if (lon_max_const)
lon_max_column = &lon_max_const->getDataColumn();
if (lat_max_const)
lat_max_column = &lat_max_const->getDataColumn();
if (precision_const)
precision_column = &precision_const->getDataColumn();
const auto * lon_min = checkAndGetColumn<ColumnVector<LonAndLatType>>(lon_min_column);
const auto * lat_min = checkAndGetColumn<ColumnVector<LonAndLatType>>(lat_min_column);
const auto * lon_max = checkAndGetColumn<ColumnVector<LonAndLatType>>(lon_max_column);
const auto * lat_max = checkAndGetColumn<ColumnVector<LonAndLatType>>(lat_max_column);
auto * precision = checkAndGetColumn<ColumnVector<PrecisionType>>(precision_column);
if (precision == nullptr)
{
precision = checkAndGetColumnConstData<ColumnVector<PrecisionType>>(precision_column);
}
const auto * precision = checkAndGetColumn<ColumnVector<PrecisionType>>(precision_column);
if (!lon_min || !lat_min || !lon_max || !lat_max || !precision)
{
@ -88,24 +103,24 @@ public:
ErrorCodes::LOGICAL_ERROR);
}
const size_t total_rows = lat_min->size();
auto col_res = ColumnArray::create(ColumnString::create());
ColumnString & res_strings = typeid_cast<ColumnString &>(col_res->getData());
ColumnArray::Offsets & res_offsets = col_res->getOffsets();
ColumnString::Chars & res_strings_chars = res_strings.getChars();
ColumnString::Offsets & res_strings_offsets = res_strings.getOffsets();
for (size_t row = 0; row < total_rows; ++row)
for (size_t row = 0; row < input_rows_count; ++row)
{
const Float64 lon_min_value = lon_min->getElement(row);
const Float64 lat_min_value = lat_min->getElement(row);
const Float64 lon_max_value = lon_max->getElement(row);
const Float64 lat_max_value = lat_max->getElement(row);
const Float64 lon_min_value = lon_min->getElement(lon_min_const ? 0 : row);
const Float64 lat_min_value = lat_min->getElement(lat_min_const ? 0 : row);
const Float64 lon_max_value = lon_max->getElement(lon_max_const ? 0 : row);
const Float64 lat_max_value = lat_max->getElement(lat_max_const ? 0 : row);
const PrecisionType precision_value = precision->getElement(precision_const ? 0 : row);
const auto prepared_args = geohashesInBoxPrepare(
lon_min_value, lat_min_value, lon_max_value, lat_max_value,
precision->getElement(row % precision->size()));
precision_value);
if (prepared_args.items_count > max_array_size)
{
throw Exception(getName() + " would produce " + std::to_string(prepared_args.items_count) +
@ -123,8 +138,9 @@ public:
for (UInt64 i = 1; i <= prepared_args.items_count ; ++i)
res_strings_offsets.push_back(starting_offset + (prepared_args.precision + 1) * i);
res_offsets.push_back((res_offsets.empty() ? 0 : res_offsets.back()) + prepared_args.items_count);
res_offsets.push_back(res_offsets.back() + prepared_args.items_count);
}
if (!res_strings_offsets.empty() && res_strings_offsets.back() != res_strings_chars.size())
{
throw Exception("String column size mismatch (internal logical error)", ErrorCodes::LOGICAL_ERROR);
@ -140,23 +156,19 @@ public:
result = std::move(col_res);
}
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t /*input_rows_count*/) const override
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) const override
{
const IColumn * lon_min = block.getByPosition(arguments[0]).column.get();
const IColumn * lat_min = block.getByPosition(arguments[1]).column.get();
const IColumn * lon_max = block.getByPosition(arguments[2]).column.get();
const IColumn * lat_max = block.getByPosition(arguments[3]).column.get();
const IColumn * prec = block.getByPosition(arguments[4]).column.get();
const IColumn * precision = block.getByPosition(arguments[4]).column.get();
ColumnPtr & res = block.getByPosition(result).column;
if (checkColumn<ColumnVector<Float32>>(lon_min))
{
execute<Float32, UInt8>(lon_min, lat_min, lon_max, lat_max, prec, res);
}
execute<Float32, UInt8>(lon_min, lat_min, lon_max, lat_max, precision, res, input_rows_count);
else
{
execute<Float64, UInt8>(lon_min, lat_min, lon_max, lat_max, prec, res);
}
execute<Float64, UInt8>(lon_min, lat_min, lon_max, lat_max, precision, res, input_rows_count);
}
};

View File

@ -0,0 +1,6 @@
['s']
['s0']
['s02','s08','s03','s09','s06','s0d']
['s']
['s0']
['s02','s08','s03','s09','s06','s0d']

View File

@ -0,0 +1,6 @@
SELECT geohashesInBox(1., 2., 3., 4., 1);
SELECT geohashesInBox(materialize(1.), 2., 3., 4., 2);
SELECT geohashesInBox(1., materialize(2.), 3., 4., 3);
SELECT geohashesInBox(1., 2., materialize(3.), 4., 1);
SELECT geohashesInBox(1., 2., 3., materialize(4.), 2);
SELECT geohashesInBox(1., 2., 3., 4., materialize(3));