development [#METR-10498]

This commit is contained in:
Pavel Kartavyy 2014-03-20 16:25:26 +04:00
parent f8d9252cf4
commit 2a408f2841
2 changed files with 51 additions and 1 deletions

View File

@ -116,6 +116,37 @@ public:
#pragma GCC diagnostic pop
struct Set
{
public:
Set(DB::ASTPtr column_set_ptr_) : column_set_ptr(column_set_ptr_)
{
}
std::string toString()
{
std::ostringstream ss;
ss << "{";
bool first = true;
for (auto & n : data)
{
if (first)
{
ss << n;
first = false;
}
else
{
ss << ", " << n;
}
}
ss << "}";
return ss.str();
}
private:
DB::ASTPtr column_set_ptr;
};
/** Диапазон с открытыми или закрытыми концами; возможно, неограниченный.
*/
@ -295,6 +326,7 @@ private:
/// Атомы логического выражения.
FUNCTION_IN_RANGE,
FUNCTION_NOT_IN_RANGE,
FUNCTION_IN_SET,
FUNCTION_UNKNOWN, /// Может принимать любое значение.
/// Операторы логического выражения.
FUNCTION_NOT,
@ -320,6 +352,10 @@ private:
return "not";
case FUNCTION_UNKNOWN:
return "unknown";
case FUNCTION_IN_SET:
std::ostringstream ss;
ss << "(column " << key_column << " in " << set.toString() << ")";
return ss.str();
case FUNCTION_IN_RANGE:
case FUNCTION_NOT_IN_RANGE:
{
@ -337,6 +373,8 @@ private:
/// Для FUNCTION_IN_RANGE и FUNCTION_NOT_IN_RANGE.
Range range;
size_t key_column;
/// Для FUNCTION_IN_SET
Set set;
};
typedef std::vector<RPNElement> RPN;

View File

@ -1,6 +1,7 @@
#include <DB/Storages/MergeTree/PKCondition.h>
#include <DB/DataTypes/DataTypesNumberFixed.h>
#include <DB/Interpreters/ExpressionAnalyzer.h>
#include <DB/Columns/ColumnSet.h>
namespace DB
{
@ -114,7 +115,7 @@ void PKCondition::traverseAST(ASTPtr & node, Block & block_with_constants)
bool PKCondition::atomFromAST(ASTPtr & node, Block & block_with_constants, RPNElement & out)
{
/// Фнукции < > = != <= >=, у которых один агрумент константа, другой - один из столбцов первичного ключа.
/// Фнукции < > = != <= >= in , у которых один агрумент константа, другой - один из столбцов первичного ключа.
if (ASTFunction * func = dynamic_cast<ASTFunction *>(&*node))
{
ASTs & args = dynamic_cast<ASTExpressionList &>(*func->arguments).children;
@ -126,6 +127,7 @@ bool PKCondition::atomFromAST(ASTPtr & node, Block & block_with_constants, RPNEl
bool inverted;
size_t column;
Field value;
if (pk_columns.count(args[0]->getColumnName()) && getConstant(args[1], block_with_constants, value))
{
inverted = false;
@ -136,6 +138,11 @@ bool PKCondition::atomFromAST(ASTPtr & node, Block & block_with_constants, RPNEl
inverted = true;
column = pk_columns[args[1]->getColumnName()];
}
/// для In, notIn
else if (pk_columns.count(args[0]->getColumnName()) && dynamic_cast<DB::ColumnSet *>(args[1]))
{
column = pk_columns[args[1]->getColumnName()];
}
else
return false;
@ -172,6 +179,11 @@ bool PKCondition::atomFromAST(ASTPtr & node, Block & block_with_constants, RPNEl
out.range = Range::createRightBounded(value, true);
else if (func->name == "greaterOrEquals")
out.range = Range::createLeftBounded(value, true);
else if (func->name == "in" || func->name == "notIn")
{
out.function = RPNElement::FUNCTION_IN_SET;
out.set = Set(args[1]);
}
else
return false;