1#include "catch.hpp"
2#include "duckdb/common/helper.hpp"
3#include "duckdb/planner/expression/bound_operator_expression.hpp"
4#include "duckdb/optimizer/rule/empty_needle_removal.hpp"
5#include "duckdb/optimizer/rule/constant_folding.hpp"
6#include "duckdb/execution/expression_executor.hpp"
7#include "expression_helper.hpp"
8
9using namespace duckdb;
10using namespace std;
11
12static void require_case(ExpressionHelper &helper, string input) {
13 auto root = helper.ParseExpression(input);
14 auto result = helper.ApplyExpressionRule(move(root));
15 REQUIRE(result->type == ExpressionType::CASE_EXPR);
16}
17
18static void require_constant(ExpressionHelper &helper, string input, Value constant) {
19 auto root = helper.ParseExpression(input);
20 auto result = helper.ApplyExpressionRule(move(root));
21 REQUIRE(result->IsFoldable());
22 auto result_value = ExpressionExecutor::EvaluateScalar(*result);
23 REQUIRE(((constant.is_null && result_value.is_null) || constant == result_value));
24}
25
26TEST_CASE("Test Empty Needle Optimization Rules", "[needle-optimizer]") {
27 ExpressionHelper helper;
28
29 REQUIRE(helper.AddColumns("S VARCHAR").empty());
30
31 helper.AddRule<EmptyNeedleRemovalRule>();
32 helper.AddRule<ConstantFoldingRule>();
33
34 string input, expected_output;
35
36 require_case(helper, "PREFIX(S, '')");
37 require_case(helper, "CONTAINS(S, '')");
38 require_case(helper, "SUFFIX(S, '')");
39
40 require_constant(helper, "PREFIX(S, NULL)", Value());
41 require_constant(helper, "PREFIX('', NULL)", Value());
42 require_constant(helper, "PREFIX(NULL, NULL)", Value());
43 require_constant(helper, "PREFIX(NULL, '')", Value());
44
45 require_constant(helper, "PREFIX('asdf', '')", Value::BOOLEAN(true));
46 require_constant(helper, "PREFIX('', '')", Value::BOOLEAN(true));
47
48 require_constant(helper, "CONTAINS(S, NULL)", Value());
49 require_constant(helper, "CONTAINS('', NULL)", Value());
50 require_constant(helper, "CONTAINS(NULL, NULL)", Value());
51 require_constant(helper, "CONTAINS(NULL, '')", Value());
52
53 require_constant(helper, "CONTAINS('asdf', '')", Value::BOOLEAN(true));
54 require_constant(helper, "CONTAINS('', '')", Value::BOOLEAN(true));
55
56 require_constant(helper, "SUFFIX(S, NULL)", Value());
57 require_constant(helper, "SUFFIX('', NULL)", Value());
58 require_constant(helper, "SUFFIX(NULL, NULL)", Value());
59 require_constant(helper, "SUFFIX(NULL, '')", Value());
60
61 require_constant(helper, "SUFFIX('asdf', '')", Value::BOOLEAN(true));
62 require_constant(helper, "SUFFIX('', '')", Value::BOOLEAN(true));
63
64 // REQUIRE_FAIL ----------------
65 input = "PREFIX(S, ' ')";
66 REQUIRE(helper.VerifyRewrite(input, input));
67
68 input = "PREFIX(S, 'a')";
69 REQUIRE(helper.VerifyRewrite(input, input));
70
71 input = "CONTAINS(S, ' ')";
72 REQUIRE(helper.VerifyRewrite(input, input));
73
74 input = "CONTAINS(S, 'a')";
75 REQUIRE(helper.VerifyRewrite(input, input));
76
77 input = "SUFFIX(S, ' ')";
78 REQUIRE(helper.VerifyRewrite(input, input));
79
80 input = "SUFFIX(S, 'a')";
81 REQUIRE(helper.VerifyRewrite(input, input));
82}
83