Skip to content

Commit

Permalink
Extract reusable functions for SQL generation in fuzzer test (faceboo…
Browse files Browse the repository at this point in the history
…kincubator#10545)

Summary:
Extracts appendComma, toCallInputsSql, toCallSql, toAggregateCallSql functions
for reuse.

Pull Request resolved: facebookincubator#10545

Reviewed By: kevinwilfong

Differential Revision: D60176391

Pulled By: Yuhta

fbshipit-source-id: 4690bd21038f2a3244a5979d5cb59d9c291a17ad
  • Loading branch information
rui-mo authored and facebook-github-bot committed Jul 24, 2024
1 parent ed9e5b6 commit 40122c6
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 131 deletions.
2 changes: 1 addition & 1 deletion velox/exec/fuzzer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# limitations under the License.

add_library(velox_fuzzer_util DuckQueryRunner.cpp PrestoQueryRunner.cpp
FuzzerUtil.cpp)
FuzzerUtil.cpp ToSQLUtil.cpp)

target_link_libraries(
velox_fuzzer_util
Expand Down
51 changes: 1 addition & 50 deletions velox/exec/fuzzer/DuckQueryRunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,62 +14,13 @@
* limitations under the License.
*/
#include "velox/exec/fuzzer/DuckQueryRunner.h"
#include "velox/exec/fuzzer/ToSQLUtil.h"
#include "velox/exec/tests/utils/QueryAssertions.h"

namespace facebook::velox::exec::test {

namespace {

void appendComma(int32_t i, std::stringstream& sql) {
if (i > 0) {
sql << ", ";
}
}

std::string toCallSql(const core::CallTypedExprPtr& call) {
std::stringstream sql;
sql << call->name() << "(";
for (auto i = 0; i < call->inputs().size(); ++i) {
appendComma(i, sql);
sql << std::dynamic_pointer_cast<const core::FieldAccessTypedExpr>(
call->inputs()[i])
->name();
}
sql << ")";
return sql.str();
}

std::string toAggregateCallSql(
const core::CallTypedExprPtr& call,
const std::vector<core::FieldAccessTypedExprPtr>& sortingKeys,
const std::vector<core::SortOrder>& sortingOrders,
bool distinct) {
std::stringstream sql;
sql << call->name() << "(";

if (distinct) {
sql << "distinct ";
}

for (auto i = 0; i < call->inputs().size(); ++i) {
appendComma(i, sql);
sql << std::dynamic_pointer_cast<const core::FieldAccessTypedExpr>(
call->inputs()[i])
->name();
}

if (!sortingKeys.empty()) {
sql << " order by ";
for (auto i = 0; i < sortingKeys.size(); ++i) {
appendComma(i, sql);
sql << sortingKeys[i]->name() << " " << sortingOrders[i].toString();
}
}

sql << ")";
return sql.str();
}

bool isSupported(const TypePtr& type) {
// DuckDB doesn't support nanosecond precision for timestamps.
if (type->kind() == TypeKind::TIMESTAMP) {
Expand Down
81 changes: 1 addition & 80 deletions velox/exec/fuzzer/PrestoQueryRunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "velox/connectors/hive/TableHandle.h"
#include "velox/core/Expressions.h"
#include "velox/dwio/common/WriterFactory.h"
#include "velox/exec/fuzzer/ToSQLUtil.h"
#include "velox/exec/tests/utils/QueryAssertions.h"
#include "velox/serializers/PrestoSerializer.h"
#include "velox/type/parser/TypeParser.h"
Expand Down Expand Up @@ -213,12 +214,6 @@ std::optional<std::string> PrestoQueryRunner::toSql(

namespace {

void appendComma(int32_t i, std::stringstream& sql) {
if (i > 0) {
sql << ", ";
}
}

std::string toTypeSql(const TypePtr& type) {
switch (type->kind()) {
case TypeKind::ARRAY:
Expand Down Expand Up @@ -248,80 +243,6 @@ std::string toTypeSql(const TypePtr& type) {
}
}

std::string toCallSql(const core::CallTypedExprPtr& call);

void toCallInputsSql(
const std::vector<core::TypedExprPtr>& inputs,
std::stringstream& sql) {
for (auto i = 0; i < inputs.size(); ++i) {
appendComma(i, sql);

const auto& input = inputs.at(i);
if (auto field =
std::dynamic_pointer_cast<const core::FieldAccessTypedExpr>(
input)) {
sql << field->name();
} else if (
auto call =
std::dynamic_pointer_cast<const core::CallTypedExpr>(input)) {
sql << toCallSql(call);
} else if (
auto lambda =
std::dynamic_pointer_cast<const core::LambdaTypedExpr>(input)) {
const auto& signature = lambda->signature();
const auto& body =
std::dynamic_pointer_cast<const core::CallTypedExpr>(lambda->body());
VELOX_CHECK_NOT_NULL(body);

sql << "(";
for (auto j = 0; j < signature->size(); ++j) {
appendComma(j, sql);
sql << signature->nameOf(j);
}

sql << ") -> " << toCallSql(body);
} else {
VELOX_NYI();
}
}
}

std::string toCallSql(const core::CallTypedExprPtr& call) {
std::stringstream sql;
sql << call->name() << "(";
toCallInputsSql(call->inputs(), sql);
sql << ")";
return sql.str();
}

std::string toAggregateCallSql(
const core::CallTypedExprPtr& call,
const std::vector<core::FieldAccessTypedExprPtr>& sortingKeys,
const std::vector<core::SortOrder>& sortingOrders,
bool distinct) {
VELOX_CHECK_EQ(sortingKeys.size(), sortingOrders.size());
std::stringstream sql;
sql << call->name() << "(";

if (distinct) {
sql << "distinct ";
}

toCallInputsSql(call->inputs(), sql);

if (!sortingKeys.empty()) {
sql << " ORDER BY ";

for (int i = 0; i < sortingKeys.size(); i++) {
appendComma(i, sql);
sql << sortingKeys[i]->name() << " " << sortingOrders[i].toString();
}
}

sql << ")";
return sql.str();
}

std::string toWindowCallSql(
const core::CallTypedExprPtr& call,
bool ignoreNulls = false) {
Expand Down
99 changes: 99 additions & 0 deletions velox/exec/fuzzer/ToSQLUtil.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "velox/exec/fuzzer/ToSQLUtil.h"

namespace facebook::velox::exec::test {

void appendComma(int32_t i, std::stringstream& sql) {
if (i > 0) {
sql << ", ";
}
}

void toCallInputsSql(
const std::vector<core::TypedExprPtr>& inputs,
std::stringstream& sql) {
for (auto i = 0; i < inputs.size(); ++i) {
appendComma(i, sql);

const auto& input = inputs.at(i);
if (auto field =
std::dynamic_pointer_cast<const core::FieldAccessTypedExpr>(
input)) {
sql << field->name();
} else if (
auto call =
std::dynamic_pointer_cast<const core::CallTypedExpr>(input)) {
sql << toCallSql(call);
} else if (
auto lambda =
std::dynamic_pointer_cast<const core::LambdaTypedExpr>(input)) {
const auto& signature = lambda->signature();
const auto& body =
std::dynamic_pointer_cast<const core::CallTypedExpr>(lambda->body());
VELOX_CHECK_NOT_NULL(body);

sql << "(";
for (auto j = 0; j < signature->size(); ++j) {
appendComma(j, sql);
sql << signature->nameOf(j);
}

sql << ") -> " << toCallSql(body);
} else {
VELOX_NYI("Unsupported input expression: {}.", input->toString());
}
}
}

std::string toCallSql(const core::CallTypedExprPtr& call) {
std::stringstream sql;
sql << call->name() << "(";
toCallInputsSql(call->inputs(), sql);
sql << ")";
return sql.str();
}

std::string toAggregateCallSql(
const core::CallTypedExprPtr& call,
const std::vector<core::FieldAccessTypedExprPtr>& sortingKeys,
const std::vector<core::SortOrder>& sortingOrders,
bool distinct) {
VELOX_CHECK_EQ(sortingKeys.size(), sortingOrders.size());
std::stringstream sql;
sql << call->name() << "(";

if (distinct) {
sql << "distinct ";
}

toCallInputsSql(call->inputs(), sql);

if (!sortingKeys.empty()) {
sql << " ORDER BY ";

for (int i = 0; i < sortingKeys.size(); i++) {
appendComma(i, sql);
sql << sortingKeys[i]->name() << " " << sortingOrders[i].toString();
}
}

sql << ")";
return sql.str();
}

} // namespace facebook::velox::exec::test
42 changes: 42 additions & 0 deletions velox/exec/fuzzer/ToSQLUtil.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once

#include "velox/core/PlanNode.h"

namespace facebook::velox::exec::test {

/// Appends a comma to a given stringstream if the provided integer is greater
/// than 0.
void appendComma(int32_t i, std::stringstream& sql);

// Converts input expressions into SQL string and appends to a given
// stringstream.
void toCallInputsSql(
const std::vector<core::TypedExprPtr>& inputs,
std::stringstream& sql);

// Converts a call expression into a SQL string.
std::string toCallSql(const core::CallTypedExprPtr& call);

// Converts aggregate call expression into a SQL string.
std::string toAggregateCallSql(
const core::CallTypedExprPtr& call,
const std::vector<core::FieldAccessTypedExprPtr>& sortingKeys,
const std::vector<core::SortOrder>& sortingOrders,
bool distinct);

} // namespace facebook::velox::exec::test

0 comments on commit 40122c6

Please sign in to comment.