Skip to content

Commit

Permalink
Respect orderable constraint in ArgumentTypeFuzzer
Browse files Browse the repository at this point in the history
  • Loading branch information
duanmeng committed Oct 12, 2023
1 parent 26142de commit 59b6675
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 1 deletion.
10 changes: 9 additions & 1 deletion velox/expression/tests/ArgumentTypeFuzzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,22 @@ void ArgumentTypeFuzzer::determineUnboundedTypeVariables() {
// Random randomType() never generates unknown here.
// TODO: we should extend randomType types and exclude unknown based
// on variableInfo.
bindings_[variableName] = randType();
if (variableInfo.orderableTypesOnly()) {
bindings_[variableName] = randOrderableType();
} else {
bindings_[variableName] = randType();
}
}
}

TypePtr ArgumentTypeFuzzer::randType() {
return velox::randType(rng_, 2);
}

TypePtr ArgumentTypeFuzzer::randOrderableType() {
return velox::randOrderableType(rng_, 2);
}

bool ArgumentTypeFuzzer::fuzzArgumentTypes(uint32_t maxVariadicArgs) {
const auto& formalArgs = signature_.argumentTypes();
auto formalArgsCnt = formalArgs.size();
Expand Down
3 changes: 3 additions & 0 deletions velox/expression/tests/ArgumentTypeFuzzer.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ class ArgumentTypeFuzzer {

TypePtr randType();

/// Generates an orderable random type, including structs, and arrays.
TypePtr randOrderableType();

const exec::FunctionSignature& signature_;

TypePtr returnType_;
Expand Down
75 changes: 75 additions & 0 deletions velox/expression/tests/ArgumentTypeFuzzerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,4 +326,79 @@ TEST_F(ArgumentTypeFuzzerTest, unconstrainedSignatureTemplate) {
ASSERT_EQ(argumentTypes[0]->childAt(0), argumentTypes[1]);
}

TEST_F(ArgumentTypeFuzzerTest, orderableConstraint) {
{
for (int i = 0; i < 100; ++i) {
auto signature = exec::FunctionSignatureBuilder()
.orderableTypeVariable("T")
.returnType("bigint")
.argumentType("T")
.build();
std::mt19937 seed{123456};
ArgumentTypeFuzzer fuzzer{*signature, nullptr, seed};
fuzzer.fuzzArgumentTypes(kMaxVariadicArgs);
ASSERT_TRUE(fuzzer.argumentTypes()[0]->isOrderable());
}
}

{
auto signature = exec::FunctionSignatureBuilder()
.orderableTypeVariable("T")
.returnType("T")
.argumentType("T")
.build();
testFuzzingFailure(signature, MAP(VARCHAR(), BIGINT()));
testFuzzingFailure(signature, ARRAY(MAP(VARCHAR(), BIGINT())));
}

{
auto signature = exec::FunctionSignatureBuilder()
.orderableTypeVariable("T")
.returnType("array(T)")
.argumentType("array(T)")
.build();

testFuzzingSuccess(signature, ARRAY(DOUBLE()), {ARRAY(DOUBLE())});
testFuzzingSuccess(
signature, ARRAY(ROW({DOUBLE()})), {ARRAY(ROW({DOUBLE()}))});
testFuzzingFailure(signature, MAP(VARCHAR(), BIGINT()));
}

{
auto signature = exec::FunctionSignatureBuilder()
.typeVariable("T")
.orderableTypeVariable("U")
.returnType("row(T, U)")
.argumentType("T")
.argumentType("row(T,U)")
.build();

testFuzzingSuccess(
signature,
ROW({MAP(BIGINT(), BIGINT()), BIGINT()}),
{MAP(BIGINT(), BIGINT()), ROW({MAP(BIGINT(), BIGINT()), BIGINT()})});

testFuzzingFailure(signature, ROW({BIGINT(), MAP(VARCHAR(), BIGINT())}));
}

{
auto signature = exec::FunctionSignatureBuilder()
.typeVariable("T")
.orderableTypeVariable("U")
.returnType("row(T,U)")
.argumentType("T")
.argumentType("function(T,U)")
.build();

testFuzzingSuccess(
signature,
ROW({MAP(BIGINT(), BIGINT()), BIGINT()}),
{MAP(BIGINT(), BIGINT()),
std::make_shared<FunctionType>(
std::vector<TypePtr>{MAP(BIGINT(), BIGINT())}, BIGINT())});

testFuzzingFailure(signature, ROW({BIGINT(), MAP(VARCHAR(), BIGINT())}));
}
}

} // namespace facebook::velox::test

0 comments on commit 59b6675

Please sign in to comment.