def test_should_visit_select_if_nested_query(self, mock_p, mock_c, mock_d): m = MagicMock() mock_p.return_value = mock_c.return_value = mock_d.return_value = m stmt = Parser().parse(""" SELECT id FROM (SELECT data, id FROM video \ WHERE data > 2) WHERE id>3;""")[0] converter = StatementToPlanConvertor() actual_plan = converter.visit(stmt) plans = [LogicalProject([TupleValueExpression('id')])] plans.append( LogicalFilter( ComparisonExpression(ExpressionType.COMPARE_GREATER, TupleValueExpression('id'), ConstantValueExpression(3)))) plans.append(LogicalQueryDerivedGet()) plans.append( LogicalProject( [TupleValueExpression('data'), TupleValueExpression('id')])) plans.append( LogicalFilter( ComparisonExpression(ExpressionType.COMPARE_GREATER, TupleValueExpression('data'), ConstantValueExpression(2)))) plans.append(LogicalGet(TableRef(TableInfo('video')), m)) expected_plan = None for plan in reversed(plans): if expected_plan: plan.append_child(expected_plan) expected_plan = plan self.assertEqual(expected_plan, actual_plan) wrong_plan = plans[0] for plan in plans[1:]: wrong_plan.append_child(plan) self.assertNotEqual(wrong_plan, actual_plan)
def test_logical_or(self): tpl_exp = TupleValueExpression(0) const_exp = ConstantValueExpression(1) comparison_expression_left = ComparisonExpression( ExpressionType.COMPARE_EQUAL, tpl_exp, const_exp) tpl_exp = TupleValueExpression(0) const_exp = ConstantValueExpression(1) comparison_expression_right = ComparisonExpression( ExpressionType.COMPARE_GREATER, tpl_exp, const_exp) logical_expr = LogicalExpression(ExpressionType.LOGICAL_OR, comparison_expression_left, comparison_expression_right) frame_1 = Frame(1, np.ones((1, 1)), None) frame_2 = Frame(2, 2 * np.ones((1, 1)), None) frame_3 = Frame(3, 3 * np.ones((1, 1)), None) input_batch = FrameBatch(frames=[ frame_1, frame_2, frame_3, ], info=None) expected_value = [[True], [True], [True]] output_value = logical_expr.evaluate(input_batch) self.assertEqual(expected_value, output_value)
def test_comparison_compare_lesser(self): const_exp1 = ConstantValueExpression(0) const_exp2 = ConstantValueExpression(2) cmpr_exp = ComparisonExpression(ExpressionType.COMPARE_LESSER, const_exp1, const_exp2) self.assertEqual([True], cmpr_exp.evaluate(None).frames[0].tolist())
def test_logical_or(self): const_exp1 = ConstantValueExpression(1) const_exp2 = ConstantValueExpression(1) comparison_expression_left = ComparisonExpression( ExpressionType.COMPARE_EQUAL, const_exp1, const_exp2 ) const_exp1 = ConstantValueExpression(1) const_exp2 = ConstantValueExpression(2) comparison_expression_right = ComparisonExpression( ExpressionType.COMPARE_GREATER, const_exp1, const_exp2 ) logical_expr = LogicalExpression( ExpressionType.LOGICAL_OR, comparison_expression_left, comparison_expression_right ) self.assertEqual( [True], logical_expr.evaluate(None).frames[0].tolist() )
def test_comparison_compare_lesser(self): tpl_exp = TupleValueExpression(0) const_exp = ConstantValueExpression(2) cmpr_exp = ComparisonExpression(ExpressionType.COMPARE_LESSER, tpl_exp, const_exp) tuple1 = [1, 2, 3] self.assertEqual(True, cmpr_exp.evaluate(tuple1, None))
def test_comparison_compare_greater(self): tpl_exp = TupleValueExpression(0) const_exp = ConstantValueExpression(1) cmpr_exp = ComparisonExpression(ExpressionType.COMPARE_GREATER, tpl_exp, const_exp) tuple1 = [2, 1, 1] self.assertEqual(True, cmpr_exp.evaluate(tuple1, None))
def test_comparison_compare_equal(self): tpl_exp = TupleValueExpression(0) const_exp = ConstantValueExpression(1) cmpr_exp = ComparisonExpression(ExpressionType.COMPARE_EQUAL, tpl_exp, const_exp) # ToDo implement a generic tuple class # to fetch the tuple from table tuple1 = [1, 2, 3] self.assertEqual(True, cmpr_exp.evaluate(tuple1, None))
def test_comparison_compare_greater(self): const_exp1 = ConstantValueExpression(1) const_exp2 = ConstantValueExpression(0) cmpr_exp = ComparisonExpression( ExpressionType.COMPARE_GREATER, const_exp1, const_exp2 ) self.assertEqual([True], cmpr_exp.evaluate(None))
def test_compare_doesnt_broadcast_when_rhs_is_list(self): tpl_exp = TupleValueExpression(0) const_exp = ConstantValueExpression([1]) cmpr_exp = ComparisonExpression(ExpressionType.COMPARE_EQUAL, tpl_exp, const_exp) compare = type("compare", (), { "value": 1, "__eq__": lambda s, x: s.value == x }) tuple1 = [[compare()], 2, 3] self.assertEqual([True], cmpr_exp.evaluate(tuple1, None))
def test_comparison_compare_neq(self): tpl_exp = TupleValueExpression(0) const_exp = ConstantValueExpression(1) cmpr_exp = ComparisonExpression(ExpressionType.COMPARE_NEQ, tpl_exp, const_exp) # checking not equal tuple1 = [2, 2, 3] self.assertEqual(True, cmpr_exp.evaluate(tuple1, None)) tuple1 = [3, 2, 3] self.assertEqual(True, cmpr_exp.evaluate(tuple1, None))
def test_comparison_compare_leq(self): tpl_exp = TupleValueExpression(0) const_exp = ConstantValueExpression(2) cmpr_exp = ComparisonExpression(ExpressionType.COMPARE_LEQ, tpl_exp, const_exp) # checking lesser tuple1 = [1, 2, 3] self.assertEqual(True, cmpr_exp.evaluate(tuple1, None)) # checking equal tuple2 = [2, 2, 3] self.assertEqual(True, cmpr_exp.evaluate(tuple2, None))
def test_comparison_compare_equal(self): tpl_exp = TupleValueExpression(0) const_exp = ConstantValueExpression(1) cmpr_exp = ComparisonExpression(ExpressionType.COMPARE_EQUAL, tpl_exp, const_exp) # ToDo implement a generic tuple class # to fetch the tuple from table compare = type("compare", (BasePrediction, ), { "value": 1, "__eq__": lambda s, x: s.value == x }) tuple1 = [[compare()], 2, 3] self.assertEqual([True], cmpr_exp.evaluate(tuple1, None))
def test_func_expr_with_cmpr_and_const_expr_should_work(self): frame_1 = Frame(1, np.ones((1, 1)), None) frame_2 = Frame(1, 2 * np.ones((1, 1)), None) outcome_1 = Prediction(frame_1, ["car", "bus"], [0.5, 0.6]) outcome_2 = Prediction(frame_1, ["bus"], [0.6]) func = FunctionExpression(lambda x: [outcome_1, outcome_2]) value_expr = ConstantValueExpression("car") expression_tree = ComparisonExpression(ExpressionType.COMPARE_EQUAL, func, value_expr) batch = FrameBatch(frames=[frame_1, frame_2]) self.assertEqual([True, False], expression_tree.evaluate(batch))
def test_comparison_compare_greater(self): tpl_exp = TupleValueExpression(0) const_exp = ConstantValueExpression(1) comparison_expression_left = ComparisonExpression( ExpressionType.COMPARE_EQUAL, tpl_exp, const_exp) tpl_exp = TupleValueExpression(0) const_exp = ConstantValueExpression(1) comparison_expression_right = ComparisonExpression( ExpressionType.COMPARE_GREATER, tpl_exp, const_exp) logical_expr = LogicalExpression(ExpressionType.LOGICAL_OR, comparison_expression_left, comparison_expression_right) tuple1 = [[1], 2, 3] self.assertEqual([True], logical_expr.evaluate(tuple1, None))
def test_comparison_compare_geq(self): tpl_exp = TupleValueExpression(0) const_exp = ConstantValueExpression(1) cmpr_exp = ComparisonExpression( ExpressionType.COMPARE_GEQ, tpl_exp, const_exp ) # checking greater x>=1 tuple1 = [[2], 2, 3] self.assertEqual([True], cmpr_exp.evaluate(tuple1, None)) # checking equal tuple2 = [[1], 2, 3] self.assertEqual([True], cmpr_exp.evaluate(tuple2, None))
def test_short_circuiting_or_partial(self): # tests whether right-hand side is partially executed with or tup_val_exp_l = TupleValueExpression(col_name=0) tup_val_exp_r = TupleValueExpression(col_name=1) comp_exp_l = ComparisonExpression( ExpressionType.COMPARE_EQUAL, tup_val_exp_l, tup_val_exp_r ) comp_exp_r = Mock(spec=ComparisonExpression) comp_exp_r.evaluate = Mock(return_value=Mock(frames=[[True], [False]])) logical_exp = LogicalExpression( ExpressionType.LOGICAL_OR, comp_exp_l, comp_exp_r ) tuples = Batch(pd.DataFrame( {0: [1, 2, 3, 4], 1: [5, 6, 3, 4]})) self.assertEqual( [True, False, True, True], logical_exp.evaluate(tuples).frames[0].tolist() ) comp_exp_r.evaluate.assert_called_once_with(tuples, mask=[0, 1])
def test_short_circuiting_or_complete(self): # tests whether right-hand side is bypassed completely with or tup_val_exp_l = TupleValueExpression(col_name=0) tup_val_exp_r = TupleValueExpression(col_name=1) comp_exp_l = ComparisonExpression( ExpressionType.COMPARE_EQUAL, tup_val_exp_l, tup_val_exp_r ) comp_exp_r = Mock(spec=ComparisonExpression) logical_exp = LogicalExpression( ExpressionType.LOGICAL_OR, comp_exp_l, comp_exp_r ) tuples = Batch(pd.DataFrame( {0: [1, 2, 3], 1: [1, 2, 3]})) self.assertEqual( [True, True, True], logical_exp.evaluate(tuples).frames[0].tolist() ) comp_exp_r.evaluate.assert_not_called()
def test_func_expr_with_cmpr_and_const_expr_should_work(self): frames = create_dataframe(2) outcome_1 = Outcome(pd.DataFrame( {'labels': ["car", "bus"], 'scores': [0.5, 0.6]}), 'labels') outcome_2 = Outcome(pd.DataFrame( {'labels': ["bus"], 'scores': [0.6]}), 'labels') func = FunctionExpression(lambda x: [outcome_1, outcome_2]) value_expr = ConstantValueExpression("car") expression_tree = ComparisonExpression(ExpressionType.COMPARE_EQUAL, func, value_expr) batch = Batch(frames=frames) self.assertEqual([True, False], expression_tree.evaluate(batch))
def test_if_expr_tree_is_equal(self): const_exp1 = ConstantValueExpression(0) const_exp2 = ConstantValueExpression(0) columnName1 = TupleValueExpression(col_name='DATA') columnName2 = TupleValueExpression(col_name='DATA') aggr_expr1 = AggregationExpression(ExpressionType.AGGREGATION_AVG, None, columnName1) aggr_expr2 = AggregationExpression(ExpressionType.AGGREGATION_AVG, None, columnName2) cmpr_exp1 = ComparisonExpression(ExpressionType.COMPARE_NEQ, aggr_expr1, const_exp1) cmpr_exp2 = ComparisonExpression(ExpressionType.COMPARE_NEQ, aggr_expr2, const_exp2) self.assertEqual(cmpr_exp1, cmpr_exp2)
def test_logical_not(self): const_exp1 = ConstantValueExpression(0) const_exp2 = ConstantValueExpression(1) comparison_expression_right = ComparisonExpression( ExpressionType.COMPARE_GREATER, const_exp1, const_exp2) logical_expr = LogicalExpression(ExpressionType.LOGICAL_NOT, None, comparison_expression_right) self.assertEqual([True], logical_expr.evaluate(None))
def test_comparison_compare_leq(self): tpl_exp = TupleValueExpression(0) const_exp = ConstantValueExpression(2) cmpr_exp = ComparisonExpression(ExpressionType.COMPARE_LEQ, tpl_exp, const_exp) frame_1 = Frame(1, np.ones((1, 1)), None) frame_2 = Frame(2, 2 * np.ones((1, 1)), None) frame_3 = Frame(3, 3 * np.ones((1, 1)), None) input_batch = FrameBatch(frames=[ frame_1, frame_2, frame_3, ], info=None) expected_value = [[True], [True], [False]] output_value = cmpr_exp.evaluate(input_batch) self.assertEqual(expected_value, output_value)
def test_should_visit_select_union_if_union_query(self, mock_p, mock_c, mock_d): m = MagicMock() mock_p.return_value = mock_c.return_value = mock_d.return_value = m stmt = Parser().parse(""" SELECT id FROM video WHERE id>3 UNION ALL SELECT id FROM video WHERE id<=3;""")[0] converter = StatementToPlanConvertor() actual_plan = converter.visit(stmt) left_plans = [LogicalProject([TupleValueExpression('id')])] left_plans.append( LogicalFilter( ComparisonExpression(ExpressionType.COMPARE_GREATER, TupleValueExpression('id'), ConstantValueExpression(3)))) left_plans.append(LogicalGet(TableRef(TableInfo('video')), m)) def reverse_plan(plans): return_plan = None for plan in reversed(plans): if return_plan: plan.append_child(return_plan) return_plan = plan return return_plan expect_left_plan = reverse_plan(left_plans) right_plans = [LogicalProject([TupleValueExpression('id')])] right_plans.append( LogicalFilter( ComparisonExpression(ExpressionType.COMPARE_LEQ, TupleValueExpression('id'), ConstantValueExpression(3)))) right_plans.append(LogicalGet(TableRef(TableInfo('video')), m)) expect_right_plan = reverse_plan(right_plans) expected_plan = LogicalUnion(True) expected_plan.append_child(expect_right_plan) expected_plan.append_child(expect_left_plan) self.assertEqual(expected_plan, actual_plan)
def test_should_return_false_for_unequal_expressions(self): const_exp1 = ConstantValueExpression(0) const_exp2 = ConstantValueExpression(1) func_expr = FunctionExpression(lambda x: x + 1) cmpr_exp = ComparisonExpression(ExpressionType.COMPARE_NEQ, const_exp1, const_exp2) tuple_expr = TupleValueExpression(col_name='id') aggr_expr = AggregationExpression(ExpressionType.AGGREGATION_MAX, None, tuple_expr) logical_expr = LogicalExpression(ExpressionType.LOGICAL_OR, cmpr_exp, cmpr_exp) self.assertNotEqual(const_exp1, const_exp2) self.assertNotEqual(cmpr_exp, const_exp1) self.assertNotEqual(func_expr, cmpr_exp) self.assertNotEqual(tuple_expr, aggr_expr) self.assertNotEqual(aggr_expr, tuple_expr) self.assertNotEqual(tuple_expr, cmpr_exp) self.assertNotEqual(logical_expr, cmpr_exp)
def test_comparison_compare_geq(self): const_exp1 = ConstantValueExpression(1) const_exp2 = ConstantValueExpression(1) const_exp3 = ConstantValueExpression(0) cmpr_exp1 = ComparisonExpression(ExpressionType.COMPARE_GEQ, const_exp1, const_exp2) cmpr_exp2 = ComparisonExpression(ExpressionType.COMPARE_GEQ, const_exp1, const_exp3) # checking equal self.assertEqual([True], cmpr_exp1.evaluate(None).frames[0].tolist()) # checking greater equal self.assertEqual([True], cmpr_exp2.evaluate(None).frames[0].tolist())
def test_comparison_compare_contains(self): const_exp1 = ConstantValueExpression([1, 2], ColumnType.NDARRAY) const_exp2 = ConstantValueExpression([1, 5], ColumnType.NDARRAY) const_exp3 = ConstantValueExpression([1, 2, 3, 4], ColumnType.NDARRAY) cmpr_exp1 = ComparisonExpression(ExpressionType.COMPARE_CONTAINS, const_exp3, const_exp1) self.assertEqual([True], cmpr_exp1.evaluate(None).frames[0].tolist()) cmpr_exp2 = ComparisonExpression(ExpressionType.COMPARE_CONTAINS, const_exp3, const_exp2) self.assertEqual([False], cmpr_exp2.evaluate(None).frames[0].tolist())
def test_visit_select_orderby(self, mock_p, mock_c, mock_d): m = MagicMock() mock_p.return_value = mock_c.return_value = mock_d.return_value = m stmt = Parser().parse(""" SELECT data, id FROM video \ WHERE data > 2 ORDER BY data, id DESC;""")[0] converter = StatementToPlanConvertor() actual_plan = converter.visit(stmt) plans = [] plans.append( LogicalOrderBy([ (TupleValueExpression('data'), ParserOrderBySortType.ASC), (TupleValueExpression('id'), ParserOrderBySortType.DESC) ])) plans.append( LogicalProject( [TupleValueExpression('data'), TupleValueExpression('id')])) plans.append( LogicalFilter( ComparisonExpression(ExpressionType.COMPARE_GREATER, TupleValueExpression('data'), ConstantValueExpression(2)))) plans.append(LogicalGet(TableRef(TableInfo('video')), m)) expected_plan = None for plan in reversed(plans): if expected_plan: plan.append_child(expected_plan) expected_plan = plan self.assertEqual(expected_plan, actual_plan) wrong_plan = plans[0] for plan in plans[1:]: wrong_plan.append_child(plan) self.assertNotEqual(wrong_plan, actual_plan)
def test_visit_select_sample(self, mock_p, mock_c, mock_d): m = MagicMock() mock_p.return_value = mock_c.return_value = mock_d.return_value = m stmt = Parser().parse(""" SELECT data, id FROM video SAMPLE 2 \ WHERE id > 2 LIMIT 3;""")[0] converter = StatementToPlanConvertor() actual_plan = converter.visit(stmt) plans = [] plans.append(LogicalLimit(ConstantValueExpression(3))) plans.append( LogicalProject( [TupleValueExpression('data'), TupleValueExpression('id')])) plans.append( LogicalFilter( ComparisonExpression(ExpressionType.COMPARE_GREATER, TupleValueExpression('id'), ConstantValueExpression(2)))) plans.append(LogicalSample(ConstantValueExpression(2))) plans.append( LogicalGet( TableRef(TableInfo('video'), ConstantValueExpression(2)), m)) expected_plan = None for plan in reversed(plans): if expected_plan: plan.append_child(expected_plan) expected_plan = plan self.assertEqual(expected_plan, actual_plan)
def test_comparison_compare_leq(self): const_exp1 = ConstantValueExpression(0) const_exp2 = ConstantValueExpression(2) const_exp3 = ConstantValueExpression(2) cmpr_exp1 = ComparisonExpression( ExpressionType.COMPARE_LEQ, const_exp1, const_exp2 ) cmpr_exp2 = ComparisonExpression( ExpressionType.COMPARE_LEQ, const_exp2, const_exp3 ) # checking lesser self.assertEqual([True], cmpr_exp1.evaluate(None)) # checking equal self.assertEqual([True], cmpr_exp2.evaluate(None))
def visitBinaryComparasionPredicate( self, ctx: evaql_parser.BinaryComparisonPredicateContext): left = self.visit(ctx.left) right = self.visit(ctx.right) op = self.visit(ctx.comparisonOperator()) return ComparisonExpression(op, left, right)