diff --git a/src/visitor/FoldConstantExprVisitor.cpp b/src/visitor/FoldConstantExprVisitor.cpp index 6d3e036ccb673a67df17442b5c19e9bed033b234..7fafff0498f383742b96c73479e181abd21084c8 100644 --- a/src/visitor/FoldConstantExprVisitor.cpp +++ b/src/visitor/FoldConstantExprVisitor.cpp @@ -4,6 +4,8 @@ * attached with Common Clause Condition 1.0, found in the LICENSES directory. */ +#include "common/function/FunctionManager.h" + #include "visitor/FoldConstantExprVisitor.h" #include "context/QueryExpressionContext.h" @@ -75,6 +77,14 @@ void FoldConstantExprVisitor::visit(FunctionCallExpression *expr) { } } } + auto result = FunctionManager::getIsPure(*expr->name(), expr->args()->args().size()); + if (!result.ok()) { + canBeFolded = false; + } + if (!result.value()) { + // stateful so can't fold + canBeFolded = false; + } canBeFolded_ = canBeFolded; } diff --git a/src/visitor/test/FoldConstantExprVisitorTest.cpp b/src/visitor/test/FoldConstantExprVisitorTest.cpp index e59badf642024fc5989b8dc70aff26a449ad6d81..f35131dc5974a3ae847fd36b19648dd94134e537 100644 --- a/src/visitor/test/FoldConstantExprVisitorTest.cpp +++ b/src/visitor/test/FoldConstantExprVisitorTest.cpp @@ -215,6 +215,29 @@ TEST_F(FoldConstantExprVisitorTest, TestMapExpr) { ASSERT(visitor.canBeFolded()); } +TEST_F(FoldConstantExprVisitorTest, TestFoldFunction) { + // pure function + // abs(-1) + 1 => 1 + 1 + { + auto expr = pool.add(addExpr(fnExpr("abs", {constantExpr(-1)}), constantExpr(1))); + auto expected = pool.add(addExpr(constantExpr(1), constantExpr(1))); + FoldConstantExprVisitor visitor; + expr->accept(&visitor); + ASSERT_TRUE(visitor.canBeFolded()); + ASSERT_EQ(*expr, *expected) << expr->toString() << " vs. " << expected->toString(); + } + // not pure function + // rand32(4) + 1 => rand32(4) + 1 + { + auto expr = pool.add(addExpr(fnExpr("rand32", {constantExpr(4)}), constantExpr(1))); + auto expected = pool.add(addExpr(fnExpr("rand32", {constantExpr(4)}), constantExpr(1))); + FoldConstantExprVisitor visitor; + expr->accept(&visitor); + ASSERT_FALSE(visitor.canBeFolded()); + ASSERT_EQ(*expr, *expected) << expr->toString() << " vs. " << expected->toString(); + } +} + TEST_F(FoldConstantExprVisitorTest, TestFoldFailed) { // function call {