Skip to content

Commit

Permalink
add extract (#4098)
Browse files Browse the repository at this point in the history
* add extract

* format

* fix typesignature

* add a test case with no-ascii string

* add test case in tck

* fix clang compile error

Co-authored-by: Sophie <84560950+Sophie-Xie@users.noreply.github.com>
Co-authored-by: Yee <2520865+yixinglu@users.noreply.github.com>

confirm with Yee
  • Loading branch information
wuxiaobai24 committed Apr 11, 2022
1 parent 0fbe9f5 commit 63d162c
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/common/function/FunctionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ std::unordered_map<std::string, std::vector<TypeSignature>> FunctionManager::typ
{"duration",
{TypeSignature({Value::Type::STRING}, Value::Type::DURATION),
TypeSignature({Value::Type::MAP}, Value::Type::DURATION)}},
{"extract", {TypeSignature({Value::Type::STRING, Value::Type::STRING}, Value::Type::LIST)}},
};

// static
Expand Down Expand Up @@ -2705,6 +2706,25 @@ FunctionManager::FunctionManager() {
}
};
}
{
auto &attr = functions_["extract"];
attr.minArity_ = 2;
attr.maxArity_ = 2;
attr.isPure_ = true;
attr.body_ = [](const auto &args) -> Value {
if (!args[0].get().isStr() || !args[1].get().isStr()) {
return Value::kNullBadType;
}

const auto &s = args[0].get().getStr();
std::regex rgx(args[1].get().getStr());
List res;
for (std::sregex_iterator beg(s.begin(), s.end(), rgx), end{}; beg != end; ++beg) {
res.emplace_back(beg->str());
}
return res;
};
}
} // NOLINT

// static
Expand Down
13 changes: 13 additions & 0 deletions src/common/function/test/FunctionManagerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,19 @@ TEST_F(FunctionManagerTest, functionCall) {
std::vector<Value>({".", 1, true, Value::kNullValue, "world", time}),
"1.true.world.09:39:21.000012000");
}
{
TEST_FUNCTION(extract,
std::vector<Value>({"Hello Nebula Graph", "\\w+"}),
List({"Hello", "Nebula", "Graph"}));
TEST_FUNCTION(extract,
std::vector<Value>({"你好,Nebula 图数据库", "(图|数据库|测试|Nebula)"}),
List({"Nebula", "", "数据库"}));
TEST_FUNCTION(extract,
std::vector<Value>({"Hello Nebula Graph", "(Nebula|Graph)"}),
List({"Nebula", "Graph"}));
TEST_FUNCTION(extract, std::vector<Value>({"Hello Nebula Graph", "testing"}), List());
TEST_FUNCTION(extract, std::vector<Value>({"Hello 2022 year", "\\d+"}), List({"2022"}));
}
{
TEST_FUNCTION(toBoolean, args_["int"], Value::kNullBadType);
TEST_FUNCTION(toBoolean, args_["float"], Value::kNullBadType);
Expand Down
20 changes: 20 additions & 0 deletions tests/tck/features/expression/FunctionCall.feature
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,26 @@ Feature: Function Call Expression
| result |
| NULL |

Scenario: extract
When executing query:
"""
MATCH (a:player)-[b:serve]-(c:team{name: "Lakers"})
WHERE a.player.age > 45
RETURN extract(a.player.name, "\\w+") as result
"""
Then the result should be, in any order:
| result |
| ["Shaquille", "O", "Neal"] |
When executing query:
"""
MATCH (a:player)-[b:serve]-(c:team{name: "Lakers"})
WHERE a.player.age > 45
RETURN extract(a.player.name, "hello") as result
"""
Then the result should be, in any order:
| result |
| [] |

Scenario: round
When executing query:
"""
Expand Down

0 comments on commit 63d162c

Please sign in to comment.