Skip to content

Commit

Permalink
[native] Add presto.default-namespace Prestissimo config property
Browse files Browse the repository at this point in the history
  • Loading branch information
pdabre12 authored and Pratik Joseph Dabre committed Dec 6, 2024
1 parent fc52b76 commit 046c021
Show file tree
Hide file tree
Showing 11 changed files with 188 additions and 32 deletions.
8 changes: 8 additions & 0 deletions presto-docs/src/main/sphinx/presto_cpp/properties.rst
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ alphabetical order.
This property provides function signatures for built-in aggregation
functions which are compatible with Velox.

``presto.default-namespace``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

* **Type:** ``string``
* **Default value:** ``presto.default``

Specifies the namespace prefix for native C++ functions.

Worker Properties
-----------------

Expand Down
10 changes: 6 additions & 4 deletions presto-native-execution/presto_cpp/main/PrestoServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ void PrestoServer::run() {
address_ = fmt::format("[{}]", address_);
}
nodeLocation_ = nodeConfig->nodeLocation();
prestoBuiltinFunctionPrefix_ = systemConfig->prestoDefaultNamespacePrefix();
} catch (const velox::VeloxUserError& e) {
PRESTO_STARTUP_LOG(ERROR) << "Failed to start server due to " << e.what();
exit(EXIT_FAILURE);
Expand Down Expand Up @@ -1244,11 +1245,12 @@ void PrestoServer::registerCustomOperators() {
}

void PrestoServer::registerFunctions() {
static const std::string kPrestoDefaultPrefix{"presto.default."};
velox::functions::prestosql::registerAllScalarFunctions(kPrestoDefaultPrefix);
velox::functions::prestosql::registerAllScalarFunctions(
prestoBuiltinFunctionPrefix_);
velox::aggregate::prestosql::registerAllAggregateFunctions(
kPrestoDefaultPrefix);
velox::window::prestosql::registerAllWindowFunctions(kPrestoDefaultPrefix);
prestoBuiltinFunctionPrefix_);
velox::window::prestosql::registerAllWindowFunctions(
prestoBuiltinFunctionPrefix_);
if (SystemConfig::instance()->registerTestFunctions()) {
velox::functions::prestosql::registerAllScalarFunctions(
"json.test_schema.");
Expand Down
1 change: 1 addition & 0 deletions presto-native-execution/presto_cpp/main/PrestoServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ class PrestoServer {
std::string address_;
std::string nodeLocation_;
folly::SSLContextPtr sslContext_;
std::string prestoBuiltinFunctionPrefix_;
};

} // namespace facebook::presto
5 changes: 5 additions & 0 deletions presto-native-execution/presto_cpp/main/common/Configs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ SystemConfig::SystemConfig() {
STR_PROP(kCacheVeloxTtlCheckInterval, "1h"),
BOOL_PROP(kEnableRuntimeMetricsCollection, false),
BOOL_PROP(kPlanValidatorFailOnNestedLoopJoin, false),
STR_PROP(kPrestoDefaultNamespacePrefix, "presto.default"),
};
}

Expand Down Expand Up @@ -753,6 +754,10 @@ bool SystemConfig::enableRuntimeMetricsCollection() const {
return optionalProperty<bool>(kEnableRuntimeMetricsCollection).value();
}

std::string SystemConfig::prestoDefaultNamespacePrefix() const {
return optionalProperty(kPrestoDefaultNamespacePrefix).value().append(".");
}

