Coverage Report

Created: 2026-03-31 07:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/duckdb/src/optimizer/rule/date_part_simplification.cpp
Line
Count
Source
1
#include "duckdb/optimizer/rule/date_part_simplification.hpp"
2
3
#include "duckdb/common/exception.hpp"
4
#include "duckdb/planner/expression/bound_constant_expression.hpp"
5
#include "duckdb/planner/expression/bound_function_expression.hpp"
6
#include "duckdb/optimizer/matcher/expression_matcher.hpp"
7
#include "duckdb/optimizer/expression_rewriter.hpp"
8
#include "duckdb/common/enums/date_part_specifier.hpp"
9
#include "duckdb/function/function.hpp"
10
#include "duckdb/function/function_binder.hpp"
11
12
namespace duckdb {
13
14
70.9k
DatePartSimplificationRule::DatePartSimplificationRule(ExpressionRewriter &rewriter) : Rule(rewriter) {
15
70.9k
  auto func = make_uniq<FunctionExpressionMatcher>();
16
70.9k
  func->function = make_uniq<SpecificFunctionMatcher>("date_part");
17
70.9k
  func->matchers.push_back(make_uniq<ConstantExpressionMatcher>());
18
70.9k
  func->matchers.push_back(make_uniq<ExpressionMatcher>());
19
70.9k
  func->policy = SetMatcher::Policy::ORDERED;
20
70.9k
  root = std::move(func);
21
70.9k
}
22
23
unique_ptr<Expression> DatePartSimplificationRule::Apply(LogicalOperator &op, vector<reference<Expression>> &bindings,
24
0
                                                         bool &changes_made, bool is_root) {
25
0
  auto &date_part = bindings[0].get().Cast<BoundFunctionExpression>();
26
0
  auto &constant_expr = bindings[1].get().Cast<BoundConstantExpression>();
27
0
  auto &constant = constant_expr.value;
28
29
0
  if (constant.IsNull()) {
30
    // NULL specifier: return constant NULL
31
0
    return make_uniq<BoundConstantExpression>(Value(date_part.return_type));
32
0
  }
33
  // otherwise check the specifier
34
0
  auto specifier = GetDatePartSpecifier(StringValue::Get(constant));
35
0
  string new_function_name;
36
0
  switch (specifier) {
37
0
  case DatePartSpecifier::YEAR:
38
0
    new_function_name = "year";
39
0
    break;
40
0
  case DatePartSpecifier::MONTH:
41
0
    new_function_name = "month";
42
0
    break;
43
0
  case DatePartSpecifier::DAY:
44
0
    new_function_name = "day";
45
0
    break;
46
0
  case DatePartSpecifier::DECADE:
47
0
    new_function_name = "decade";
48
0
    break;
49
0
  case DatePartSpecifier::CENTURY:
50
0
    new_function_name = "century";
51
0
    break;
52
0
  case DatePartSpecifier::MILLENNIUM:
53
0
    new_function_name = "millennium";
54
0
    break;
55
0
  case DatePartSpecifier::QUARTER:
56
0
    new_function_name = "quarter";
57
0
    break;
58
0
  case DatePartSpecifier::WEEK:
59
0
    new_function_name = "week";
60
0
    break;
61
0
  case DatePartSpecifier::YEARWEEK:
62
0
    new_function_name = "yearweek";
63
0
    break;
64
0
  case DatePartSpecifier::DOW:
65
0
    new_function_name = "dayofweek";
66
0
    break;
67
0
  case DatePartSpecifier::ISODOW:
68
0
    new_function_name = "isodow";
69
0
    break;
70
0
  case DatePartSpecifier::DOY:
71
0
    new_function_name = "dayofyear";
72
0
    break;
73
0
  case DatePartSpecifier::MICROSECONDS:
74
0
    new_function_name = "microsecond";
75
0
    break;
76
0
  case DatePartSpecifier::MILLISECONDS:
77
0
    new_function_name = "millisecond";
78
0
    break;
79
0
  case DatePartSpecifier::SECOND:
80
0
    new_function_name = "second";
81
0
    break;
82
0
  case DatePartSpecifier::MINUTE:
83
0
    new_function_name = "minute";
84
0
    break;
85
0
  case DatePartSpecifier::HOUR:
86
0
    new_function_name = "hour";
87
0
    break;
88
0
  default:
89
0
    return nullptr;
90
0
  }
91
  // found a replacement function: bind it
92
0
  vector<unique_ptr<Expression>> children;
93
0
  children.push_back(std::move(date_part.children[1]));
94
95
0
  ErrorData error;
96
0
  FunctionBinder binder(rewriter.context);
97
0
  auto function = binder.BindScalarFunction(DEFAULT_SCHEMA, new_function_name, std::move(children), error, false);
98
0
  if (!function) {
99
0
    error.Throw();
100
0
  }
101
0
  return function;
102
0
}
103
104
} // namespace duckdb