Fix partition pruner: non-monotonic function IN

This commit is contained in:
Amos Bird 2022-03-09 15:48:42 +08:00
parent 81e56a06a3
commit a19224bc9b
No known key found for this signature in database
GPG Key ID: 80D430DCBECFEDB4
6 changed files with 24 additions and 7 deletions

View File

@ -267,7 +267,7 @@ public:
*/
virtual Monotonicity getMonotonicityForRange(const IDataType & /*type*/, const Field & /*left*/, const Field & /*right*/) const
{
throw Exception("Function " + getName() + " has no information about its monotonicity.", ErrorCodes::NOT_IMPLEMENTED);
throw Exception("Function " + getName() + " has no information about its monotonicity", ErrorCodes::NOT_IMPLEMENTED);
}
};
@ -452,7 +452,7 @@ public:
using Monotonicity = IFunctionBase::Monotonicity;
virtual Monotonicity getMonotonicityForRange(const IDataType & /*type*/, const Field & /*left*/, const Field & /*right*/) const
{
throw Exception("Function " + getName() + " has no information about its monotonicity.", ErrorCodes::NOT_IMPLEMENTED);
throw Exception("Function " + getName() + " has no information about its monotonicity", ErrorCodes::NOT_IMPLEMENTED);
}
/// For non-variadic functions, return number of arguments; otherwise return zero (that should be ignored).

View File

@ -445,7 +445,7 @@ MergeTreeSetIndex::MergeTreeSetIndex(const Columns & set_elements, std::vector<K
* 1: the intersection of the set and the range is non-empty
* 2: the range contains elements not in the set
*/
BoolMask MergeTreeSetIndex::checkInRange(const std::vector<Range> & key_ranges, const DataTypes & data_types) const
BoolMask MergeTreeSetIndex::checkInRange(const std::vector<Range> & key_ranges, const DataTypes & data_types, bool single_point) const
{
size_t tuple_size = indexes_mapping.size();
@ -468,7 +468,8 @@ BoolMask MergeTreeSetIndex::checkInRange(const std::vector<Range> & key_ranges,
std::optional<Range> new_range = KeyCondition::applyMonotonicFunctionsChainToRange(
key_ranges[indexes_mapping[i].key_index],
indexes_mapping[i].functions,
data_types[indexes_mapping[i].key_index]);
data_types[indexes_mapping[i].key_index],
single_point);
if (!new_range)
return {true, true};

View File

@ -214,7 +214,7 @@ public:
bool hasMonotonicFunctionsChain() const;
BoolMask checkInRange(const std::vector<Range> & key_ranges, const DataTypes & data_types) const;
BoolMask checkInRange(const std::vector<Range> & key_ranges, const DataTypes & data_types, bool single_point = false) const;
private:
// If all arguments in tuple are key columns, we can optimize NOT IN when there is only one element.

View File

@ -448,7 +448,7 @@ KeyCondition::KeyCondition(
{
for (size_t i = 0, size = key_column_names.size(); i < size; ++i)
{
std::string name = key_column_names[i];
const auto & name = key_column_names[i];
if (!key_columns.count(name))
key_columns[name] = i;
}
@ -1999,7 +1999,7 @@ BoolMask KeyCondition::checkInHyperrectangle(
if (!element.set_index)
throw Exception("Set for IN is not created yet", ErrorCodes::LOGICAL_ERROR);
rpn_stack.emplace_back(element.set_index->checkInRange(hyperrectangle, data_types));
rpn_stack.emplace_back(element.set_index->checkInRange(hyperrectangle, data_types, single_point));
if (element.function == RPNElement::FUNCTION_NOT_IN_SET)
rpn_stack.back() = !rpn_stack.back();
}

View File

@ -0,0 +1,14 @@
DROP TABLE IF EXISTS lower_test;
CREATE TABLE lower_test (
a Int32,
b String
) ENGINE=MergeTree
PARTITION BY b
ORDER BY a;
INSERT INTO lower_test (a,b) VALUES (1,'A'),(2,'B'),(3,'C');
SELECT a FROM lower_test WHERE lower(b) IN ('a','b') order by a;
DROP TABLE lower_test;