From 2f6af26f57d9a6e7bd460dee7acb40c73727c938 Mon Sep 17 00:00:00 2001
From: Pindikura Ravindra
Date: Mon, 3 Sep 2018 14:33:45 +0530
Subject: [PATCH] GDV-56: [C++] Add a helper library containing cpp stubs (#88)
- To get around the java load issue, create a native library and load it in the LLVM module.
This module has the hooks for all the c++ function helpers.
- for files that are compiled in libgandiva_helpers, add into gandiva::helpers namespace.
- merged status.cc into status.h
---
cpp/src/gandiva/CMakeLists.txt | 15 +++-
cpp/src/gandiva/codegen/CMakeLists.txt | 44 +++++++---
cpp/src/gandiva/codegen/bc_file_path.cc.in | 3 +
cpp/src/gandiva/codegen/configuration.h | 30 +++++--
cpp/src/gandiva/codegen/engine.cc | 32 +++++++-
cpp/src/gandiva/codegen/engine.h | 9 ++-
.../gandiva/codegen/function_holder_stubs.cc | 23 ++++++
cpp/src/gandiva/codegen/like_holder.cc | 11 +--
cpp/src/gandiva/codegen/like_holder.h | 8 ++
.../gandiva/codegen/llvm_generator_test.cc | 2 +-
cpp/src/gandiva/codegen/regex_util.cc | 12 ++-
cpp/src/gandiva/codegen/regex_util.h | 9 ++-
cpp/src/gandiva/codegen/status.cc | 81 -------------------
cpp/src/gandiva/codegen/status.h | 60 ++++++++++++++
cpp/src/gandiva/jni/config_builder.cc | 8 ++
cpp/src/gandiva/jni/env_helper.h | 1 +
cpp/src/gandiva/jni/jni_common.cc | 5 ++
17 files changed, 241 insertions(+), 112 deletions(-)
create mode 100644 cpp/src/gandiva/codegen/function_holder_stubs.cc
delete mode 100644 cpp/src/gandiva/codegen/status.cc
diff --git a/cpp/src/gandiva/CMakeLists.txt b/cpp/src/gandiva/CMakeLists.txt
index 972678ec47003..61d54f7eeb69a 100644
--- a/cpp/src/gandiva/CMakeLists.txt
+++ b/cpp/src/gandiva/CMakeLists.txt
@@ -20,11 +20,22 @@ project(gandiva)
find_package(LLVM)
# Set the path where the byte-code files will be installed.
-set(GANDIVA_BC_FILE_NAME irhelpers.bc)
set(GANDIVA_BC_INSTALL_DIR
${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/gandiva)
+
+set(GANDIVA_BC_FILE_NAME irhelpers.bc)
set(GANDIVA_BC_INSTALL_PATH ${GANDIVA_BC_INSTALL_DIR}/${GANDIVA_BC_FILE_NAME})
-set(GANDIVA_BC_OUTPUT_PATH ${CMAKE_BINARY_DIR}/irhelpers.bc)
+set(GANDIVA_BC_OUTPUT_PATH ${CMAKE_BINARY_DIR}/${GANDIVA_BC_FILE_NAME})
+
+# Set the path where the so lib file will be installed.
+if (APPLE)
+ set(GANDIVA_HELPER_LIB_FILE_NAME libgandiva_helpers.dylib)
+else()
+ set(GANDIVA_HELPER_LIB_FILE_NAME libgandiva_helpers.so)
+endif(APPLE)
+
+set(GANDIVA_HELPER_LIB_INSTALL_PATH ${GANDIVA_BC_INSTALL_DIR}/${GANDIVA_HELPER_LIB_FILE_NAME})
+set(GANDIVA_HELPER_LIB_OUTPUT_PATH ${CMAKE_BINARY_DIR}/src/codegen/${GANDIVA_HELPER_LIB_FILE_NAME})
add_subdirectory(codegen)
add_subdirectory(jni)
diff --git a/cpp/src/gandiva/codegen/CMakeLists.txt b/cpp/src/gandiva/codegen/CMakeLists.txt
index 7ebf08618cd9c..0bc760acad4bb 100644
--- a/cpp/src/gandiva/codegen/CMakeLists.txt
+++ b/cpp/src/gandiva/codegen/CMakeLists.txt
@@ -22,6 +22,11 @@ find_package(Boost COMPONENTS system regex filesystem REQUIRED)
set(BC_FILE_PATH_CC "${CMAKE_CURRENT_BINARY_DIR}/bc_file_path.cc")
configure_file(bc_file_path.cc.in ${BC_FILE_PATH_CC})
+# helper files that are shared between libgandiva and libgandiva_helpers
+set(SHARED_HELPER_FILES
+ like_holder.cc
+ regex_util.cc)
+
set(SRC_FILES annotator.cc
bitmap_accumulator.cc
configuration.cc
@@ -35,12 +40,10 @@ set(SRC_FILES annotator.cc
function_signature.cc
llvm_generator.cc
llvm_types.cc
- like_holder.cc
projector.cc
selection_vector.cc
- regex_util.cc
- status.cc
tree_expr_builder.cc
+ ${SHARED_HELPER_FILES}
${BC_FILE_PATH_CC})
add_library(gandiva_obj_lib OBJECT ${SRC_FILES})
@@ -84,18 +87,39 @@ install(
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
+# Pre-compiled .so library for function helpers.
+add_library(gandiva_helpers SHARED
+ ${SHARED_HELPER_FILES}
+ function_holder_stubs.cc)
+
+target_compile_definitions(gandiva_helpers
+ PRIVATE -DGDV_HELPERS
+)
+
+target_include_directories(gandiva_helpers
+ PRIVATE
+ ${CMAKE_SOURCE_DIR}/include
+ ${CMAKE_SOURCE_DIR}/src
+ $
+)
+
+target_link_libraries(gandiva_helpers PRIVATE Boost::boost)
+if (NOT APPLE)
+ target_link_libraries(gandiva_helpers LINK_PRIVATE -static-libstdc++ -static-libgcc)
+endif()
+
#args: label test-file src-files
add_gandiva_unit_test(bitmap_accumulator_test.cc bitmap_accumulator.cc)
-add_gandiva_unit_test(engine_llvm_test.cc engine.cc llvm_types.cc status.cc configuration.cc ${BC_FILE_PATH_CC})
+add_gandiva_unit_test(engine_llvm_test.cc engine.cc llvm_types.cc configuration.cc ${BC_FILE_PATH_CC})
add_gandiva_unit_test(function_signature_test.cc function_signature.cc)
add_gandiva_unit_test(function_registry_test.cc function_registry.cc function_signature.cc)
add_gandiva_unit_test(llvm_types_test.cc llvm_types.cc)
-add_gandiva_unit_test(llvm_generator_test.cc llvm_generator.cc regex_util.cc engine.cc llvm_types.cc expr_decomposer.cc function_registry.cc annotator.cc status.cc bitmap_accumulator.cc configuration.cc function_signature.cc like_holder.cc regex_util.cc ${BC_FILE_PATH_CC})
+add_gandiva_unit_test(llvm_generator_test.cc llvm_generator.cc regex_util.cc engine.cc llvm_types.cc expr_decomposer.cc function_registry.cc annotator.cc bitmap_accumulator.cc configuration.cc function_signature.cc like_holder.cc regex_util.cc ${BC_FILE_PATH_CC})
add_gandiva_unit_test(annotator_test.cc annotator.cc function_signature.cc)
-add_gandiva_unit_test(tree_expr_test.cc tree_expr_builder.cc expr_decomposer.cc annotator.cc function_registry.cc function_signature.cc like_holder.cc regex_util.cc status.cc)
-add_gandiva_unit_test(expr_decomposer_test.cc expr_decomposer.cc tree_expr_builder.cc annotator.cc function_registry.cc function_signature.cc like_holder.cc regex_util.cc status.cc)
-add_gandiva_unit_test(status_test.cc status.cc)
+add_gandiva_unit_test(tree_expr_test.cc tree_expr_builder.cc expr_decomposer.cc annotator.cc function_registry.cc function_signature.cc like_holder.cc regex_util.cc)
+add_gandiva_unit_test(expr_decomposer_test.cc expr_decomposer.cc tree_expr_builder.cc annotator.cc function_registry.cc function_signature.cc like_holder.cc regex_util.cc)
+add_gandiva_unit_test(status_test.cc)
add_gandiva_unit_test(expression_registry_test.cc llvm_types.cc expression_registry.cc function_signature.cc function_registry.cc)
-add_gandiva_unit_test(selection_vector_test.cc selection_vector.cc status.cc)
+add_gandiva_unit_test(selection_vector_test.cc selection_vector.cc)
add_gandiva_unit_test(lru_cache_test.cc)
-add_gandiva_unit_test(like_holder_test.cc like_holder.cc regex_util.cc status.cc)
+add_gandiva_unit_test(like_holder_test.cc like_holder.cc regex_util.cc)
diff --git a/cpp/src/gandiva/codegen/bc_file_path.cc.in b/cpp/src/gandiva/codegen/bc_file_path.cc.in
index 74d003b34e380..bcf6fd9771fa9 100644
--- a/cpp/src/gandiva/codegen/bc_file_path.cc.in
+++ b/cpp/src/gandiva/codegen/bc_file_path.cc.in
@@ -17,4 +17,7 @@ namespace gandiva {
// Path to the byte-code file.
extern const char kByteCodeFilePath[] = "${GANDIVA_BC_OUTPUT_PATH}";
+// Path to the pre-compiled solib file.
+extern const char kHelperLibFilePath[] = "${GANDIVA_HELPER_LIB_OUTPUT_PATH}";
+
} // namespace gandiva
diff --git a/cpp/src/gandiva/codegen/configuration.h b/cpp/src/gandiva/codegen/configuration.h
index 73d9a66ac7986..978cc6282aa5c 100644
--- a/cpp/src/gandiva/codegen/configuration.h
+++ b/cpp/src/gandiva/codegen/configuration.h
@@ -24,6 +24,7 @@
namespace gandiva {
extern const char kByteCodeFilePath[];
+extern const char kHelperLibFilePath[];
class ConfigurationBuilder;
/// \brief runtime config for gandiva
@@ -32,17 +33,23 @@ class ConfigurationBuilder;
/// at run time.
class Configuration {
public:
- const std::string &byte_code_file_path() const { return byte_code_file_path_; }
friend class ConfigurationBuilder;
+
+ const std::string &byte_code_file_path() const { return byte_code_file_path_; }
+ const std::string &helper_lib_file_path() const { return helper_lib_file_path_; }
+
std::size_t Hash() const;
bool operator==(const Configuration &other) const;
bool operator!=(const Configuration &other) const;
private:
- explicit Configuration(const std::string byte_code_file_path)
- : byte_code_file_path_(byte_code_file_path) {}
+ explicit Configuration(const std::string &byte_code_file_path,
+ const std::string &helper_lib_file_path)
+ : byte_code_file_path_(byte_code_file_path),
+ helper_lib_file_path_(helper_lib_file_path) {}
const std::string byte_code_file_path_;
+ const std::string helper_lib_file_path_;
};
/// \brief configuration builder for gandiva
@@ -51,15 +58,24 @@ class Configuration {
/// to override specific values and build a custom instance
class ConfigurationBuilder {
public:
- ConfigurationBuilder() : byte_code_file_path_(kByteCodeFilePath) {}
+ ConfigurationBuilder()
+ : byte_code_file_path_(kByteCodeFilePath),
+ helper_lib_file_path_(kHelperLibFilePath) {}
ConfigurationBuilder &set_byte_code_file_path(const std::string &byte_code_file_path) {
byte_code_file_path_ = byte_code_file_path;
return *this;
}
+ ConfigurationBuilder &set_helper_lib_file_path(
+ const std::string &helper_lib_file_path) {
+ helper_lib_file_path_ = helper_lib_file_path;
+ return *this;
+ }
+
std::shared_ptr build() {
- std::shared_ptr configuration(new Configuration(byte_code_file_path_));
+ std::shared_ptr configuration(
+ new Configuration(byte_code_file_path_, helper_lib_file_path_));
return configuration;
}
@@ -69,9 +85,11 @@ class ConfigurationBuilder {
private:
std::string byte_code_file_path_;
+ std::string helper_lib_file_path_;
static std::shared_ptr InitDefaultConfig() {
- std::shared_ptr configuration(new Configuration(kByteCodeFilePath));
+ std::shared_ptr configuration(
+ new Configuration(kByteCodeFilePath, kHelperLibFilePath));
return configuration;
}
diff --git a/cpp/src/gandiva/codegen/engine.cc b/cpp/src/gandiva/codegen/engine.cc
index 58316fe4b4417..29748a3455f75 100644
--- a/cpp/src/gandiva/codegen/engine.cc
+++ b/cpp/src/gandiva/codegen/engine.cc
@@ -39,9 +39,12 @@
namespace gandiva {
-bool Engine::init_once_done_ = false;
std::once_flag init_once_flag;
+bool Engine::init_once_done_ = false;
+std::set Engine::loaded_libs_ = {};
+std::mutex Engine::mtx_;
+
// One-time initializations.
void Engine::InitOnce() {
DCHECK_EQ(init_once_done_, false);
@@ -78,12 +81,35 @@ Status Engine::Make(std::shared_ptr config,
return Status::CodeGenError(engine_obj->llvm_error_);
}
- Status result = engine_obj->LoadPreCompiledIRFiles(config->byte_code_file_path());
- GANDIVA_RETURN_NOT_OK(result);
+ auto status = engine_obj->LoadPreCompiledHelperLibs(config->helper_lib_file_path());
+ GANDIVA_RETURN_NOT_OK(status);
+
+ status = engine_obj->LoadPreCompiledIRFiles(config->byte_code_file_path());
+ GANDIVA_RETURN_NOT_OK(status);
+
*engine = std::move(engine_obj);
return Status::OK();
}
+Status Engine::LoadPreCompiledHelperLibs(const std::string &file_path) {
+ int err = 0;
+
+ mtx_.lock();
+ // Load each so lib only once.
+ if (loaded_libs_.find(file_path) == loaded_libs_.end()) {
+ err = llvm::sys::DynamicLibrary::LoadLibraryPermanently(file_path.c_str());
+ if (!err) {
+ loaded_libs_.insert(file_path);
+ }
+ }
+ mtx_.unlock();
+
+ return (err == 0)
+ ? Status::OK()
+ : Status::CodeGenError("loading precompiled native file " + file_path +
+ " failed with error " + std::to_string(err));
+}
+
// Handling for pre-compiled IR libraries.
Status Engine::LoadPreCompiledIRFiles(const std::string &byte_code_file_path) {
/// Read from file into memory buffer.
diff --git a/cpp/src/gandiva/codegen/engine.h b/cpp/src/gandiva/codegen/engine.h
index 2a87f740cccf7..2b539d6c3a2f5 100644
--- a/cpp/src/gandiva/codegen/engine.h
+++ b/cpp/src/gandiva/codegen/engine.h
@@ -16,6 +16,7 @@
#define GANDIVA_ENGINE_H
#include
+#include
#include
#include
@@ -67,7 +68,10 @@ class Engine {
llvm::ExecutionEngine &execution_engine() { return *execution_engine_.get(); }
- /// load pre-compiled modules and merge them into the main module.
+ /// load pre-compiled so libraries and merge them into the main module.
+ Status LoadPreCompiledHelperLibs(const std::string &helper_lib_file_path);
+
+ /// load pre-compiled IR modules and merge them into the main module.
Status LoadPreCompiledIRFiles(const std::string &byte_code_file_path);
/// dump the IR code to stdout with the prefix string.
@@ -83,6 +87,9 @@ class Engine {
bool module_finalized_;
std::string llvm_error_;
+
+ static std::set loaded_libs_;
+ static std::mutex mtx_;
};
} // namespace gandiva
diff --git a/cpp/src/gandiva/codegen/function_holder_stubs.cc b/cpp/src/gandiva/codegen/function_holder_stubs.cc
new file mode 100644
index 0000000000000..45d8c4b5f5563
--- /dev/null
+++ b/cpp/src/gandiva/codegen/function_holder_stubs.cc
@@ -0,0 +1,23 @@
+// Copyright (C) 2017-2018 Dremio Corporation
+//
+// 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 "codegen/like_holder.h"
+
+// Wrapper C functions for "like" to be invoked from LLVM.
+extern "C" bool like_utf8_utf8(int64_t ptr, const char *data, int data_len,
+ const char *pattern, int pattern_len) {
+ gandiva::helpers::LikeHolder *holder =
+ reinterpret_cast(ptr);
+ return (*holder)(std::string(data, data_len));
+}
diff --git a/cpp/src/gandiva/codegen/like_holder.cc b/cpp/src/gandiva/codegen/like_holder.cc
index 34bdc61722c71..6992b51efb6cd 100644
--- a/cpp/src/gandiva/codegen/like_holder.cc
+++ b/cpp/src/gandiva/codegen/like_holder.cc
@@ -20,6 +20,10 @@
namespace gandiva {
+#ifdef GDV_HELPERS
+namespace helpers {
+#endif
+
Status LikeHolder::Make(const FunctionNode &node, std::shared_ptr *holder) {
if (node.children().size() != 2) {
return Status::Invalid("'like' function requires two parameters");
@@ -49,11 +53,8 @@ Status LikeHolder::Make(const std::string &sql_pattern,
return Status::OK();
}
-// Wrapper C functions for "like" to be invoked from LLVM.
-extern "C" bool like_utf8_utf8(int64_t ptr, const char *data, int data_len,
- const char *pattern, int pattern_len) {
- LikeHolder *holder = reinterpret_cast(ptr);
- return (*holder)(std::string(data, data_len));
+#ifdef GDV_HELPERS
}
+#endif
} // namespace gandiva
diff --git a/cpp/src/gandiva/codegen/like_holder.h b/cpp/src/gandiva/codegen/like_holder.h
index 5875a3bcf64d4..51b14e42f0fc4 100644
--- a/cpp/src/gandiva/codegen/like_holder.h
+++ b/cpp/src/gandiva/codegen/like_holder.h
@@ -22,6 +22,10 @@
namespace gandiva {
+#ifdef GDV_HELPERS
+namespace helpers {
+#endif
+
/// Function Holder for SQL 'like'
class LikeHolder : public FunctionHolder {
public:
@@ -41,6 +45,10 @@ class LikeHolder : public FunctionHolder {
std::regex regex_; // compiled regex for the pattern
};
+#ifdef GDV_HELPERS
+}
+#endif
+
} // namespace gandiva
#endif // GANDIVA_LIKE_HOLDER_H
diff --git a/cpp/src/gandiva/codegen/llvm_generator_test.cc b/cpp/src/gandiva/codegen/llvm_generator_test.cc
index e397b250b59c5..701a148236fda 100644
--- a/cpp/src/gandiva/codegen/llvm_generator_test.cc
+++ b/cpp/src/gandiva/codegen/llvm_generator_test.cc
@@ -38,7 +38,7 @@ TEST_F(TestLLVMGenerator, VerifyPCFunctions) {
std::unique_ptr generator;
Status status =
LLVMGenerator::Make(ConfigurationBuilder::DefaultConfiguration(), &generator);
- EXPECT_TRUE(status.ok());
+ EXPECT_TRUE(status.ok()) << status.message();
llvm::Module *module = generator->module();
for (auto &iter : registry_) {
diff --git a/cpp/src/gandiva/codegen/regex_util.cc b/cpp/src/gandiva/codegen/regex_util.cc
index 8253cf072d4ad..f0cf7cbf6ed3b 100644
--- a/cpp/src/gandiva/codegen/regex_util.cc
+++ b/cpp/src/gandiva/codegen/regex_util.cc
@@ -16,13 +16,17 @@
namespace gandiva {
-/// Characters that are considered special by posix regex. These needs to be
-/// escaped with '\\'.
+#ifdef GDV_HELPERS
+namespace helpers {
+#endif
+
const std::set RegexUtil::posix_regex_specials_ = {
'[', ']', '(', ')', '|', '^', '-', '+', '*', '?', '{', '}', '$', '\\'};
Status RegexUtil::SqlLikePatternToPosix(const std::string &sql_pattern, char escape_char,
std::string &posix_pattern) {
+ /// Characters that are considered special by posix regex. These needs to be
+ /// escaped with '\\'.
posix_pattern.clear();
for (size_t idx = 0; idx < sql_pattern.size(); ++idx) {
auto cur = sql_pattern.at(idx);
@@ -61,4 +65,8 @@ Status RegexUtil::SqlLikePatternToPosix(const std::string &sql_pattern, char esc
return Status::OK();
}
+#ifdef GDV_HELPERS
+} // namespace helpers
+#endif
+
} // namespace gandiva
diff --git a/cpp/src/gandiva/codegen/regex_util.h b/cpp/src/gandiva/codegen/regex_util.h
index f3b405f3e21ab..698ffba629652 100644
--- a/cpp/src/gandiva/codegen/regex_util.h
+++ b/cpp/src/gandiva/codegen/regex_util.h
@@ -20,6 +20,10 @@
namespace gandiva {
+#ifdef GDV_HELPERS
+namespace helpers {
+#endif
+
/// \brief Utility class for converting sql patterns to posix patterns.
class RegexUtil {
public:
@@ -33,10 +37,13 @@ class RegexUtil {
}
private:
- // set of characters that std::regex treats as special.
static const std::set posix_regex_specials_;
};
+#ifdef GDV_HELPERS
+} // namespace helpers
+#endif
+
} // namespace gandiva
#endif // GANDIVA_REGEX_UTIL_H
diff --git a/cpp/src/gandiva/codegen/status.cc b/cpp/src/gandiva/codegen/status.cc
deleted file mode 100644
index be00e19dc8d8a..0000000000000
--- a/cpp/src/gandiva/codegen/status.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (C) 2017-2018 Dremio Corporation
-//
-// 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.
-
-// Adapted from Apache Arrow.
-
-#include "gandiva/status.h"
-
-#include
-#include
-
-namespace gandiva {
-
-Status::Status(StatusCode code, const std::string& msg) {
- assert(code != StatusCode::OK);
- state_ = new State;
- state_->code = code;
- state_->msg = msg;
-}
-
-void Status::CopyFrom(const Status& s) {
- delete state_;
- if (s.state_ == nullptr) {
- state_ = nullptr;
- } else {
- state_ = new State(*s.state_);
- }
-}
-
-std::string Status::CodeAsString() const {
- if (state_ == nullptr) {
- return "OK";
- }
-
- const char* type;
- switch (code()) {
- case StatusCode::OK:
- type = "OK";
- break;
- case StatusCode::CodeGenError:
- type = "CodeGenError";
- break;
- case StatusCode::Invalid:
- type = "Invalid";
- break;
- case StatusCode::ExpressionValidationError:
- type = "ExpressionValidationError";
- break;
- default:
- type = "Unknown";
- break;
- }
- return std::string(type);
-}
-
-void Status::MoveFrom(Status& s) {
- delete state_;
- state_ = s.state_;
- s.state_ = NULL;
-}
-
-std::string Status::ToString() const {
- std::string result(CodeAsString());
- if (state_ == NULL) {
- return result;
- }
- result += ": ";
- result += state_->msg;
- return result;
-}
-} // namespace gandiva
diff --git a/cpp/src/gandiva/codegen/status.h b/cpp/src/gandiva/codegen/status.h
index ba0c888653cf8..33c491dd57d1d 100644
--- a/cpp/src/gandiva/codegen/status.h
+++ b/cpp/src/gandiva/codegen/status.h
@@ -18,6 +18,7 @@
#ifndef GANDIVA_STATUS_H
#define GANDIVA_STATUS_H
+#include
#include
#include
#include
@@ -196,5 +197,64 @@ inline Status& Status::operator&=(Status&& s) {
return *this;
}
+inline Status::Status(StatusCode code, const std::string& msg) {
+ assert(code != StatusCode::OK);
+ state_ = new State;
+ state_->code = code;
+ state_->msg = msg;
+}
+
+inline void Status::CopyFrom(const Status& s) {
+ delete state_;
+ if (s.state_ == nullptr) {
+ state_ = nullptr;
+ } else {
+ state_ = new State(*s.state_);
+ }
+}
+
+inline std::string Status::CodeAsString() const {
+ if (state_ == nullptr) {
+ return "OK";
+ }
+
+ const char* type;
+ switch (code()) {
+ case StatusCode::OK:
+ type = "OK";
+ break;
+ case StatusCode::CodeGenError:
+ type = "CodeGenError";
+ break;
+ case StatusCode::Invalid:
+ type = "Invalid";
+ break;
+ case StatusCode::ExpressionValidationError:
+ type = "ExpressionValidationError";
+ break;
+ default:
+ type = "Unknown";
+ break;
+ }
+ return std::string(type);
+}
+
+inline void Status::MoveFrom(Status& s) {
+ delete state_;
+ state_ = s.state_;
+ s.state_ = NULL;
+}
+
+inline std::string Status::ToString() const {
+ std::string result(CodeAsString());
+ if (state_ == NULL) {
+ return result;
+ }
+ result += ": ";
+ result += state_->msg;
+ return result;
+}
+
} // namespace gandiva
+
#endif // GANDIVA_STATUS_H
diff --git a/cpp/src/gandiva/jni/config_builder.cc b/cpp/src/gandiva/jni/config_builder.cc
index c7fb5b5b0d3fc..5cc9c7ce1aa08 100644
--- a/cpp/src/gandiva/jni/config_builder.cc
+++ b/cpp/src/gandiva/jni/config_builder.cc
@@ -32,12 +32,20 @@ Java_org_apache_arrow_gandiva_evaluator_ConfigurationBuilder_buildConfigInstance
JNIEnv *env, jobject configuration) {
jstring byte_code_file_path =
(jstring)env->CallObjectMethod(configuration, byte_code_accessor_method_id_, 0);
+ jstring helper_library_file_path = (jstring)env->CallObjectMethod(
+ configuration, helper_library_accessor_method_id_, 0);
ConfigurationBuilder configuration_builder;
if (byte_code_file_path != nullptr) {
const char *byte_code_file_path_cpp = env->GetStringUTFChars(byte_code_file_path, 0);
configuration_builder.set_byte_code_file_path(byte_code_file_path_cpp);
env->ReleaseStringUTFChars(byte_code_file_path, byte_code_file_path_cpp);
}
+ if (helper_library_file_path != nullptr) {
+ const char *helper_library_file_path_cpp =
+ env->GetStringUTFChars(helper_library_file_path, 0);
+ configuration_builder.set_helper_lib_file_path(helper_library_file_path_cpp);
+ env->ReleaseStringUTFChars(helper_library_file_path, helper_library_file_path_cpp);
+ }
std::shared_ptr config = configuration_builder.build();
env->DeleteLocalRef(byte_code_file_path);
return ConfigHolder::MapInsert(config);
diff --git a/cpp/src/gandiva/jni/env_helper.h b/cpp/src/gandiva/jni/env_helper.h
index ba3093f2b2910..2fe96670284f0 100644
--- a/cpp/src/gandiva/jni/env_helper.h
+++ b/cpp/src/gandiva/jni/env_helper.h
@@ -21,5 +21,6 @@ extern jclass configuration_builder_class_;
// method references
extern jmethodID byte_code_accessor_method_id_;
+extern jmethodID helper_library_accessor_method_id_;
#endif // ENV_HELPER_H
diff --git a/cpp/src/gandiva/jni/jni_common.cc b/cpp/src/gandiva/jni/jni_common.cc
index 2e89dd816bfde..1abecf1b9b7b9 100644
--- a/cpp/src/gandiva/jni/jni_common.cc
+++ b/cpp/src/gandiva/jni/jni_common.cc
@@ -65,6 +65,7 @@ static jint JNI_VERSION = JNI_VERSION_1_6;
// extern refs - initialized for other modules.
jclass configuration_builder_class_;
jmethodID byte_code_accessor_method_id_;
+jmethodID helper_library_accessor_method_id_;
// refs for self.
static jclass gandiva_exception_;
@@ -93,6 +94,10 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved) {
const char return_type[] = "()Ljava/lang/String;";
byte_code_accessor_method_id_ =
env->GetMethodID(configuration_builder_class_, method_name, return_type);
+
+ const char helper_method_name[] = "getHelperLibraryFilePath";
+ helper_library_accessor_method_id_ =
+ env->GetMethodID(configuration_builder_class_, helper_method_name, return_type);
env->ExceptionDescribe();
return JNI_VERSION;