Skip to content

Commit

Permalink
Fold constant for List/Set Expression
Browse files Browse the repository at this point in the history
fix ut

small comment

small delete

small change for ut

small fix
  • Loading branch information
czpmango committed Nov 17, 2022
1 parent cb3d8f2 commit 58b7843
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 2 deletions.
24 changes: 22 additions & 2 deletions src/graph/visitor/FoldConstantExprVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,27 @@ void FoldConstantExprVisitor::visit(ArithmeticExpression *expr) {

void FoldConstantExprVisitor::visit(RelationalExpression *expr) {
visitBinaryExpr(expr);
if (expr->kind() == Expression::Kind::kRelIn) {
auto rhs = static_cast<RelationalExpression *>(expr)->right();
if (rhs->kind() == Expression::Kind::kConstant) {
auto ce = static_cast<ConstantExpression *>(rhs);
auto v = ce->value();
// Convert to more efficient C++ data structure based on the size of the container expression
if (v.isList()) {
auto &list = v.getList().values;
if (list.size() >= 16) {
ce->setValue(Set(std::unordered_set<Value>{std::make_move_iterator(list.begin()),
std::make_move_iterator(list.end())}));
}
} else if (v.isSet()) {
auto &set = v.getSet().values;
if (set.size() < 16) {
ce->setValue(List(std::vector<Value>{std::make_move_iterator(set.begin()),
std::make_move_iterator(set.end())}));
}
}
}
}
}

void FoldConstantExprVisitor::visit(SubscriptExpression *expr) {
Expand Down Expand Up @@ -348,8 +369,7 @@ void FoldConstantExprVisitor::visitBinaryExpr(BinaryExpression *expr) {
}

Expression *FoldConstantExprVisitor::fold(Expression *expr) {
// Container expression should remain the same type after being folded
if (expr->isContainerExpr() || !status_.ok()) {
if (!status_.ok()) {
return expr;
}

Expand Down
54 changes: 54 additions & 0 deletions src/graph/visitor/test/FoldConstantExprVisitorTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,5 +215,59 @@ TEST_F(FoldConstantExprVisitorTest, TestPathBuild) {
expected->add(ConstantExpression::make(pool, "TOM"));
ASSERT_EQ(*expr, *expected);
}

TEST_F(FoldConstantExprVisitorTest, TestRelIn) {
auto items = ExpressionList::make(pool);
items->add(ArithmeticExpression::makeAdd(
pool, ConstantExpression::make(pool, 1), ConstantExpression::make(pool, 2)));
items->add(ConstantExpression::make(pool, 4));
items->add(ConstantExpression::make(pool, false));
items->add(ConstantExpression::make(pool, "3"));
items->add(ConstantExpression::make(pool, 5));
items->add(ConstantExpression::make(pool, 3));
auto lhs = ConstantExpression::make(pool, 3);
auto listExpr = ListExpression::make(pool, items);
auto inListExpr = RelationalExpression::makeIn(pool, lhs, listExpr);
FoldConstantExprVisitor foldVisitor(pool);
inListExpr->accept(&foldVisitor);

auto expectInListExpr = RelationalExpression::makeIn(
pool, lhs, ConstantExpression::make(pool, List(std::vector<Value>{3, 4, false, "3", 5, 3})));
EXPECT_EQ(*inListExpr, *expectInListExpr);
auto setExpr = SetExpression::make(pool, items);
auto inSetExpr = RelationalExpression::makeIn(pool, lhs, setExpr);
inSetExpr->accept(&foldVisitor);
auto expectInSetExpr = RelationalExpression::makeIn(
pool, lhs, ConstantExpression::make(pool, List(std::vector<Value>{5, "3", false, 4, 3})));
EXPECT_EQ(*inSetExpr, *expectInSetExpr);

for (int i = 10u; i < 20; ++i) {
items->add(ConstantExpression::make(pool, i));
}

auto bigListExpr = ListExpression::make(pool, items);
auto inBigListExpr = RelationalExpression::makeIn(pool, lhs, bigListExpr);

inBigListExpr->accept(&foldVisitor);

auto expectInBigListExpr = RelationalExpression::makeIn(
pool,
lhs,
ConstantExpression::make(pool,
Set(std::unordered_set<Value>{
19, 18, 3, 16, 4, 17, false, 13, "3", 5, 10, 11, 12, 14, 15})));
EXPECT_EQ(*inBigListExpr, *expectInBigListExpr);
auto bigSetExpr = SetExpression::make(pool, items);
auto inBigSetExpr = RelationalExpression::makeIn(pool, lhs, bigSetExpr);
inBigSetExpr->accept(&foldVisitor);
auto expectInBigSetExpr = RelationalExpression::makeIn(
pool,
lhs,
ConstantExpression::make(
pool,
List(std::vector<Value>{19, 18, 16, 15, 14, 12, 11, 10, 5, 13, "3", 17, false, 4, 3})));
EXPECT_EQ(*inBigSetExpr, *expectInBigSetExpr);
}

} // namespace graph
} // namespace nebula

0 comments on commit 58b7843

Please sign in to comment.