Skip to content

[native] Dynamically Linked Library in Presto CPP#24330

Merged
aditi-pandit merged 1 commit intoprestodb:masterfrom
soumiiow:dylib_new
Jun 27, 2025
Merged

[native] Dynamically Linked Library in Presto CPP#24330
aditi-pandit merged 1 commit intoprestodb:masterfrom
soumiiow:dylib_new

Conversation

@soumiiow
Copy link
Contributor

@soumiiow soumiiow commented Jan 7, 2025

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

  • Please make sure your submission complies with our contributing guide, in particular code style and commit standards.
  • PR description addresses the issue accurately and concisely. If the change is non-trivial, a GitHub Issue is referenced.
  • Documented new properties (with its default value), SQL syntax, functions, or other functionality.
  • If release notes are required, they follow the release notes guidelines.
  • Adequate tests were added if applicable.
  • CI passed.

Release Notes

Please follow release notes guidelines and fill in the release notes below.

== RELEASE NOTES ==

General Changes
* ... :pr:`12345`
* ... :pr:`12345`

Hive Connector Changes
* ... :pr:`12345`
* ... :pr:`12345`

If release note is NOT required, use:

== NO RELEASE NOTE ==

@soumiiow soumiiow self-assigned this Jan 7, 2025
@linux-foundation-easycla
Copy link

linux-foundation-easycla bot commented Jan 7, 2025

CLA Signed

The committers listed above are authorized under a signed CLA.

  • ✅ login: soumiiow / name: Soumya Duriseti (24262e3)

@soumiiow soumiiow marked this pull request as ready for review January 7, 2025 18:04
@soumiiow soumiiow requested a review from a team as a code owner January 7, 2025 18:04
@tdcmeehan tdcmeehan self-assigned this Jan 8, 2025
@tdcmeehan tdcmeehan added the from:IBM PR from IBM label Jan 30, 2025
@prestodb-ci prestodb-ci requested review from a team, pdabre12 and psnv03 and removed request for a team January 30, 2025 18:47
Copy link
Contributor

@czentgr czentgr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also rebase.

${GFLAGS_LIBRARIES}
pthread)
pthread
velox_dynamic_function_loader)
Copy link
Contributor

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.

presto_link_job_pool)

add_executable(presto_server PrestoMain.cpp)
target_link_options(presto_server BEFORE PUBLIC "-Wl,-export-dynamic")
Copy link
Contributor

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.
Copy link
Contributor

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
Copy link
Contributor

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());
Copy link
Contributor

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.

Copy link
Contributor

@steveburnett steveburnett left a 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.

Copy link
Contributor

@steveburnett steveburnett left a 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.

@soumiiow
Copy link
Contributor Author

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.

Copy link
Contributor

@steveburnett steveburnett left a 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.

Copy link
Contributor

@steveburnett steveburnett left a 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.

* 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 named ``ExampleFunction.cpp`` in the same format as this example:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reads like you can only use the name ExampleFunction.cpp. You can say something like

"Create a new C++ file for your UDF. We are using a c++ file named `ExampleFunction.cpp`` for the examples below."

Copy link
Contributor Author

@soumiiow soumiiow Jun 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch! thank you!

To create the UDF, create a new C++ file in the same format as the below example file named ExampleFunction.cpp

hope this conveys the message!! lmk what you think

}
}

Note: The ``int64_t`` return type and the ``Varchar`` input type can be changed as needed. Additional or no arguments may be specified as well. For more examples, see the `examples <https://github.com/soumiiow/presto/tree/dylib_new/presto-native-execution/presto_cpp/main/dynamic_registry/examples>`_.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a link saying that the functions follow Velox scalar function API. Please follow https://facebookincubator.github.io/velox/develop/scalar-functions.html for more details on how to write scalar functions.

void PrestoServer::registerDynamicFunctions() {
std::error_code
ec; // For using the non-throwing overloads of functions below.
auto systemConfig = SystemConfig::instance();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const auto

for (const auto& dirEntry :
std::filesystem::directory_iterator(pluginDir)) {
if (isSharedLibrary(dirEntry.path())) {
PRESTO_STARTUP_LOG(INFO)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add the library name in the info message.

Copy link
Contributor

@czentgr czentgr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

} // namespace facebook::velox::common::dynamicRegistry

extern "C" {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the other files have no empty line here.

};

extern "C" {
void registerExtensions() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we mention it that this name is required in the note below? It is mentioned in the examples.
We could say something like:

The function registerExtensions is the entry point to execute the registration of the UDF and cannot be changed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i like this, ill add this as a comment for all example files!

# See the License for the specific language governing permissions and
# limitations under the License.

add_subdirectory(examples)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to add a CMake flag PRESTO_ENABLE_EXAMPLES to guard this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will add this here, but i'm wondering should this be able enabled/disabled in presto-native-execution/CMakelists.txt like so:
set(PRESTO_ENABLE_EXAMPLES OFF CACHE BOOL "Enable Presto examples")

@@ -0,0 +1,122 @@
/*
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this test being run? I don't see it being added to any test executable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry meant to leave this file out! i mustve picked up this change as i was switching my branches around

endif()

set(PRESTO_ENABLE_EXAMPLES
ON
Copy link
Collaborator

@majetideepak majetideepak Jun 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default OFF


void PrestoServer::registerDynamicFunctions() {
std::error_code
ec; // For using the non-throwing overloads of functions below.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// For using the non-throwing overloads of functions below.
std::error_code ec;

majetideepak
majetideepak previously approved these changes Jun 16, 2025
majetideepak
majetideepak previously approved these changes Jun 18, 2025
aditi-pandit
aditi-pandit previously approved these changes Jun 18, 2025
Copy link
Contributor

@aditi-pandit aditi-pandit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @soumiiow for the iterations.

@aditi-pandit
Copy link
Contributor

@soumiiow : Can you rebase ?

czentgr
czentgr previously approved these changes Jun 23, 2025
majetideepak
majetideepak previously approved these changes Jun 23, 2025
@majetideepak
Copy link
Collaborator

@steveburnett can you please re-review the doc changes?

aditi-pandit
aditi-pandit previously approved these changes Jun 23, 2025
Copy link
Contributor

@aditi-pandit aditi-pandit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @soumiiow

Copy link
Contributor

@steveburnett steveburnett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! A formatting nit, and a suggestion that I think makes the steps more clear.

Copy link
Contributor

@steveburnett steveburnett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A single formatting nit, nothing else!

steveburnett
steveburnett previously approved these changes Jun 23, 2025
Copy link
Contributor

@steveburnett steveburnett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! (docs)

Pull updated branch, new local doc build, looks great. No problems found.

Thanks for your patience!

Copy link
Contributor

@aditi-pandit aditi-pandit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @soumiiow

Copy link
Contributor

@steveburnett steveburnett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGMT! (docs)

Pull updated branch, new local doc build, everything looks good.

@aditi-pandit
Copy link
Contributor

@soumiiow : Can you change the commit title to that of this PR ? Presto PRs are not merged like Velox PRs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

from:IBM PR from IBM

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants