Coverage Report

Created: 2025-08-28 07:58

/src/duckdb/src/optimizer/rule/constant_folding.cpp
Line
Count
Source
1
2
#include "duckdb/optimizer/rule/constant_folding.hpp"
3
4
#include "duckdb/common/exception.hpp"
5
#include "duckdb/execution/expression_executor.hpp"
6
#include "duckdb/optimizer/expression_rewriter.hpp"
7
#include "duckdb/planner/expression/bound_constant_expression.hpp"
8
9
namespace duckdb {
10
11
//! The ConstantFoldingExpressionMatcher matches on any scalar expression (i.e. Expression::IsFoldable is true)
12
class ConstantFoldingExpressionMatcher : public FoldableConstantMatcher {
13
public:
14
2.05M
  bool Match(Expression &expr, vector<reference<Expression>> &bindings) override {
15
    // we also do not match on ConstantExpressions, because we cannot fold those any further
16
2.05M
    if (expr.GetExpressionType() == ExpressionType::VALUE_CONSTANT) {
17
370k
      return false;
18
370k
    }
19
1.68M
    return FoldableConstantMatcher::Match(expr, bindings);
20
2.05M
  }
21
};
22
23
64.7k
ConstantFoldingRule::ConstantFoldingRule(ExpressionRewriter &rewriter) : Rule(rewriter) {
24
64.7k
  auto op = make_uniq<ConstantFoldingExpressionMatcher>();
25
64.7k
  root = std::move(op);
26
64.7k
}
27
28
unique_ptr<Expression> ConstantFoldingRule::Apply(LogicalOperator &op, vector<reference<Expression>> &bindings,
29
110k
                                                  bool &changes_made, bool is_root) {
30
110k
  auto &root = bindings[0].get();
31
  // the root is a scalar expression that we have to fold
32
110k
  D_ASSERT(root.IsFoldable() && root.GetExpressionType() != ExpressionType::VALUE_CONSTANT);
33
34
  // use an ExpressionExecutor to execute the expression
35
110k
  Value result_value;
36
110k
  if (!ExpressionExecutor::TryEvaluateScalar(GetContext(), root, result_value)) {
37
31.8k
    return nullptr;
38
31.8k
  }
39
78.4k
  D_ASSERT(result_value.type().InternalType() == root.return_type.InternalType());
40
  // now get the value from the result vector and insert it back into the plan as a constant expression
41
78.4k
  return make_uniq<BoundConstantExpression>(result_value);
42
110k
}
43
44
} // namespace duckdb