blob: fd9b78a5f52ae347463f8cd9d9de229e8b797577 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
#include <Parsers/makeASTForLogicalFunction.h>
#include <Parsers/ASTLiteral.h>
#include <Parsers/ASTFunction.h>
#include <Parsers/ASTExpressionList.h>
#include <Common/FieldVisitorConvertToNumber.h>
#include <boost/range/algorithm_ext/erase.hpp>
namespace DB
{
ASTPtr makeASTForLogicalAnd(ASTs && arguments)
{
bool partial_result = true;
boost::range::remove_erase_if(arguments, [&](const ASTPtr & argument) -> bool
{
bool b;
if (!tryGetLiteralBool(argument.get(), b))
return false;
partial_result &= b;
return true;
});
if (!partial_result)
return std::make_shared<ASTLiteral>(Field{static_cast<UInt8>(0)});
if (arguments.empty())
return std::make_shared<ASTLiteral>(Field{static_cast<UInt8>(1)});
if (arguments.size() == 1)
return arguments[0];
auto function = std::make_shared<ASTFunction>();
auto exp_list = std::make_shared<ASTExpressionList>();
function->name = "and";
function->arguments = exp_list;
function->children.push_back(exp_list);
exp_list->children = std::move(arguments);
return function;
}
ASTPtr makeASTForLogicalOr(ASTs && arguments)
{
bool partial_result = false;
boost::range::remove_erase_if(arguments, [&](const ASTPtr & argument) -> bool
{
bool b;
if (!tryGetLiteralBool(argument.get(), b))
return false;
partial_result |= b;
return true;
});
if (partial_result)
return std::make_shared<ASTLiteral>(Field{static_cast<UInt8>(1)});
if (arguments.empty())
return std::make_shared<ASTLiteral>(Field{static_cast<UInt8>(0)});
if (arguments.size() == 1)
return arguments[0];
auto function = std::make_shared<ASTFunction>();
auto exp_list = std::make_shared<ASTExpressionList>();
function->name = "or";
function->arguments = exp_list;
function->children.push_back(exp_list);
exp_list->children = std::move(arguments);
return function;
}
bool tryGetLiteralBool(const IAST * ast, bool & value)
{
if (!ast)
return false;
try
{
if (const ASTLiteral * literal = ast->as<ASTLiteral>())
{
value = !literal->value.isNull() && applyVisitor(FieldVisitorConvertToNumber<bool>(), literal->value);
return true;
}
return false;
}
catch (...)
{
return false;
}
}
}
|