NodeConfig::NodeConfig() {
registeredProps_ =
std::unordered_map<std::string, folly::Optional<std::string>>{
Expand Down
5 changes: 5 additions & 0 deletions presto-native-execution/presto_cpp/main/common/Configs.h
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,10 @@ class SystemConfig : public ConfigBase {
static constexpr std::string_view kPlanValidatorFailOnNestedLoopJoin{
"velox-plan-validator-fail-on-nested-loop-join"};

// Specifies the default Presto namespace prefix.
static constexpr std::string_view kPrestoDefaultNamespacePrefix{
"presto.default-namespace"};

SystemConfig();

virtual ~SystemConfig() = default;
Expand Down Expand Up @@ -881,6 +885,7 @@ class SystemConfig : public ConfigBase {
bool enableRuntimeMetricsCollection() const;

bool prestoNativeSidecar() const;
std::string prestoDefaultNamespacePrefix() const;
};

/// Provides access to node properties defined in node.properties file.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,13 @@ target_link_libraries(
presto_common_test
presto_common
presto_exception
velox_aggregates
velox_exception
velox_file
velox_functions_prestosql
velox_function_registry
velox_presto_types
velox_window
${RE2}
GTest::gtest
GTest::gtest_main)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,59 @@
* limitations under the License.
*/
#include <gtest/gtest.h>
#include <unordered_set>
#include "presto_cpp/main/common/ConfigReader.h"
#include "presto_cpp/main/common/Configs.h"
#include "velox/common/base/Exceptions.h"
#include "velox/common/base/tests/GTestUtils.h"
#include "velox/common/file/File.h"
#include "velox/common/file/FileSystems.h"
#include "velox/exec/Aggregate.h"
#include "velox/exec/Window.h"
#include "velox/functions/FunctionRegistry.h"
#include "velox/functions/prestosql/aggregates/RegisterAggregateFunctions.h"
#include "velox/functions/prestosql/registration/RegistrationFunctions.h"
#include "velox/functions/prestosql/window/WindowFunctionsRegistration.h"

namespace facebook::presto::test {

using namespace velox;

namespace {

template <typename FunctionMap>
bool validateDefaultNamespacePrefix(
const FunctionMap& functionMap,
const std::string& prestoDefaultNamespacePrefix) {
static const std::unordered_set<std::string> kBlockList = {
"row_constructor", "in", "is_null"};

std::vector<std::string> prestoDefaultNamespacePrefixParts;
folly::split(
'.',
prestoDefaultNamespacePrefix,
prestoDefaultNamespacePrefixParts,
true);

for (const auto& [functionName, _] : functionMap) {
// Skip internal functions. They don't have any prefix.
if ((kBlockList.count(functionName) != 0) ||
(functionName.find("$internal$") != std::string::npos)) {
continue;
}

std::vector<std::string> parts;
folly::split('.', functionName, parts, true);
if ((parts.size() != 3) ||
(parts[0] != prestoDefaultNamespacePrefixParts[0]) ||
(parts[1] != prestoDefaultNamespacePrefixParts[1])) {
return false;
}
}
return true;
}
} // namespace

class ConfigTest : public testing::Test {
protected:
void SetUp() override {
Expand Down Expand Up @@ -310,4 +352,35 @@ TEST_F(ConfigTest, readConfigEnvVarTest) {
unsetenv(kEmptyEnvVarName.c_str());
}

TEST_F(ConfigTest, prestoDefaultNamespacePrefix) {
SystemConfig config;
init(
config,
{{std::string(SystemConfig::kPrestoDefaultNamespacePrefix),
"presto.default"}});
std::string prestoBuiltinFunctionPrefix =
config.prestoDefaultNamespacePrefix();

velox::functions::prestosql::registerAllScalarFunctions(
prestoBuiltinFunctionPrefix);
velox::aggregate::prestosql::registerAllAggregateFunctions(
prestoBuiltinFunctionPrefix);
velox::window::prestosql::registerAllWindowFunctions(
prestoBuiltinFunctionPrefix);

// Get all registered scalar functions in Velox
auto scalarFunctions = getFunctionSignatures();
ASSERT_TRUE(validateDefaultNamespacePrefix(
scalarFunctions, prestoBuiltinFunctionPrefix));

// Get all registered aggregate functions in Velox
auto aggregateFunctions = exec::aggregateFunctions().copy();
ASSERT_TRUE(validateDefaultNamespacePrefix(
aggregateFunctions, prestoBuiltinFunctionPrefix));

// Get all registered window functions in Velox
auto windowFunctions = exec::windowFunctions();
ASSERT_TRUE(validateDefaultNamespacePrefix(
windowFunctions, prestoBuiltinFunctionPrefix));
}
} // namespace facebook::presto::test
94 changes: 68 additions & 26 deletions presto-native-execution/presto_cpp/main/types/PrestoToVeloxExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include "presto_cpp/main/types/PrestoToVeloxExpr.h"
#include <boost/algorithm/string/case_conv.hpp>
#include "presto_cpp/main/common/Configs.h"
#include "presto_cpp/presto_protocol/Base64Util.h"
#include "velox/common/base/Exceptions.h"
#include "velox/functions/prestosql/types/JsonType.h"
Expand All @@ -33,24 +34,41 @@ std::string toJsonString(const T& value) {
}

std::string mapScalarFunction(const std::string& name) {
static const std::string prestoDefaultNamespacePrefix =
SystemConfig::instance()->prestoDefaultNamespacePrefix();
static const std::unordered_map<std::string, std::string> kFunctionNames = {
// Operator overrides: com.facebook.presto.common.function.OperatorType
{"presto.default.$operator$add", "presto.default.plus"},
{"presto.default.$operator$between", "presto.default.between"},
{"presto.default.$operator$divide", "presto.default.divide"},
{"presto.default.$operator$equal", "presto.default.eq"},
{"presto.default.$operator$greater_than", "presto.default.gt"},
{"presto.default.$operator$greater_than_or_equal", "presto.default.gte"},
{"presto.default.$operator$add",
formatDefaultNamespacePrefix(prestoDefaultNamespacePrefix, "plus")},
{"presto.default.$operator$between",
formatDefaultNamespacePrefix(prestoDefaultNamespacePrefix, "between")},
{"presto.default.$operator$divide",
formatDefaultNamespacePrefix(prestoDefaultNamespacePrefix, "divide")},
{"presto.default.$operator$equal",
formatDefaultNamespacePrefix(prestoDefaultNamespacePrefix, "eq")},
{"presto.default.$operator$greater_than",
formatDefaultNamespacePrefix(prestoDefaultNamespacePrefix, "gt")},
{"presto.default.$operator$greater_than_or_equal",
formatDefaultNamespacePrefix(prestoDefaultNamespacePrefix, "gte")},
{"presto.default.$operator$is_distinct_from",
"presto.default.distinct_from"},
{"presto.default.$operator$less_than", "presto.default.lt"},
{"presto.default.$operator$less_than_or_equal", "presto.default.lte"},
{"presto.default.$operator$modulus", "presto.default.mod"},
{"presto.default.$operator$multiply", "presto.default.multiply"},
{"presto.default.$operator$negation", "presto.default.negate"},
{"presto.default.$operator$not_equal", "presto.default.neq"},
{"presto.default.$operator$subtract", "presto.default.minus"},
{"presto.default.$operator$subscript", "presto.default.subscript"},
formatDefaultNamespacePrefix(
prestoDefaultNamespacePrefix, "distinct_from")},
{"presto.default.$operator$less_than",
formatDefaultNamespacePrefix(prestoDefaultNamespacePrefix, "lt")},
{"presto.default.$operator$less_than_or_equal",
formatDefaultNamespacePrefix(prestoDefaultNamespacePrefix, "lte")},
{"presto.default.$operator$modulus",
formatDefaultNamespacePrefix(prestoDefaultNamespacePrefix, "mod")},
{"presto.default.$operator$multiply",
formatDefaultNamespacePrefix(prestoDefaultNamespacePrefix, "muliply")},
{"presto.default.$operator$negation",
formatDefaultNamespacePrefix(prestoDefaultNamespacePrefix, "negate")},
{"presto.default.$operator$not_equal",
formatDefaultNamespacePrefix(prestoDefaultNamespacePrefix, "neq")},
{"presto.default.$operator$subtract",
formatDefaultNamespacePrefix(prestoDefaultNamespacePrefix, "minus")},
{"presto.default.$operator$subscript",
formatDefaultNamespacePrefix(prestoDefaultNamespacePrefix, "subscript")},
// Special form function overrides.
{"presto.default.in", "in"},
};
Expand All @@ -66,11 +84,15 @@ std::string mapScalarFunction(const std::string& name) {
}

std::string mapAggregateOrWindowFunction(const std::string& name) {
static const std::string prestoDefaultNamespacePrefix =
SystemConfig::instance()->prestoDefaultNamespacePrefix();
static const std::unordered_map<std::string, std::string> kFunctionNames = {
{"presto.default.$internal$max_data_size_for_stats",
"presto.default.max_data_size_for_stats"},
formatDefaultNamespacePrefix(
prestoDefaultNamespacePrefix, "max_data_size_for_stats")},
{"presto.default.$internal$sum_data_size_for_stats",
"presto.default.sum_data_size_for_stats"},
formatDefaultNamespacePrefix(
prestoDefaultNamespacePrefix, "sum_data_size_for_stats")},
};
std::string lowerCaseName = boost::to_lower_copy(name);
auto it = kFunctionNames.find(name);
Expand Down Expand Up @@ -167,6 +189,8 @@ std::optional<TypedExprPtr> convertCastToVarcharWithMaxLength(
const std::string& returnType,
const std::vector<TypedExprPtr>& args,
bool nullOnFailure) {
static const std::string prestoDefaultNamespacePrefix =
SystemConfig::instance()->prestoDefaultNamespacePrefix();
if (nullOnFailure) {
VELOX_NYI("TRY_CAST of varchar to {} is not supported.", returnType);
}
Expand All @@ -190,7 +214,7 @@ std::optional<TypedExprPtr> convertCastToVarcharWithMaxLength(
std::make_shared<ConstantTypedExpr>(velox::BIGINT(), 1LL),
std::make_shared<ConstantTypedExpr>(velox::BIGINT(), (int64_t)length),
},
"presto.default.substr");
formatDefaultNamespacePrefix(prestoDefaultNamespacePrefix, "substr"));
}

/// Converts cast and try_cast functions to CastTypedExpr with nullOnFailure
Expand All @@ -207,6 +231,8 @@ std::optional<TypedExprPtr> tryConvertCast(
const std::string& returnType,
const std::vector<TypedExprPtr>& args,
const TypeParser* typeParser) {
static const std::string prestoDefaultNamespacePrefix =
SystemConfig::instance()->prestoDefaultNamespacePrefix();
static const char* kCast = "presto.default.$operator$cast";
static const char* kTryCast = "presto.default.try_cast";
static const char* kJsonToArrayCast =
Expand Down Expand Up @@ -237,7 +263,10 @@ std::optional<TypedExprPtr> tryConvertCast(
return std::make_shared<CastTypedExpr>(
type,
std::vector<TypedExprPtr>{std::make_shared<CallTypedExpr>(
velox::JSON(), args, "presto.default.json_parse")},
velox::JSON(),
args,
formatDefaultNamespacePrefix(
prestoDefaultNamespacePrefix, "json_parse"))},
false);
} else {
return std::nullopt;
Expand Down Expand Up @@ -274,7 +303,6 @@ std::optional<TypedExprPtr> tryConvertTry(
const std::vector<TypedExprPtr>& args,
const TypeParser* typeParser) {
static const char* kTry = "presto.default.$internal$try";

if (signature.kind != protocol::FunctionKind::SCALAR) {
return std::nullopt;
}
Expand All @@ -300,8 +328,11 @@ std::optional<TypedExprPtr> tryConvertLiteralArray(
const std::vector<TypedExprPtr>& args,
velox::memory::MemoryPool* pool,
const TypeParser* typeParser) {
static const char* kLiteralArray = "presto.default.$literal$array";
static const char* kFromBase64 = "presto.default.from_base64";
static const std::string prestoDefaultNamespacePrefix =
SystemConfig::instance()->prestoDefaultNamespacePrefix();
static const char* kLiteralArray = "presto.default.$literal.$array";
static const std::string kFromBase64 =
formatDefaultNamespacePrefix(prestoDefaultNamespacePrefix, "from_base64");

if (signature.kind != protocol::FunctionKind::SCALAR) {
return std::nullopt;
Expand Down Expand Up @@ -342,7 +373,10 @@ std::optional<TypedExprPtr> tryConvertLiteralArray(

std::optional<TypedExprPtr> VeloxExprConverter::tryConvertDate(
const protocol::CallExpression& pexpr) const {
static const char* kDate = "presto.default.date";
static const std::string prestoDefaultNamespacePrefix =
SystemConfig::instance()->prestoDefaultNamespacePrefix();
static const std::string kDate =
formatDefaultNamespacePrefix(prestoDefaultNamespacePrefix, "date");

auto builtin = std::static_pointer_cast<protocol::BuiltInFunctionHandle>(
pexpr.functionHandle);
Expand All @@ -363,8 +397,12 @@ std::optional<TypedExprPtr> VeloxExprConverter::tryConvertDate(

std::optional<TypedExprPtr> VeloxExprConverter::tryConvertLike(
const protocol::CallExpression& pexpr) const {
static const char* kLike = "presto.default.like";
static const char* kLikePatternType = "presto.default.like_pattern";
static const std::string prestoDefaultNamespacePrefix =
SystemConfig::instance()->prestoDefaultNamespacePrefix();
static const std::string kLike =
formatDefaultNamespacePrefix(prestoDefaultNamespacePrefix, "like");
static const std::string kLikePatternType = formatDefaultNamespacePrefix(
prestoDefaultNamespacePrefix, "like_pattern");
static const char* kLikeReturnType = "LikePattern";
static const char* kCast = "presto.default.$operator$cast";

Expand Down Expand Up @@ -500,9 +538,13 @@ bool isTrueConstant(const TypedExprPtr& expression) {
std::shared_ptr<const CallTypedExpr> makeEqualsExpr(
const TypedExprPtr& a,
const TypedExprPtr& b) {
static const std::string prestoDefaultNamespacePrefix =
SystemConfig::instance()->prestoDefaultNamespacePrefix();
std::vector<TypedExprPtr> inputs{a, b};
return std::make_shared<CallTypedExpr>(
velox::BOOLEAN(), std::move(inputs), "presto.default.eq");
velox::BOOLEAN(),
std::move(inputs),
formatDefaultNamespacePrefix(prestoDefaultNamespacePrefix, "eq"));
}

std::shared_ptr<const CastTypedExpr> makeCastExpr(
Expand Down
Loading

0 comments on commit 046c021

Please sign in to comment.