Skip to content

Commit

Permalink
Add between operator for strings (#207)
Browse files Browse the repository at this point in the history
Summary: Pull Request resolved: #207

Reviewed By: kgpai

Differential Revision: D30933071

Pulled By: mbasmanova

fbshipit-source-id: 06b17a7098f5a11ec6b2154650bf58aada5b91e3
  • Loading branch information
mbasmanova authored and facebook-github-bot committed Sep 14, 2021
1 parent 6d9ca6c commit 577708c
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 14 deletions.
13 changes: 4 additions & 9 deletions velox/duckdb/conversion/DuckParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,15 +156,10 @@ std::shared_ptr<const core::IExpr> parseComparisonExpr(ParsedExpression& expr) {
std::shared_ptr<const core::IExpr> parseBetweenExpr(ParsedExpression& expr) {
const auto& betweenExpr = dynamic_cast<BetweenExpression&>(expr);
return callExpr(
"and",
{
callExpr(
"gte",
{parseExpr(*betweenExpr.input), parseExpr(*betweenExpr.lower)}),
callExpr(
"lte",
{parseExpr(*betweenExpr.input), parseExpr(*betweenExpr.upper)}),
});
"between",
{parseExpr(*betweenExpr.input),
parseExpr(*betweenExpr.lower),
parseExpr(*betweenExpr.upper)});
}

// Parse a conjunction (AND or OR).
Expand Down
6 changes: 2 additions & 4 deletions velox/duckdb/conversion/tests/DuckParserTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,10 @@ TEST(DuckParserTest, expressions) {
}

TEST(DuckParserTest, between) {
EXPECT_EQ(
"and(gte(\"c0\",0),lte(\"c0\",1))",
parseExpr("c0 between 0 and 1")->toString());
EXPECT_EQ("between(\"c0\",0,1)", parseExpr("c0 between 0 and 1")->toString());

EXPECT_EQ(
"and(and(gte(\"c0\",0),lte(\"c0\",1)),gt(\"c0\",10))",
"and(between(\"c0\",0,1),gt(\"c0\",10))",
parseExpr("c0 between 0 and 1 and c0 > 10")->toString());
}

Expand Down
4 changes: 3 additions & 1 deletion velox/expression/ExprCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,9 @@ ExprPtr compileExpression(
result = std::make_shared<Expr>(
resultType, std::move(compiledInputs), func, call->name());
} else {
VELOX_FAIL("Function not registered: {}", call->name());
VELOX_FAIL(
"Function not registered: {}",
core::FunctionKey(call->name(), inputTypes).toString());
}
} else if (
auto access =
Expand Down
1 change: 1 addition & 0 deletions velox/functions/prestosql/RegisterComparisons.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ void registerComparisonFunctions() {
registerFunction<udf_between<int64_t>, bool, int64_t, int64_t, int64_t>();
registerFunction<udf_between<double>, bool, double, double, double>();
registerFunction<udf_between<float>, bool, float, float, float>();
registerFunction<udf_between<StringView>, bool, Varchar, Varchar, Varchar>();
}

} // namespace facebook::velox::functions
21 changes: 21 additions & 0 deletions velox/functions/prestosql/tests/ComparisonsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,24 @@ TEST_F(ComparisonsTest, between) {
EXPECT_EQ(result->valueAt(i), std::get<1>(testData[i])) << "at " << i;
}
}

TEST_F(ComparisonsTest, betweenVarchar) {
using S = StringView;

const auto between = [&](std::optional<std::string> s) {
auto expr = "c0 between 'mango' and 'pear'";
if (s.has_value()) {
return evaluateOnce<bool>(expr, std::optional(S(s.value())));
} else {
return evaluateOnce<bool>(expr, std::optional<S>());
}
};

EXPECT_EQ(std::nullopt, between(std::nullopt));
EXPECT_EQ(false, between(""));
EXPECT_EQ(false, between("apple"));
EXPECT_EQ(false, between("pineapple"));
EXPECT_EQ(true, between("mango"));
EXPECT_EQ(true, between("orange"));
EXPECT_EQ(true, between("pear"));
}

0 comments on commit 577708c

Please sign in to comment.