mirror of https://gitee.com/bigwinds/arangodb
normalize AQL filter conditions, so that attribute accesses are normally placed on the left hand side of the condition (#9217)
This commit is contained in:
parent
3f603f024f
commit
d1a6d23c36
|
@ -819,10 +819,53 @@ AstNode* Ast::createNodeUnaryOperator(AstNodeType type, AstNode const* operand)
|
||||||
/// @brief create an AST binary operator node
|
/// @brief create an AST binary operator node
|
||||||
AstNode* Ast::createNodeBinaryOperator(AstNodeType type, AstNode const* lhs,
|
AstNode* Ast::createNodeBinaryOperator(AstNodeType type, AstNode const* lhs,
|
||||||
AstNode const* rhs) {
|
AstNode const* rhs) {
|
||||||
|
// do a bit of normalization here, so that attribute accesses are normally
|
||||||
|
// on the left side of a comparison. this may allow future simplifications
|
||||||
|
// of code that check filter conditions
|
||||||
|
// note that there will still be cases in which both sides of the comparsion
|
||||||
|
// contain an attribute access, e.g. doc.value1 == doc.value2
|
||||||
|
bool swap = false;
|
||||||
|
if (type == NODE_TYPE_OPERATOR_BINARY_EQ &&
|
||||||
|
rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS &&
|
||||||
|
lhs->type != NODE_TYPE_ATTRIBUTE_ACCESS) {
|
||||||
|
// value == doc.value => doc.value == value
|
||||||
|
swap = true;
|
||||||
|
} else if (type == NODE_TYPE_OPERATOR_BINARY_NE &&
|
||||||
|
rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS &&
|
||||||
|
lhs->type != NODE_TYPE_ATTRIBUTE_ACCESS) {
|
||||||
|
// value != doc.value => doc.value != value
|
||||||
|
swap = true;
|
||||||
|
} else if (type == NODE_TYPE_OPERATOR_BINARY_GT &&
|
||||||
|
rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS &&
|
||||||
|
lhs->type != NODE_TYPE_ATTRIBUTE_ACCESS) {
|
||||||
|
// value > doc.value => doc.value < value
|
||||||
|
type = NODE_TYPE_OPERATOR_BINARY_LT;
|
||||||
|
swap = true;
|
||||||
|
} else if (type == NODE_TYPE_OPERATOR_BINARY_LT &&
|
||||||
|
rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS &&
|
||||||
|
lhs->type != NODE_TYPE_ATTRIBUTE_ACCESS) {
|
||||||
|
// value < doc.value => doc.value > value
|
||||||
|
type = NODE_TYPE_OPERATOR_BINARY_GT;
|
||||||
|
swap = true;
|
||||||
|
} else if (type == NODE_TYPE_OPERATOR_BINARY_GE &&
|
||||||
|
rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS &&
|
||||||
|
lhs->type != NODE_TYPE_ATTRIBUTE_ACCESS) {
|
||||||
|
// value >= doc.value => doc.value <= value
|
||||||
|
type = NODE_TYPE_OPERATOR_BINARY_LE;
|
||||||
|
swap = true;
|
||||||
|
} else if (type == NODE_TYPE_OPERATOR_BINARY_LE &&
|
||||||
|
rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS &&
|
||||||
|
lhs->type != NODE_TYPE_ATTRIBUTE_ACCESS) {
|
||||||
|
// value <= doc.value => doc.value >= value
|
||||||
|
type = NODE_TYPE_OPERATOR_BINARY_GE;
|
||||||
|
swap = true;
|
||||||
|
}
|
||||||
|
|
||||||
AstNode* node = createNode(type);
|
AstNode* node = createNode(type);
|
||||||
node->reserve(2);
|
node->reserve(2);
|
||||||
node->addMember(lhs);
|
|
||||||
node->addMember(rhs);
|
node->addMember(swap ? rhs : lhs);
|
||||||
|
node->addMember(swap ? lhs : rhs);
|
||||||
|
|
||||||
// initialize sortedness information (currently used for the IN/NOT IN
|
// initialize sortedness information (currently used for the IN/NOT IN
|
||||||
// operators only) for nodes of type ==, < or <=, the bool means if the range
|
// operators only) for nodes of type ==, < or <=, the bool means if the range
|
||||||
|
|
Loading…
Reference in New Issue