fn test_parse_predicate()

in interactive_engine/executor/ir/graph_proxy/src/utils/expr/eval_pred.rs [549:841]


    fn test_parse_predicate() {
        let expr = str_to_expr_pb("1".to_string()).unwrap();
        let p_eval = PEvaluator::try_from(expr).unwrap();
        match &p_eval {
            PEvaluator::Predicates(pred) => {
                assert_eq!(pred.clone(), Predicates::SingleItem(Operand::Const(object!(1))));
            }
            PEvaluator::General(_) => panic!("should be predicate"),
        }
        assert!(p_eval
            .eval_bool::<(), NoneContext>(None)
            .unwrap());

        let expr = str_to_expr_pb("@a.name".to_string()).unwrap();
        let p_eval = PEvaluator::try_from(expr).unwrap();
        match &p_eval {
            PEvaluator::Predicates(pred) => {
                assert_eq!(
                    pred.clone(),
                    Predicates::SingleItem(Operand::Var {
                        tag: Some("a".into()),
                        prop_key: Some(PropKey::Key("name".into()))
                    })
                );
            }
            PEvaluator::General(_) => panic!("should be predicate"),
        }
        assert!(!p_eval
            .eval_bool::<(), NoneContext>(None)
            .unwrap());

        let expr = str_to_expr_pb("!@a.name".to_string()).unwrap();
        let p_eval = PEvaluator::try_from(expr).unwrap();
        match &p_eval {
            PEvaluator::Predicates(pred) => {
                assert_eq!(
                    pred.clone(),
                    Predicates::SingleItem(Operand::Var {
                        tag: Some("a".into()),
                        prop_key: Some(PropKey::Key("name".into()))
                    })
                    .not()
                );
            }
            PEvaluator::General(_) => panic!("should be predicate"),
        }
        assert!(p_eval
            .eval_bool::<(), NoneContext>(None)
            .unwrap());

        let expr = str_to_expr_pb("1 > 2".to_string()).unwrap();
        let p_eval = PEvaluator::try_from(expr).unwrap();
        match &p_eval {
            PEvaluator::Predicates(pred) => {
                assert_eq!(
                    pred.clone(),
                    Predicates::Binary(Predicate {
                        left: Operand::Const(object!(1)),
                        cmp: common_pb::Logical::Gt,
                        right: Operand::Const(object!(2)),
                    })
                );
            }
            PEvaluator::General(_) => panic!("should be predicate"),
        }
        assert!(!p_eval
            .eval_bool::<(), NoneContext>(None)
            .unwrap());

        let expr = str_to_expr_pb("!(1 > 2)".to_string()).unwrap();
        let p_eval = PEvaluator::try_from(expr).unwrap();
        match &p_eval {
            PEvaluator::Predicates(pred) => {
                assert_eq!(
                    pred.clone(),
                    Predicates::Binary(Predicate {
                        left: Operand::Const(object!(1)),
                        cmp: common_pb::Logical::Gt,
                        right: Operand::Const(object!(2)),
                    })
                    .not()
                );
            }
            PEvaluator::General(_) => panic!("should be predicate"),
        }
        assert!(p_eval
            .eval_bool::<(), NoneContext>(None)
            .unwrap());

        let expr = str_to_expr_pb("!(!(!(!(1 > 2))))".to_string()).unwrap();
        let p_eval = PEvaluator::try_from(expr).unwrap();
        match &p_eval {
            PEvaluator::Predicates(pred) => {
                assert_eq!(
                    pred.clone(),
                    Predicates::Binary(Predicate {
                        left: Operand::Const(object!(1)),
                        cmp: common_pb::Logical::Gt,
                        right: Operand::Const(object!(2)),
                    })
                    .not()
                    .not()
                    .not()
                    .not()
                );
            }
            PEvaluator::General(_) => panic!("should be predicate"),
        }
        assert!(!p_eval
            .eval_bool::<(), NoneContext>(None)
            .unwrap());

        let expr = str_to_expr_pb("1 && 1 > 2".to_string()).unwrap();
        let p_eval = PEvaluator::try_from(expr).unwrap();
        match &p_eval {
            PEvaluator::Predicates(pred) => {
                assert_eq!(
                    pred.clone(),
                    Predicates::SingleItem(Operand::Const(object!(1))).and(Predicates::Binary(Predicate {
                        left: Operand::Const(object!(1)),
                        cmp: common_pb::Logical::Gt,
                        right: Operand::Const(object!(2)),
                    }))
                );
            }
            PEvaluator::General(_) => panic!("should be predicate"),
        }
        assert!(!p_eval
            .eval_bool::<(), NoneContext>(None)
            .unwrap());

        let expr = str_to_expr_pb("!@a.name && @a.age > 2 || @b.~id == 10".to_string()).unwrap();
        let p_eval = PEvaluator::try_from(expr).unwrap();
        match &p_eval {
            PEvaluator::Predicates(pred) => {
                assert_eq!(
                    pred.clone(),
                    Predicates::not(Predicates::SingleItem(Operand::Var {
                        tag: Some("a".into()),
                        prop_key: Some(PropKey::Key("name".into()))
                    }))
                    .and(Predicates::Binary(Predicate {
                        left: Operand::Var {
                            tag: Some("a".into()),
                            prop_key: Some(PropKey::Key("age".into()))
                        },
                        cmp: common_pb::Logical::Gt,
                        right: Operand::Const(object!(2)),
                    }))
                    .or(Predicates::Binary(Predicate {
                        left: Operand::Var { tag: Some("b".into()), prop_key: Some(PropKey::Id) },
                        cmp: common_pb::Logical::Eq,
                        right: Operand::Const(object!(10)),
                    }))
                );
            }
            PEvaluator::General(_) => panic!("should be predicate"),
        }

        let expr = str_to_expr_pb(
            "(@a.name == \"John\" && @a.age > 27) || (@b.~label == 11 && @b.name == \"Alien\")".to_string(),
        )
        .unwrap();
        let p_eval = PEvaluator::try_from(expr).unwrap();
        match &p_eval {
            PEvaluator::Predicates(pred) => assert_eq!(
                pred.clone(),
                Predicates::Binary(Predicate {
                    left: Operand::Var {
                        tag: Some("a".into()),
                        prop_key: Some(PropKey::Key("name".into()))
                    },
                    cmp: common_pb::Logical::Eq,
                    right: Operand::Const(object!("John")),
                })
                .and(Predicates::Binary(Predicate {
                    left: Operand::Var {
                        tag: Some("a".into()),
                        prop_key: Some(PropKey::Key("age".into()))
                    },
                    cmp: common_pb::Logical::Gt,
                    right: Operand::Const(27_i64.into()),
                }))
                .or(Predicates::Binary(Predicate {
                    left: Operand::Var { tag: Some("b".into()), prop_key: Some(PropKey::Label) },
                    cmp: common_pb::Logical::Eq,
                    right: Operand::Const(11_i64.into()),
                })
                .and(Predicates::Binary(Predicate {
                    left: Operand::Var {
                        tag: Some("b".into()),
                        prop_key: Some(PropKey::Key("name".into()))
                    },
                    cmp: common_pb::Logical::Eq,
                    right: Operand::Const(object!("Alien")),
                })))
            ),
            PEvaluator::General(_) => panic!("should be predicate"),
        }

        let expr = str_to_expr_pb(
            "@a.name == \"John\" && ((@a.age > 27 || !(@b.~label)) && @b.name == \"Alien\")".to_string(),
        )
        .unwrap();
        let p_eval = PEvaluator::try_from(expr).unwrap();
        match &p_eval {
            PEvaluator::Predicates(pred) => assert_eq!(
                pred.clone(),
                Predicates::Binary(Predicate {
                    left: Operand::Var {
                        tag: Some("a".into()),
                        prop_key: Some(PropKey::Key("name".into()))
                    },
                    cmp: common_pb::Logical::Eq,
                    right: Operand::Const(object!("John")),
                })
                .and(
                    Predicates::Binary(Predicate {
                        left: Operand::Var {
                            tag: Some("a".into()),
                            prop_key: Some(PropKey::Key("age".into()))
                        },
                        cmp: common_pb::Logical::Gt,
                        right: Operand::Const(27_i64.into()),
                    })
                    .or(Predicates::not(Predicates::SingleItem(Operand::Var {
                        tag: Some("b".into()),
                        prop_key: Some(PropKey::Label)
                    })))
                    .and(Predicates::Binary(Predicate {
                        left: Operand::Var {
                            tag: Some("b".into()),
                            prop_key: Some(PropKey::Key("name".into()))
                        },
                        cmp: common_pb::Logical::Eq,
                        right: Operand::Const(object!("Alien")),
                    }))
                )
            ),
            PEvaluator::General(_) => panic!("should be predicate"),
        }

        let expr = str_to_expr_pb("isnull @a.name".to_string()).unwrap();
        let p_eval = PEvaluator::try_from(expr).unwrap();
        match &p_eval {
            PEvaluator::Predicates(pred) => {
                assert_eq!(
                    pred.clone(),
                    Predicates::Unary(UnaryPredicate {
                        operand: Operand::Var {
                            tag: Some("a".into()),
                            prop_key: Some(PropKey::Key("name".into()))
                        },
                        cmp: common_pb::Logical::Isnull,
                    })
                );
            }
            PEvaluator::General(_) => panic!("should be predicate"),
        }

        let expr = str_to_expr_pb("isnull @a.name && @a.age > 2 || isnull @b.age".to_string()).unwrap();
        let p_eval = PEvaluator::try_from(expr).unwrap();
        match &p_eval {
            PEvaluator::Predicates(pred) => {
                assert_eq!(
                    pred.clone(),
                    Predicates::Unary(UnaryPredicate {
                        operand: Operand::Var {
                            tag: Some("a".into()),
                            prop_key: Some(PropKey::Key("name".into()))
                        },
                        cmp: common_pb::Logical::Isnull,
                    })
                    .and(Predicates::Binary(Predicate {
                        left: Operand::Var {
                            tag: Some("a".into()),
                            prop_key: Some(PropKey::Key("age".into()))
                        },
                        cmp: common_pb::Logical::Gt,
                        right: Operand::Const(object!(2)),
                    }))
                    .or(Predicates::Unary(UnaryPredicate {
                        operand: Operand::Var {
                            tag: Some("b".into()),
                            prop_key: Some(PropKey::Key("age".into()))
                        },
                        cmp: common_pb::Logical::Isnull,
                    }))
                );
            }
            PEvaluator::General(_) => panic!("should be predicate"),
        }
    }