mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 07:31:57 +00:00
build fix [#METR-10498]
This commit is contained in:
parent
14168120f1
commit
a737895eb4
@ -74,6 +74,14 @@ namespace DB
|
||||
{
|
||||
return strcmp(lhs.data, rhs.data) < 0 ? true : false;
|
||||
}
|
||||
|
||||
inline std::ostream & operator<<(std::ostream & os, const StringRef & str)
|
||||
{
|
||||
if (str.data)
|
||||
return os << str.toString();
|
||||
else
|
||||
return os;
|
||||
}
|
||||
}
|
||||
|
||||
namespace std
|
||||
|
@ -20,8 +20,7 @@
|
||||
#include <DB/Columns/ColumnConst.h>
|
||||
#include <DB/Columns/ColumnArray.h>
|
||||
|
||||
#include <DB/Storages/MergeTree/PKCondition.h>
|
||||
|
||||
#include <DB/Storages/MergeTree/BoolMask.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
@ -64,16 +63,18 @@ public:
|
||||
*/
|
||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result, bool negative) const;
|
||||
|
||||
std::string toString()
|
||||
std::string descibe()
|
||||
{
|
||||
if (type == KEY_64)
|
||||
return setToString(key64);
|
||||
else if (type == KEY_STRING)
|
||||
return setToString(key_string);
|
||||
else if (type == HASHED)
|
||||
return setToString(hashed);
|
||||
return "{hashed values}";
|
||||
else if (type == EMPTY)
|
||||
return "{}";
|
||||
else
|
||||
throw DB::Exception("Unknown type");
|
||||
}
|
||||
|
||||
void createOrderedSet()
|
||||
@ -87,14 +88,17 @@ public:
|
||||
std::sort(ordered_string.begin(), ordered_string.end());
|
||||
}
|
||||
|
||||
BoolMask mayBeTrueInRange(const Range & key_range)
|
||||
BoolMask mayBeTrueInRange(const Field & left, const Field & right)
|
||||
{
|
||||
if (type == KEY_64)
|
||||
return mayBeTrueInRangeImpl(key_range, ordered_key64);
|
||||
return mayBeTrueInRangeImpl(left, right, ordered_key64);
|
||||
else if (type == KEY_STRING)
|
||||
return mayBeTrueInRangeImpl(key_range, ordered_string);
|
||||
else
|
||||
throw DB::Exception("Unsupported set of type " << type);
|
||||
return mayBeTrueInRangeImpl(left, right, ordered_string);
|
||||
else{
|
||||
std::stringstream ss;
|
||||
ss << "Unsupported set of type " << type;
|
||||
throw DB::Exception(ss.str());
|
||||
}
|
||||
}
|
||||
private:
|
||||
/** Разные структуры данных, которые могут использоваться для проверки принадлежности
|
||||
@ -166,16 +170,17 @@ private:
|
||||
{
|
||||
std::stringstream ss;
|
||||
bool first = false;
|
||||
for (auto & n : set)
|
||||
|
||||
for (auto it = set.begin(); it != set.end(); ++it)
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
ss << n;
|
||||
ss << *it;
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << ", " << n;
|
||||
ss << ", " << *it;
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,34 +192,42 @@ private:
|
||||
std::vector<UInt64> ordered_key64;
|
||||
std::vector<StringRef> ordered_string;
|
||||
|
||||
template <class Set>
|
||||
BoolMask mayBeTrueInRangeImpl(const Range & key_range, const Set & set)
|
||||
template <class T>
|
||||
BoolMask mayBeTrueInRangeImpl(const Field & field_left, const Field & field_right, const std::vector<T> & v)
|
||||
{
|
||||
T left = field_left.get<T>();
|
||||
T right = field_right.get<T>();
|
||||
|
||||
bool can_be_true;
|
||||
bool can_be_false = true;
|
||||
|
||||
/// Если во всем диапазоне одинаковый ключ и он есть в Set, то выбираем блок для in и не выбираем для notIn
|
||||
if (key_range.left == key_range.right)
|
||||
if (left == right)
|
||||
{
|
||||
if (set.find(key_range.left) != set.end())
|
||||
if (std::find(v.begin(), v.end(), left) != v.end())
|
||||
{
|
||||
can_be_false = false;
|
||||
can_be_true = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
can_be_true = false;
|
||||
can_be_false = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto left_it = set.lower_boud(key_range.left);
|
||||
auto left_it = std::lower_bound(v.begin(), v.end(), left);
|
||||
/// если весь диапазон, правее in
|
||||
if (left_it == set.end())
|
||||
if (left_it == v.end())
|
||||
{
|
||||
can_be_true = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto right_it = set.upper_bound(key_range.right);
|
||||
auto right_it = std::upper_bound(v.begin(), v.end(), right);
|
||||
/// весь диапазон, левее in
|
||||
if (right_it == set.begin())
|
||||
if (right_it == v.begin())
|
||||
{
|
||||
can_be_true = false;
|
||||
}
|
||||
@ -239,7 +252,7 @@ private:
|
||||
|
||||
};
|
||||
|
||||
typedef SharedPtr<Set> SetPtr;
|
||||
typedef Poco::SharedPtr<Set> SetPtr;
|
||||
typedef std::vector<SetPtr> Sets;
|
||||
|
||||
|
||||
|
24
dbms/include/DB/Storages/MergeTree/BoolMask.h
Normal file
24
dbms/include/DB/Storages/MergeTree/BoolMask.h
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
/// Множество значений булевой переменной. То есть два булевых значения: может ли быть true, может ли быть false.
|
||||
struct BoolMask
|
||||
{
|
||||
bool can_be_true;
|
||||
bool can_be_false;
|
||||
|
||||
BoolMask() {}
|
||||
BoolMask(bool can_be_true_, bool can_be_false_) : can_be_true(can_be_true_), can_be_false(can_be_false_) {}
|
||||
|
||||
BoolMask operator &(const BoolMask & m)
|
||||
{
|
||||
return BoolMask(can_be_true && m.can_be_true, can_be_false || m.can_be_false);
|
||||
}
|
||||
BoolMask operator |(const BoolMask & m)
|
||||
{
|
||||
return BoolMask(can_be_true || m.can_be_true, can_be_false && m.can_be_false);
|
||||
}
|
||||
BoolMask operator !()
|
||||
{
|
||||
return BoolMask(can_be_false, can_be_true);
|
||||
}
|
||||
};
|
@ -9,6 +9,7 @@
|
||||
#include <DB/Parsers/ASTFunction.h>
|
||||
#include <DB/Parsers/ASTLiteral.h>
|
||||
#include <DB/Columns/ColumnSet.h>
|
||||
#include <DB/Storages/MergeTree/BoolMask.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
@ -115,29 +116,6 @@ public:
|
||||
bool operator() (const Array & l, const Array & r) const { return l < r; }
|
||||
};
|
||||
|
||||
/// Множество значений булевой переменной. То есть два булевых значения: может ли быть true, может ли быть false.
|
||||
struct BoolMask
|
||||
{
|
||||
bool can_be_true;
|
||||
bool can_be_false;
|
||||
|
||||
BoolMask() {}
|
||||
BoolMask(bool can_be_true_, bool can_be_false_) : can_be_true(can_be_true_), can_be_false(can_be_false_) {}
|
||||
|
||||
BoolMask operator &(const BoolMask & m)
|
||||
{
|
||||
return BoolMask(can_be_true && m.can_be_true, can_be_false || m.can_be_false);
|
||||
}
|
||||
BoolMask operator |(const BoolMask & m)
|
||||
{
|
||||
return BoolMask(can_be_true || m.can_be_true, can_be_false && m.can_be_false);
|
||||
}
|
||||
BoolMask operator !()
|
||||
{
|
||||
return BoolMask(can_be_false, can_be_true);
|
||||
}
|
||||
};
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
/** Диапазон с открытыми или закрытыми концами; возможно, неограниченный.
|
||||
@ -335,6 +313,7 @@ private:
|
||||
|
||||
String toString()
|
||||
{
|
||||
std::ostringstream ss;
|
||||
switch (function)
|
||||
{
|
||||
case FUNCTION_AND:
|
||||
@ -345,14 +324,15 @@ private:
|
||||
return "not";
|
||||
case FUNCTION_UNKNOWN:
|
||||
return "unknown";
|
||||
case FUNCTION_NOT_IN_SET:
|
||||
case FUNCTION_IN_SET:
|
||||
std::ostringstream ss;
|
||||
ss << "(column " << key_column << " in " << set->toString() << ")";
|
||||
{
|
||||
ss << "(column " << key_column << (function == FUNCTION_IN_SET ? " in " : " notIn ") << set->descibe() << ")";
|
||||
return ss.str();
|
||||
}
|
||||
case FUNCTION_IN_RANGE:
|
||||
case FUNCTION_NOT_IN_RANGE:
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "(column " << key_column << (function == FUNCTION_NOT_IN_RANGE ? " not" : "") << " in " << range.toString() << ")";
|
||||
return ss.str();
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <DB/DataTypes/DataTypesNumberFixed.h>
|
||||
#include <DB/Interpreters/ExpressionAnalyzer.h>
|
||||
#include <DB/Columns/ColumnSet.h>
|
||||
#include <DB/Columns/ColumnTuple.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
@ -139,10 +140,12 @@ bool PKCondition::atomFromAST(ASTPtr & node, Block & block_with_constants, RPNEl
|
||||
column = pk_columns[args[1]->getColumnName()];
|
||||
}
|
||||
/// для In, notIn
|
||||
else if (pk_columns.count(args[0]->getColumnName()) && dynamic_cast<DB::ColumnSet *>(args[1]))
|
||||
else if (pk_columns.count(args[0]->getColumnName()) && dynamic_cast<DB::ColumnSet *>(args[1].get()))
|
||||
{
|
||||
/// для in не бывает inverted
|
||||
inverted = false;
|
||||
/// не поддерживаем Primary Key, если аргумент функции in tuple
|
||||
if (dynamic_cast<DB::ColumnTuple*>(args[0]))
|
||||
if (dynamic_cast<DB::ColumnTuple*>(args[0].get()))
|
||||
return false;
|
||||
column = pk_columns[args[0]->getColumnName()];
|
||||
}
|
||||
@ -185,7 +188,7 @@ bool PKCondition::atomFromAST(ASTPtr & node, Block & block_with_constants, RPNEl
|
||||
else if (func->name == "in" || func->name == "notIn")
|
||||
{
|
||||
out.function = func->name == "in" ? RPNElement::FUNCTION_IN_SET : RPNElement::FUNCTION_NOT_IN_SET;
|
||||
out.set = (dynamic_cast<DB::ColumnSet *>(args[1])->getData();
|
||||
out.set = (dynamic_cast<DB::ColumnSet *>(args[1].get())->getData());
|
||||
out.set->createOrderedSet();
|
||||
}
|
||||
else
|
||||
@ -281,7 +284,7 @@ bool PKCondition::mayBeTrueInRange(const Field * left_pk, const Field * right_pk
|
||||
{
|
||||
const Range & key_range = key_ranges[element.key_column];
|
||||
|
||||
rpn_stack.push_back(element.set->mayBeTrueInRange(key_range));
|
||||
rpn_stack.push_back(element.set->mayBeTrueInRange(key_range.left, key_range.right));
|
||||
if (element.function == RPNElement::FUNCTION_NOT_IN_SET)
|
||||
rpn_stack.back() = !rpn_stack.back();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user