mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 07:31:57 +00:00
Merge pull request #40740 from amosbird/row-policy-index-fix-1
Use index when row_policy_filter is always false
This commit is contained in:
commit
86516d3bb4
@ -865,6 +865,7 @@ MergeTreeDataSelectAnalysisResultPtr ReadFromMergeTree::selectRangesToRead(
|
||||
|
||||
size_t total_parts = parts.size();
|
||||
|
||||
/// TODO Support row_policy_filter and additional_filters
|
||||
auto part_values = MergeTreeDataSelectExecutor::filterPartsByVirtualColumns(data, parts, query_info.query, context);
|
||||
if (part_values && part_values->empty())
|
||||
return std::make_shared<MergeTreeDataSelectAnalysisResult>(MergeTreeDataSelectAnalysisResult{.result = std::move(result)});
|
||||
@ -923,6 +924,9 @@ MergeTreeDataSelectAnalysisResultPtr ReadFromMergeTree::selectRangesToRead(
|
||||
}
|
||||
LOG_DEBUG(log, "Key condition: {}", key_condition->toString());
|
||||
|
||||
if (key_condition->alwaysFalse())
|
||||
return std::make_shared<MergeTreeDataSelectAnalysisResult>(MergeTreeDataSelectAnalysisResult{.result = std::move(result)});
|
||||
|
||||
const auto & select = query_info.query->as<ASTSelectQuery &>();
|
||||
|
||||
size_t total_marks_pk = 0;
|
||||
|
@ -2463,7 +2463,6 @@ BoolMask KeyCondition::checkInHyperrectangle(
|
||||
return rpn_stack[0];
|
||||
}
|
||||
|
||||
|
||||
bool KeyCondition::mayBeTrueInRange(
|
||||
size_t used_key_size,
|
||||
const FieldRef * left_keys,
|
||||
@ -2474,6 +2473,7 @@ bool KeyCondition::mayBeTrueInRange(
|
||||
}
|
||||
|
||||
String KeyCondition::RPNElement::toString() const { return toString("column " + std::to_string(key_column), false); }
|
||||
|
||||
String KeyCondition::RPNElement::toString(std::string_view column_name, bool print_constants) const
|
||||
{
|
||||
auto print_wrapped_column = [this, &column_name, print_constants](WriteBuffer & buf)
|
||||
@ -2563,10 +2563,12 @@ bool KeyCondition::alwaysUnknownOrTrue() const
|
||||
{
|
||||
return unknownOrAlwaysTrue(false);
|
||||
}
|
||||
|
||||
bool KeyCondition::anyUnknownOrAlwaysTrue() const
|
||||
{
|
||||
return unknownOrAlwaysTrue(true);
|
||||
}
|
||||
|
||||
bool KeyCondition::unknownOrAlwaysTrue(bool unknown_any) const
|
||||
{
|
||||
std::vector<UInt8> rpn_stack;
|
||||
@ -2627,6 +2629,80 @@ bool KeyCondition::unknownOrAlwaysTrue(bool unknown_any) const
|
||||
return rpn_stack[0];
|
||||
}
|
||||
|
||||
bool KeyCondition::alwaysFalse() const
|
||||
{
|
||||
/// 0: always_false, 1: always_true, 2: non_const
|
||||
std::vector<UInt8> rpn_stack;
|
||||
|
||||
for (const auto & element : rpn)
|
||||
{
|
||||
if (element.function == RPNElement::ALWAYS_TRUE)
|
||||
{
|
||||
rpn_stack.push_back(1);
|
||||
}
|
||||
else if (element.function == RPNElement::ALWAYS_FALSE)
|
||||
{
|
||||
rpn_stack.push_back(0);
|
||||
}
|
||||
else if (element.function == RPNElement::FUNCTION_NOT_IN_RANGE
|
||||
|| element.function == RPNElement::FUNCTION_IN_RANGE
|
||||
|| element.function == RPNElement::FUNCTION_IN_SET
|
||||
|| element.function == RPNElement::FUNCTION_NOT_IN_SET
|
||||
|| element.function == RPNElement::FUNCTION_IS_NULL
|
||||
|| element.function == RPNElement::FUNCTION_IS_NOT_NULL
|
||||
|| element.function == RPNElement::FUNCTION_UNKNOWN)
|
||||
{
|
||||
rpn_stack.push_back(2);
|
||||
}
|
||||
else if (element.function == RPNElement::FUNCTION_NOT)
|
||||
{
|
||||
assert(!rpn_stack.empty());
|
||||
|
||||
auto & arg = rpn_stack.back();
|
||||
if (arg == 0)
|
||||
arg = 1;
|
||||
else if (arg == 1)
|
||||
arg = 0;
|
||||
}
|
||||
else if (element.function == RPNElement::FUNCTION_AND)
|
||||
{
|
||||
assert(!rpn_stack.empty());
|
||||
|
||||
auto arg1 = rpn_stack.back();
|
||||
rpn_stack.pop_back();
|
||||
auto arg2 = rpn_stack.back();
|
||||
|
||||
if (arg1 == 0 || arg2 == 0)
|
||||
rpn_stack.back() = 0;
|
||||
else if (arg1 == 1 && arg2 == 1)
|
||||
rpn_stack.back() = 1;
|
||||
else
|
||||
rpn_stack.back() = 2;
|
||||
}
|
||||
else if (element.function == RPNElement::FUNCTION_OR)
|
||||
{
|
||||
assert(!rpn_stack.empty());
|
||||
|
||||
auto arg1 = rpn_stack.back();
|
||||
rpn_stack.pop_back();
|
||||
auto arg2 = rpn_stack.back();
|
||||
|
||||
if (arg1 == 1 || arg2 == 1)
|
||||
rpn_stack.back() = 1;
|
||||
else if (arg1 == 0 && arg2 == 0)
|
||||
rpn_stack.back() = 0;
|
||||
else
|
||||
rpn_stack.back() = 2;
|
||||
}
|
||||
else
|
||||
throw Exception("Unexpected function type in KeyCondition::RPNElement", ErrorCodes::LOGICAL_ERROR);
|
||||
}
|
||||
|
||||
if (rpn_stack.size() != 1)
|
||||
throw Exception("Unexpected stack size in KeyCondition::alwaysFalse", ErrorCodes::LOGICAL_ERROR);
|
||||
|
||||
return rpn_stack[0] == 0;
|
||||
}
|
||||
|
||||
size_t KeyCondition::getMaxKeyColumn() const
|
||||
{
|
||||
|
@ -279,6 +279,8 @@ public:
|
||||
/// Does not allow any FUNCTION_UNKNOWN (will instantly return true).
|
||||
bool anyUnknownOrAlwaysTrue() const;
|
||||
|
||||
bool alwaysFalse() const;
|
||||
|
||||
/// Get the maximum number of the key element used in the condition.
|
||||
size_t getMaxKeyColumn() const;
|
||||
|
||||
|
@ -0,0 +1,17 @@
|
||||
drop table if exists tbl;
|
||||
|
||||
create table tbl (s String, i int) engine MergeTree order by i;
|
||||
|
||||
insert into tbl values ('123', 123);
|
||||
|
||||
drop row policy if exists filter on tbl;
|
||||
|
||||
create row policy filter on tbl using 0 to all;
|
||||
|
||||
set max_rows_to_read = 0;
|
||||
|
||||
select * from tbl;
|
||||
|
||||
drop row policy filter on tbl;
|
||||
|
||||
drop table tbl;
|
Loading…
Reference in New Issue
Block a user