-
Notifications
You must be signed in to change notification settings - Fork 5.4k
[native] Dynamically Linked Library in Presto CPP #24330
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please also rebase.
@@ -76,7 +76,8 @@ target_link_libraries( | |||
${FOLLY_WITH_DEPENDENCIES} | |||
${GLOG} | |||
${GFLAGS_LIBRARIES} | |||
pthread) | |||
pthread | |||
velox_dynamic_function_loader) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this before the velox_encode library.
@@ -89,6 +90,7 @@ set_property(TARGET presto_server_lib PROPERTY JOB_POOL_LINK | |||
presto_link_job_pool) | |||
|
|||
add_executable(presto_server PrestoMain.cpp) | |||
target_link_options(presto_server BEFORE PUBLIC "-Wl,-export-dynamic") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a comment here why we need these flags?
const fs::path path(systemConfig->pluginDir()); | ||
PRESTO_STARTUP_LOG(INFO) << path; | ||
std::error_code | ||
ec; // For using the non-throwing overloads of functions below. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don;t need this comment here and so can fix up the odd formatting.
void PrestoServer::registerDynamicFunctions() { | ||
auto systemConfig = SystemConfig::instance(); | ||
if (!systemConfig->pluginDir().empty()) { | ||
// if it is a valid directory, traverse and call dynamic function loader |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make sure the comments are full sentences beginning with capitalization etc.
auto dirEntryPath = dirEntry.path(); | ||
if (!fs::is_directory(dirEntry, ec) && | ||
extensions.find(dirEntryPath.extension()) != extensions.end()) { | ||
facebook::velox::loadDynamicLibrary(dirEntryPath.c_str()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
facebook is not needed here because we are already in the facebook namespace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the doc! A few minor formatting and phrasing suggestions.
@@ -0,0 +1,17 @@ | |||
# Dynamic Loading of Presto Cpp Extensions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# Dynamic Loading of Presto Cpp Extensions | |
# Dynamic Loading of Presto CPP Extensions |
@@ -0,0 +1,17 @@ | |||
# Dynamic Loading of Presto Cpp Extensions | |||
This library adds the ability to load User Defined Functions (UDFs), connectors, or types without having to fork and build Prestissimo, through the use of shared libraries that a Prestissimo worker can access. These are to be loaded on launch of the Presto server. The Presto server searches for any .so or .dylib files and loads them using this library. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This library adds the ability to load User Defined Functions (UDFs), connectors, or types without having to fork and build Prestissimo, through the use of shared libraries that a Prestissimo worker can access. These are to be loaded on launch of the Presto server. The Presto server searches for any .so or .dylib files and loads them using this library. | |
This library adds the ability to load User Defined Functions (UDFs), connectors, or types without having to fork and build Prestissimo, through the use of shared libraries that a Prestissimo worker can access. These are loaded on launch of the Presto server. The Presto server searches for any .so or .dylib files and loads them using this library. |
This library adds the ability to load User Defined Functions (UDFs), connectors, or types without having to fork and build Prestissimo, through the use of shared libraries that a Prestissimo worker can access. These are to be loaded on launch of the Presto server. The Presto server searches for any .so or .dylib files and loads them using this library. | ||
## Getting started | ||
1. Create a cpp file for your dynamic library | ||
For dynamically loaded function registration, the format followed is mirrored of that of built-in function registration with some noted differences. Using [MyDynamicFunction.cpp](examples/MyDynamicFunction.cpp) as an example, the function uses the extern "C" keyword to protect against name mangling. A registry() function call is also necessary here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For dynamically loaded function registration, the format followed is mirrored of that of built-in function registration with some noted differences. Using [MyDynamicFunction.cpp](examples/MyDynamicFunction.cpp) as an example, the function uses the extern "C" keyword to protect against name mangling. A registry() function call is also necessary here. | |
For dynamically loaded function registration, the format is similar to that of built-in function registration, with some noted differences. Using [MyDynamicFunction.cpp](examples/MyDynamicFunction.cpp) as an example, the function uses the extern "C" keyword to protect against name mangling. A registry() function call is also necessary here. |
presto-native-execution/presto_cpp/main/dynamic_registry/README.md
Outdated
Show resolved
Hide resolved
presto-native-execution/presto_cpp/main/dynamic_registry/README.md
Outdated
Show resolved
Hide resolved
presto-native-execution/presto_cpp/main/dynamic_registry/README.md
Outdated
Show resolved
Hide resolved
``` | ||
plugin.dir="User\Test\Path\plugin" | ||
``` | ||
4. When the worker or the sidecar process starts, it will scan the plugin directory and attempt to dynamically load all shared libraries |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4. When the worker or the sidecar process starts, it will scan the plugin directory and attempt to dynamically load all shared libraries | |
When the worker or the sidecar process starts, it scans the plugin directory and attempts to dynamically load all shared libraries. |
I don't think of this as part of the steps to configure, it's what happens when things are run using the config in steps 1-3.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the documentation! I really liked your including the setup steps on plugin.rst. Some minor suggestions for formatting and phrasing but looks good overall.
presto-native-execution/presto_cpp/main/dynamic_registry/README.md
Outdated
Show resolved
Hide resolved
presto-docs/src/main/sphinx/presto_cpp/plugin/function_plugin.rst
Outdated
Show resolved
Hide resolved
presto-docs/src/main/sphinx/presto_cpp/plugin/function_plugin.rst
Outdated
Show resolved
Hide resolved
presto-docs/src/main/sphinx/presto_cpp/plugin/function_plugin.rst
Outdated
Show resolved
Hide resolved
Thanks @steveburnett please take another look, I've made the changes. I'm not sure about the tone on the intro to UDFs i have on function_plugin.rst, would appreciate another set of eyes there. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the revision! Nice work, your unordered list of UDF benefits was great and the format fixes in the README look good.
I made a couple of small suggestions about the intro to UDFs, let me know what you think.
presto-docs/src/main/sphinx/presto_cpp/plugin/function_plugin.rst
Outdated
Show resolved
Hide resolved
presto-docs/src/main/sphinx/presto_cpp/plugin/function_plugin.rst
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should have noticed this spelling nit earlier! After I found this one, I did a complete review of the doc in this PR and found no other errors so I think this is the last one.
presto-docs/src/main/sphinx/presto_cpp/plugin/function_plugin.rst
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@soumiiow : Thanks for this code. Would be great to have an e2e test with a SQL statement using the dynamic functions. On the lines of https://github.com/prestodb/presto/blob/master/presto-native-execution/src/test/java/com/facebook/presto/nativeworker/TestPrestoNativeRemoteFunctions.java
auto systemConfig = SystemConfig::instance(); | ||
cpp_nameSpace = systemConfig->prestoDefaultNamespacePrefix(); | ||
} | ||
std::string cpp_name(cpp_nameSpace); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there an assumption that namespace should end in "." ? We should make this behavior more robust by adding the period separator if its not present.
const char* nameSpace = "", | ||
const std::vector<velox::exec::SignatureVariable>& constraints = {}, | ||
bool overwrite = true) { | ||
std::string cpp_nameSpace(nameSpace); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use camelcase cppNamespace
@@ -1598,5 +1600,28 @@ protocol::NodeStatus PrestoServer::fetchNodeStatus() { | |||
|
|||
return nodeStatus; | |||
} | |||
void PrestoServer::registerDynamicFunctions() { | |||
auto systemConfig = SystemConfig::instance(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be good to have a config of library names to load rather than load all those found in the directory. wdyt ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aditi-pandit I'm trying to understand here what would the additional benefit be in doing so.
From the perspective of the user, only the shared library paths will be recognized here so any say .txt files, .cpp files, etc will not be read. Beyond that, is there a benefit to having a config here? I see it as another step for the user to have to maintain and worry about every time they'd want to add/remove a shared library
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@soumiiow : My thinking is that having a config of library names could help us if someone accidentally put in a library that had errors and issues. Right now a bad library causes the entire loading to fail, and the platform owner would need to restage the complete directory. If on the other hand they have a white-list of libraries that are good, they can easily add or remove libraries by changing the config.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @aditi-pandit , better to have a config file/entry to limit the library that can be loaded by prestissimo. Imagine that you load all libraries under a specific folder, what if someone write a library maliciously and put it into this folder. When calling those function that might lead to:
- Process crash
- Same privilege is shared, the function can do anything they want.
And if scanned by a security tool, this piece of code could report a vulnerability.
BTW, if a customer implement a new UDF themself and put the library to this plugin directory, do they need to restart presto server to take effect?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@PingLiuPing to answer the question, yes they have to restart the coordinator and all workers for this new udf to take effect
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having recursive globbing or regex can remediate the issue and that's a good idea.
But I think your current logic is good enough to filter the dynamic libraries from other file types. And you have defined the plugin.dir in configuration file.
You need to verify each dynamic library is actually the one you want to load. The easist way to achieve this is adding a verify
functioin inside the dynamic library. And when loading the library you can check if verify
function is existed and then execute it. Inside verify
function you can check the pass-in value against a fixed value, for example a UUID or even the UDF name. Though this still can be compromised, a step further towards industry product.
I just jump in to your new feature. I assume the UDF is automatically registerd.
Another approach is provide another layer of control where after the function been loaded into velox, those function cannot be directly registed and called. Instead, some DDL need to be executed to register those function, for example
create function ABC (parameters...) options (library_path ......)
In this way you define the library path explicitly for each function. And only those function been explicitly created by above DDL can be called.
Your work opened up a whole new world. And it deserves to be more careful. Welcome to discuss more alternatives.
Thanks.
@soumiiow @mohsaka
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add an example of a function which is added to the non-default namespace.
Changes needed for Mac,
Remove braces from examples. Update:
|
9d94f4f
to
ec86c3d
Compare
@@ -1598,5 +1600,28 @@ protocol::NodeStatus PrestoServer::fetchNodeStatus() { | |||
|
|||
return nodeStatus; | |||
} | |||
void PrestoServer::registerDynamicFunctions() { | |||
auto systemConfig = SystemConfig::instance(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @aditi-pandit , better to have a config file/entry to limit the library that can be loaded by prestissimo. Imagine that you load all libraries under a specific folder, what if someone write a library maliciously and put it into this folder. When calling those function that might lead to:
- Process crash
- Same privilege is shared, the function can do anything they want.
And if scanned by a security tool, this piece of code could report a vulnerability.
BTW, if a customer implement a new UDF themself and put the library to this plugin directory, do they need to restart presto server to take effect?
extern "C" { | ||
void registry() { | ||
facebook::presto::registerPrestoFunction< | ||
nameOfStruct, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: nameOfStruct to NameOfStruct.
* Once defined, easily reusable and called multiple times just like built in functions. | ||
* Shorter compile times. | ||
|
||
1. To create the UDF, create a new C++ file in the following format: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is better to give a file name here, that will better align wiht the following content. For exmaple TestFunction.cpp is ok.
Ideally we would have a kind of recursive globbing but there doesn't seem to be any library for that. Then we would have a config that allows something like this "a/b/c.dylib a//.dylib etc". But this will need to be implemented with probably filesystem + glob libraries. Alternatively we can use the regular globbing library and have the user have to enter the directories. So then it would be something like "a/b/* a/c/* etc" The easiest would be requiring the user to have to provide the absolute path for all of the libraries. Something like "a/b/c.dylib a/b/d.dylib" An alternative would be that you can provide a path regex. Something like "^/a/b/.*" and a directory. We would then recursively go through the directory and only pick libraries that match a certain regex expression. Or even simpler, just have library file names that we accept as a second config. |
@mohsaka @aditi-pandit @PingLiuPing Also for ease of use, i was also thinking, in the absence of a config, we can by default scan in all .dylib/.so files so it's not a requirement for them to put a config in if users just want to plug in and go. thoughts on that? |
I don't think it would crash the worker, we would just not load the library if it didn't match the filepath/regex/etc. |
@mohsaka good point, looking through the velox implementation using dylib, dlerror() would catch the error and give a VELOX_USER_FAIL. |
Hey @pedroerp! I was looking through remote_function_server.json to design the config for the dylib changes to be simple to use and similar to the remote fn registrations so as to make for a seamless user experience. I was curious as to the intended purpose of the In prestissimo, when we use a prefix/namespace like also, i notice that in PrestoServer.cpp, prefix is set to |
# 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. | ||
add_subdirectory(examples) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there is potential issues with regard to upgrading.
You need to fix this by changing some script to trigger the building of the dynamic library when upgrading (from customer perspective). This gurrantee the ABI compatibility in case of major compiler upgrade.
Well this requires the source code should be under some specific directory of presto installation path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed offline about ABI compatibility issues and came up with documentation changes to alert the users to rebuild shared libraries upon upgrades manually.
presto-docs/src/main/sphinx/presto_cpp/plugin.rst
Updated the RFC with the discussions regarding adding a Json config, function validation, customizable entrypoint, and signal handling so as to not crash the worker here prestodb/rfcs#24. please take a look! |
a8d2204
to
173ecc9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the doc! This will be great to have in the doc. I have some suggestions for conciseness and readability, and a couple of questions for you to consider. Let me know what you think, please!
add_library(name_of_dynamic_fn SHARED TestFunction.cpp) | ||
target_link_libraries(name_of_dynamic_fn PRIVATE fmt::fmt Folly::folly gflags::gflags) | ||
|
||
3. Place your shared libraries in the plugin directory. The path to this directory needs to be the same as ``plugin.dir`` property set in :doc:`../plugin`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3. Place your shared libraries in the plugin directory. The path to this directory needs to be the same as ``plugin.dir`` property set in :doc:`../plugin`. | |
3. Place your shared libraries in the plugin directory. The path to this directory must be the same as the ``plugin.dir`` property set in :doc:`../plugin`. |
@@ -0,0 +1 @@ | |||
Read [here](https://prestodb.io/docs/current/presto-cpp/plugin.html) on how to use the Dynamic Library Loader. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Read [here](https://prestodb.io/docs/current/presto-cpp/plugin.html) on how to use the Dynamic Library Loader. | |
See [Function Plugin](https://prestodb.io/docs/current/presto-cpp/plugin.html) on how to use the Dynamic Library Loader. |
Thanks for addressing the other reviewer's comment by using link to your doc instead of duplicating the content! (If the same text is in two different places then it has to be maintained and updated as twice the work, and errors are likelier to happen.)
When creating a link, here
doesn't tell the reader what to expect to find when they open the link. A good practice is to use the title of the destination page in the link, so the reader knows where they are going before they start. (Also, sometimes the title can save the reader time because they might decide this isn't what they need right now.)
Presto C++ Plugins | ||
******************* | ||
|
||
This chapter outlines the plugins in Presto C++ that are available for various use cases such as to load User Defined Functions (UDFs), connectors, or types. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This chapter outlines the plugins in Presto C++ that are available for various use cases such as to load User Defined Functions (UDFs), connectors, or types. | |
This page lists the plugins in Presto C++ that are available for various use cases such as to load User Defined Functions (UDFs), connectors, or types, and describes the setup needed to use these plugins. |
|
||
2. Create a Json configuration file where you will capture information on the shared libraries you wish to load dynamically. | ||
|
||
3. Set the ``plugin.dir`` property to the path of the ``plugins`` directory in the ``config.properties`` file of each of your workers. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3. Set the ``plugin.dir`` property to the path of the ``plugins`` directory in the ``config.properties`` file of each of your workers. | |
3. Set the ``plugin.dir`` property to the path of the ``plugins`` directory in the ``config.properties`` file of each worker. |
|
||
2. Create a Json configuration file where you will capture information on the shared libraries you wish to load dynamically. | ||
|
||
3. Set the ``plugin.dir`` property to the path of the ``plugins`` directory in the ``config.properties`` file of each of your workers. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
1. Place the plugin shared libraries in the ``plugins`` directory. | ||
|
||
2. Create a Json configuration file where you will capture information on the shared libraries you wish to load dynamically. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2. Create a Json configuration file where you will capture information on the shared libraries you wish to load dynamically. | |
2. Create a Json configuration file to capture information on the shared libraries you wish to load dynamically. |
Where should this file be created? Can you give an example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this file can technically be created anywhere and my current design does not ask for a particular path to make it easier from a deployment perspective. Theres a chance that the person creating the shared library is not the same as the person creating the config. As long as the user gives the full path for the config file it should get read.
So i want to discuss here first if you see value in putting that information into the docs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those are excellent points! I agree now that there's no need for it here. Thanks!
|
||
5. Start or restart the coordinator and workers to pick up any placed libraries. | ||
|
||
Note: to avoid issues with ABI compatibility, we strongly recommend recompiling all shared library plugins during OS and presto version upgrades. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: to avoid issues with ABI compatibility, we strongly recommend recompiling all shared library plugins during OS and presto version upgrades. | |
Note: To avoid issues with ABI compatibility, it is strongly recommended to recompile all shared library plugins during OS and Presto version upgrades. |
* ``nameSpace``: optional field. omitting this field gives the function the default namespace similarly to the function registeration. must match the namespace of the function. | ||
* ``docString``, ``routineCharacteristics``, ``functionKind``: collected for checking metadata. | ||
|
||
5. Set the ``plugin.config`` property to the path of Json config. Instructions to set the property in :doc:`../plugin`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
5. Set the ``plugin.config`` property to the path of Json config. Instructions to set the property in :doc:`../plugin`. | |
5. Set the ``plugin.config`` property to the path of the Json configuration file created in Step 4. See :doc:`../plugin`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@soumiiow : Did a quick pass of your code. Its overall a good design for the first-cut implementation.
const fs::path path(systemConfig->pluginDir()); | ||
PRESTO_STARTUP_LOG(INFO) << "Dynamic library loading path: " << path; | ||
std::error_code ec; | ||
if (fs::is_directory(path, ec)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be simpler to check if there is a validator config and ensure its non-empty before checking the pluginDir path at all.
/// "my_function": [ | ||
/// { | ||
/// "outputType": "integer", | ||
/// "entrypoint": "nameOfRegistryFnCall", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the formating of this line.
int64_t compareConfigWithRegisteredFunctionSignatures( | ||
facebook::velox::FunctionSignatureMap fnSignaturesBefore); | ||
|
||
std:: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a shorthand for
std::unordered_map<std::string, std::vectorvelox::exec::FunctionSignaturePtr> with "using" statement.
DynamicLibraryValidator dVal(configPath, systemConfig->pluginDir()); | ||
auto filenameAndEntrypointMap = dVal.getEntrypointMap(); | ||
auto registeredFnSignaturesBefore = velox::getFunctionSignatures(); | ||
for (const auto& entryPointItr : filenameAndEntrypointMap) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All this logic can be moved into the DynamicLibraryValidator class (maybe call it DynamicLibraryLoader instead).
The code here would only read the config entries for plugin.dir and dynamiclibraryvalidator and pass them to DynamicLibraryLoader.
@@ -197,5 +197,52 @@ TEST_F(JsonSignatureParserTest, multiple) { | |||
EXPECT_EQ(signature1->argumentTypes()[1].baseName(), "varchar"); | |||
} | |||
|
|||
TEST_F(JsonSignatureParserTest, dynamic) { | |||
auto input = R"( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a function which uses a complex type for either paramType or outputType
} | ||
})"; | ||
|
||
// Emulate user provided config file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a some repetition of code between this and the test below. Can you make common functions for reuse ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a need to separate the directories for this file from the previous directory ?
If yes, then it might be worth trying a recursive directory scenario as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove the usage of "My" in the naming of these files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updated doc! Just a couple of small nits.
|
||
Note: the ``int64_t`` return type, ``registryTest`` registry symbol name can be changed as needed. For more examples, see the `examples <https://github.com/prestodb/presto/tree/master/presto-native-execution/main/dynamic_registry/examples>`_. | ||
|
||
2. Create a shared library which may be made using CMakeLists.txt like the following: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2. Create a shared library which may be made using CMakeLists.txt like the following: | |
2. Create a shared library which may be made using ``CMakeLists.txt`` like the following: |
|
||
3. Place your shared libraries in the plugin directory. The path to this directory must be the same as the ``plugin.dir`` property set in :doc:`../plugin`. | ||
|
||
4. Create a Json configuration file in the same format as below: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4. Create a Json configuration file in the same format as below: | |
4. Create a JSON configuration file in the same format as below: |
Description
Depends on facebookincubator/velox#11439 in the Velox space
and based off of the following PR: https://github.com/facebookincubator/velox/pull/1005/files
Motivation and Context
Having these changes will enable users to register custom functions dynamically without requiring a fork of Prestissimo.
Impact
This extends Prestissimo functionality to include dynamic loading of functions, types, connectors, etc.
Test Plan
Unit tested. and Manually end to end tested the changes.
Contributor checklist
Release Notes
Please follow release notes guidelines and fill in the release notes below.
If release note is NOT required, use: