@@ -819,10 +819,53 @@ AstNode* Ast::createNodeUnaryOperator(AstNodeType type, AstNode const* operand)
819
819
// / @brief create an AST binary operator node
820
820
AstNode* Ast::createNodeBinaryOperator (AstNodeType type, AstNode const * lhs,
821
821
AstNode const * rhs) {
822
+ // do a bit of normalization here, so that attribute accesses are normally
823
+ // on the left side of a comparison. this may allow future simplifications
824
+ // of code that check filter conditions
825
+ // note that there will still be cases in which both sides of the comparsion
826
+ // contain an attribute access, e.g. doc.value1 == doc.value2
827
+ bool swap = false ;
828
+ if (type == NODE_TYPE_OPERATOR_BINARY_EQ &&
829
+ rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS &&
830
+ lhs->type != NODE_TYPE_ATTRIBUTE_ACCESS) {
831
+ // value == doc.value => doc.value == value
832
+ swap = true ;
833
+ } else if (type == NODE_TYPE_OPERATOR_BINARY_NE &&
834
+ rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS &&
835
+ lhs->type != NODE_TYPE_ATTRIBUTE_ACCESS) {
836
+ // value != doc.value => doc.value != value
837
+ swap = true ;
838
+ } else if (type == NODE_TYPE_OPERATOR_BINARY_GT &&
839
+ rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS &&
840
+ lhs->type != NODE_TYPE_ATTRIBUTE_ACCESS) {
841
+ // value > doc.value => doc.value < value
842
+ type = NODE_TYPE_OPERATOR_BINARY_LT;
843
+ swap = true ;
844
+ } else if (type == NODE_TYPE_OPERATOR_BINARY_LT &&
845
+ rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS &&
846
+ lhs->type != NODE_TYPE_ATTRIBUTE_ACCESS) {
847
+ // value < doc.value => doc.value > value
848
+ type = NODE_TYPE_OPERATOR_BINARY_GT;
849
+ swap = true ;
850
+ } else if (type == NODE_TYPE_OPERATOR_BINARY_GE &&
851
+ rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS &&
852
+ lhs->type != NODE_TYPE_ATTRIBUTE_ACCESS) {
853
+ // value >= doc.value => doc.value <= value
854
+ type = NODE_TYPE_OPERATOR_BINARY_LE;
855
+ swap = true ;
856
+ } else if (type == NODE_TYPE_OPERATOR_BINARY_LE &&
857
+ rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS &&
858
+ lhs->type != NODE_TYPE_ATTRIBUTE_ACCESS) {
859
+ // value <= doc.value => doc.value >= value
860
+ type = NODE_TYPE_OPERATOR_BINARY_GE;
861
+ swap = true ;
862
+ }
863
+
822
864
AstNode* node = createNode (type);
823
865
node->reserve (2 );
824
- node->addMember (lhs);
825
- node->addMember (rhs);
866
+
867
+ node->addMember (swap ? rhs : lhs);
868
+ node->addMember (swap ? lhs : rhs);
826
869
827
870
// initialize sortedness information (currently used for the IN/NOT IN
828
871
// operators only) for nodes of type ==, < or <=, the bool means if the range
0 commit comments