fix for mixed && and || queries
This commit is contained in:
parent
812930285e
commit
2324f8cc9b
|
@ -107,27 +107,37 @@ struct pred : seq< and_pred, star< or_ext > > {};
|
||||||
struct ParserState
|
struct ParserState
|
||||||
{
|
{
|
||||||
std::vector<Predicate *> predicate_stack;
|
std::vector<Predicate *> predicate_stack;
|
||||||
Predicate ¤t() {
|
Predicate ¤t()
|
||||||
|
{
|
||||||
return *predicate_stack.back();
|
return *predicate_stack.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool current_is_compound()
|
||||||
|
{
|
||||||
|
return current().type == Predicate::Type::And || current().type == Predicate::Type::Or;
|
||||||
|
}
|
||||||
|
|
||||||
bool negate_next = false;
|
bool negate_next = false;
|
||||||
|
|
||||||
void addExpression(Expression && exp)
|
void addExpression(Expression && exp)
|
||||||
{
|
{
|
||||||
if (current().type == Predicate::Type::Comparison) {
|
Predicate &cur = current();
|
||||||
current().cmpr.expr[1] = std::move(exp);
|
if (cur.type == Predicate::Type::Comparison) {
|
||||||
|
cur.cmpr.expr[1] = std::move(exp);
|
||||||
predicate_stack.pop_back();
|
predicate_stack.pop_back();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
assert(current_is_compound());
|
||||||
|
|
||||||
Predicate p(Predicate::Type::Comparison);
|
Predicate p(Predicate::Type::Comparison);
|
||||||
p.cmpr.expr[0] = std::move(exp);
|
p.cmpr.expr[0] = std::move(exp);
|
||||||
if (negate_next) {
|
if (negate_next) {
|
||||||
p.negate = true;
|
p.negate = true;
|
||||||
negate_next = false;
|
negate_next = false;
|
||||||
}
|
}
|
||||||
current().cpnd.sub_predicates.emplace_back(std::move(p));
|
|
||||||
predicate_stack.push_back(¤t().cpnd.sub_predicates.back());
|
cur.cpnd.sub_predicates.emplace_back(std::move(p));
|
||||||
|
predicate_stack.push_back(&cur.cpnd.sub_predicates.back());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -147,6 +157,7 @@ template<> struct action< and_ext >
|
||||||
static void apply( const input & in, ParserState & state )
|
static void apply( const input & in, ParserState & state )
|
||||||
{
|
{
|
||||||
DEBUG_PRINT_TOKEN("<and>");
|
DEBUG_PRINT_TOKEN("<and>");
|
||||||
|
assert(state.current_is_compound());
|
||||||
|
|
||||||
// if we were put into an OR group we need to rearrange
|
// if we were put into an OR group we need to rearrange
|
||||||
auto ¤t = state.current();
|
auto ¤t = state.current();
|
||||||
|
@ -177,6 +188,7 @@ template<> struct action< or_ext >
|
||||||
static void apply( const input & in, ParserState & state )
|
static void apply( const input & in, ParserState & state )
|
||||||
{
|
{
|
||||||
DEBUG_PRINT_TOKEN("<or>");
|
DEBUG_PRINT_TOKEN("<or>");
|
||||||
|
assert(state.current_is_compound());
|
||||||
|
|
||||||
// if already an OR group do nothing
|
// if already an OR group do nothing
|
||||||
auto ¤t = state.current();
|
auto ¤t = state.current();
|
||||||
|
@ -186,15 +198,17 @@ template<> struct action< or_ext >
|
||||||
|
|
||||||
// if only two predicates in the group, then convert to OR
|
// if only two predicates in the group, then convert to OR
|
||||||
auto &sub_preds = state.current().cpnd.sub_predicates;
|
auto &sub_preds = state.current().cpnd.sub_predicates;
|
||||||
if (sub_preds.size()) {
|
assert(sub_preds.size() > 1);
|
||||||
|
if (sub_preds.size() == 2) {
|
||||||
current.type = Predicate::Type::Or;
|
current.type = Predicate::Type::Or;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// split the current group into to groups which are ORed together
|
// split the current group into to groups which are ORed together
|
||||||
Predicate pred1(Predicate::Type::And), pred2(Predicate::Type::And);
|
Predicate pred1(Predicate::Type::And), pred2(Predicate::Type::And);
|
||||||
pred1.cpnd.sub_predicates.insert(sub_preds.begin(), sub_preds.back());
|
std::vector<Predicate>::iterator second_last = sub_preds.end() - 2;
|
||||||
pred2.cpnd.sub_predicates.push_back(std::move(sub_preds.back()));
|
pred1.cpnd.sub_predicates.insert(pred1.cpnd.sub_predicates.begin(), sub_preds.begin(), second_last);
|
||||||
|
pred2.cpnd.sub_predicates.insert(pred2.cpnd.sub_predicates.begin(), second_last, sub_preds.end());
|
||||||
|
|
||||||
current.type = Predicate::Type::Or;
|
current.type = Predicate::Type::Or;
|
||||||
sub_preds.clear();
|
sub_preds.clear();
|
||||||
|
|
Loading…
Reference in New Issue