mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 08:40:50 +00:00
Fix partition pruner: non-monotonic function IN
This commit is contained in:
parent
81e56a06a3
commit
a19224bc9b
@ -267,7 +267,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual Monotonicity getMonotonicityForRange(const IDataType & /*type*/, const Field & /*left*/, const Field & /*right*/) const
|
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;
|
using Monotonicity = IFunctionBase::Monotonicity;
|
||||||
virtual Monotonicity getMonotonicityForRange(const IDataType & /*type*/, const Field & /*left*/, const Field & /*right*/) const
|
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).
|
/// For non-variadic functions, return number of arguments; otherwise return zero (that should be ignored).
|
||||||
|
@ -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
|
* 1: the intersection of the set and the range is non-empty
|
||||||
* 2: the range contains elements not in the set
|
* 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();
|
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(
|
std::optional<Range> new_range = KeyCondition::applyMonotonicFunctionsChainToRange(
|
||||||
key_ranges[indexes_mapping[i].key_index],
|
key_ranges[indexes_mapping[i].key_index],
|
||||||
indexes_mapping[i].functions,
|
indexes_mapping[i].functions,
|
||||||
data_types[indexes_mapping[i].key_index]);
|
data_types[indexes_mapping[i].key_index],
|
||||||
|
single_point);
|
||||||
|
|
||||||
if (!new_range)
|
if (!new_range)
|
||||||
return {true, true};
|
return {true, true};
|
||||||
|
@ -214,7 +214,7 @@ public:
|
|||||||
|
|
||||||
bool hasMonotonicFunctionsChain() const;
|
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:
|
private:
|
||||||
// If all arguments in tuple are key columns, we can optimize NOT IN when there is only one element.
|
// If all arguments in tuple are key columns, we can optimize NOT IN when there is only one element.
|
||||||
|
@ -448,7 +448,7 @@ KeyCondition::KeyCondition(
|
|||||||
{
|
{
|
||||||
for (size_t i = 0, size = key_column_names.size(); i < size; ++i)
|
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))
|
if (!key_columns.count(name))
|
||||||
key_columns[name] = i;
|
key_columns[name] = i;
|
||||||
}
|
}
|
||||||
@ -1999,7 +1999,7 @@ BoolMask KeyCondition::checkInHyperrectangle(
|
|||||||
if (!element.set_index)
|
if (!element.set_index)
|
||||||
throw Exception("Set for IN is not created yet", ErrorCodes::LOGICAL_ERROR);
|
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)
|
if (element.function == RPNElement::FUNCTION_NOT_IN_SET)
|
||||||
rpn_stack.back() = !rpn_stack.back();
|
rpn_stack.back() = !rpn_stack.back();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
1
|
||||||
|
2
|
@ -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;
|
Loading…
Reference in New Issue
Block a user