| 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 |  | 
|---|
| 9 | using namespace duckdb; | 
|---|
| 10 | using namespace std; | 
|---|
| 11 |  | 
|---|
| 12 | static 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 |  | 
|---|
| 18 | static 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 |  | 
|---|
| 26 | TEST_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 |  | 
|---|