You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by we...@apache.org on 2019/02/01 05:05:06 UTC
[arrow] branch master updated: ARROW-3846: [Gandiva][C++] Build
Gandiva C++ libraries and get unit tests passing on Windows
This is an automated email from the ASF dual-hosted git repository.
wesm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/master by this push:
new 48de821 ARROW-3846: [Gandiva][C++] Build Gandiva C++ libraries and get unit tests passing on Windows
48de821 is described below
commit 48de821ea79bdf4d0480a2f6b377300ddc5bbd9a
Author: Wes McKinney <we...@apache.org>
AuthorDate: Thu Jan 31 23:04:59 2019 -0600
ARROW-3846: [Gandiva][C++] Build Gandiva C++ libraries and get unit tests passing on Windows
The tests pass cleanly for me on Windows with these changes. Can't say this was the most enjoyable project. I will fix up the CI but wanted to get eyes on the changes in case anything looks undesirable
Some notes
* This requires that LLVM was built with CMake, which is not true
of the Windows installers from llvm.org. It works for me if I
`conda install llvmdev=6.0.1 clangdev=6.0.1`
* I had to suppress a ton of compiler warnings that seem to be
coming from the LLVM headers. see gandiva/llvm_includes.h
* Unix targets are still using strptime for date parsing. We
might want to use `arrow/vendored/date.h` on all platforms
unless there is some significant performance difference
* This doesn't build in Appveyor yet. I wanted to wait to see which
builds folks think we should add this too (build times will go up
because installing llvmdev/clangdev will be time consuming)
* Python or other bindings will have to be investigated in a separate patch
Author: Wes McKinney <we...@apache.org>
Closes #3295 from wesm/gandiva-windows and squashes the following commits:
1fb56714 <Wes McKinney> Add missing file
1e0fdbc8 <Wes McKinney> Revert Flatbuffers changes that are causing CI flakiness
5fb78bc4 <Wes McKinney> Bump flatbuffers version to v1.10.0
707e9d9f <Wes McKinney> Visibility fixes for windows with the cast_time changes
fac669e0 <Wes McKinney> Rebase, remove failing unit test
f3b60bf3 <Wes McKinney> Some basic fixes to build system, clang IR generation, suppress endogenous LLVM warnings with MSVC 2017
---
appveyor.yml | 1 +
ci/appveyor-cpp-build.bat | 7 +++
ci/cpp-msvc-build-main.bat | 1 +
cpp/CMakeLists.txt | 6 ++-
cpp/cmake_modules/FindProtobuf.cmake | 9 ++--
cpp/cmake_modules/FindRE2.cmake | 8 ++-
cpp/cmake_modules/ThirdpartyToolchain.cmake | 24 ++++-----
cpp/src/arrow/util/bit-util-test.cc | 24 +++++++++
cpp/src/arrow/util/bit-util.h | 51 ++++++++++++++++++
cpp/src/arrow/util/parsing.h | 2 +-
.../vendored/datetime.h} | 20 ++-----
cpp/src/arrow/vendored/datetime/ios.h | 4 +-
cpp/src/arrow/vendored/datetime/tz.cpp | 3 ++
.../vendored/datetime/visibility.h} | 25 +++------
cpp/src/gandiva/CMakeLists.txt | 23 +++++++-
cpp/src/gandiva/annotator.h | 3 +-
cpp/src/gandiva/bitmap_accumulator.h | 3 +-
cpp/src/gandiva/bitmap_accumulator_test.cc | 16 +++---
cpp/src/gandiva/cast_time.cc | 5 +-
cpp/src/gandiva/compiled_expr.h | 2 +-
cpp/src/gandiva/configuration.h | 11 ++--
cpp/src/gandiva/date_utils.cc | 3 +-
cpp/src/gandiva/date_utils.h | 61 +++++++++++++++++++++-
cpp/src/gandiva/decimal_type_util.cc | 5 --
cpp/src/gandiva/decimal_type_util.h | 26 +++++----
cpp/src/gandiva/dex.h | 35 +++++++------
cpp/src/gandiva/dex_visitor.h | 5 +-
cpp/src/gandiva/engine.cc | 14 +++++
cpp/src/gandiva/engine.h | 9 ++--
cpp/src/gandiva/expr_decomposer.cc | 6 +--
cpp/src/gandiva/expr_decomposer.h | 8 ++-
cpp/src/gandiva/expression.h | 3 +-
cpp/src/gandiva/expression_registry.h | 5 +-
cpp/src/gandiva/filter.cc | 2 +
cpp/src/gandiva/filter.h | 12 ++---
cpp/src/gandiva/func_descriptor.h | 3 +-
cpp/src/gandiva/function_holder.h | 4 +-
cpp/src/gandiva/function_registry.h | 3 +-
cpp/src/gandiva/function_signature.h | 3 +-
cpp/src/gandiva/like_holder.h | 5 +-
cpp/src/gandiva/llvm_generator.h | 3 +-
.../gandiva/{function_holder.h => llvm_includes.h} | 32 ++++++------
cpp/src/gandiva/llvm_types.h | 6 +--
cpp/src/gandiva/lvalue.h | 7 +--
cpp/src/gandiva/native_function.h | 3 +-
cpp/src/gandiva/node.h | 13 ++---
cpp/src/gandiva/node_visitor.h | 3 +-
cpp/src/gandiva/precompiled/CMakeLists.txt | 33 +++++++++---
.../gandiva/precompiled/epoch_time_point_test.cc | 37 +++++++------
cpp/src/gandiva/precompiled/extended_math_ops.cc | 38 +++++++++-----
.../{function_holder.h => precompiled/testing.h} | 26 ++++-----
cpp/src/gandiva/precompiled/time_test.cc | 7 +--
cpp/src/gandiva/projector.cc | 2 +
cpp/src/gandiva/projector.h | 12 +++--
cpp/src/gandiva/regex_util.h | 3 +-
cpp/src/gandiva/selection_vector.cc | 14 ++++-
cpp/src/gandiva/selection_vector.h | 3 +-
cpp/src/gandiva/tests/date_time_test.cc | 2 +-
cpp/src/gandiva/tests/projector_test.cc | 10 ++--
cpp/src/gandiva/to_date_holder.cc | 21 +++-----
cpp/src/gandiva/to_date_holder.h | 3 +-
cpp/src/gandiva/to_date_holder_test.cc | 57 ++++++++++++--------
cpp/src/gandiva/tree_expr_builder.h | 3 +-
cpp/src/gandiva/value_validity_pair.h | 3 +-
.../gandiva/{function_holder.h => visibility.h} | 41 ++++++++++-----
cpp/thirdparty/versions.txt | 2 +-
66 files changed, 550 insertions(+), 294 deletions(-)
diff --git a/appveyor.yml b/appveyor.yml
index dbf13ff..d955484 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -47,6 +47,7 @@ matrix:
environment:
global:
USE_CLCACHE: true
+ ARROW_BUILD_GANDIVA: "OFF"
PYTHON: "3.6"
ARCH: "64"
diff --git a/ci/appveyor-cpp-build.bat b/ci/appveyor-cpp-build.bat
index 78f5e41..f95b88e 100644
--- a/ci/appveyor-cpp-build.bat
+++ b/ci/appveyor-cpp-build.bat
@@ -104,6 +104,13 @@ conda create -n arrow -q -y -c conda-forge ^
call activate arrow
+set ARROW_LLVM_VERSION=6.0.1
+
+if "%ARROW_BUILD_GANDIVA%" == "ON" (
+ @rem Install llvmdev in the toolchain if building gandiva.dll
+ conda install -q -y llvmdev=%ARROW_LLVM_VERSION% || exit /B
+)
+
@rem Use Boost from Anaconda
set BOOST_ROOT=%CONDA_PREFIX%\Library
set BOOST_LIBRARYDIR=%CONDA_PREFIX%\Library\lib
diff --git a/ci/cpp-msvc-build-main.bat b/ci/cpp-msvc-build-main.bat
index ccd64e3..779af15 100644
--- a/ci/cpp-msvc-build-main.bat
+++ b/ci/cpp-msvc-build-main.bat
@@ -55,6 +55,7 @@ cmake -G "%GENERATOR%" %CMAKE_ARGS% ^
-DARROW_VERBOSE_THIRDPARTY_BUILD=ON ^
-DARROW_CXXFLAGS="%ARROW_CXXFLAGS%" ^
-DCMAKE_CXX_FLAGS_RELEASE="/MD %CMAKE_CXX_FLAGS_RELEASE%" ^
+ -DARROW_GANDIVA=%ARROW_BUILD_GANDIVA% ^
-DARROW_PARQUET=ON ^
-DARROW_PYTHON=ON ^
.. || exit /B
diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
index 3ec430e..9cdbe7d 100644
--- a/cpp/CMakeLists.txt
+++ b/cpp/CMakeLists.txt
@@ -309,8 +309,12 @@ Note that this requires linking Boost statically"
set(BROTLI_MSVC_STATIC_LIB_SUFFIX "-static" CACHE STRING
"Brotli static lib suffix used on Windows with MSVC (default -static)")
+ set(PROTOBUF_MSVC_STATIC_LIB_SUFFIX "" CACHE STRING
+ "Protobuf static lib suffix used on Windows with MSVC (default is empty string)")
+ set(RE2_MSVC_STATIC_LIB_SUFFIX "_static" CACHE STRING
+ "re2 static lib suffix used on Windows with MSVC (default is _static)")
set(SNAPPY_MSVC_STATIC_LIB_SUFFIX "_static" CACHE STRING
- "Snappy static lib suffix used on Windows with MSVC (default is empty string)")
+ "Snappy static lib suffix used on Windows with MSVC (default is _static)")
set(LZ4_MSVC_STATIC_LIB_SUFFIX "_static" CACHE STRING
"Lz4 static lib suffix used on Windows with MSVC (default _static)")
set(ZSTD_MSVC_STATIC_LIB_SUFFIX "_static" CACHE STRING
diff --git a/cpp/cmake_modules/FindProtobuf.cmake b/cpp/cmake_modules/FindProtobuf.cmake
index e4a87f4..f53f48d 100644
--- a/cpp/cmake_modules/FindProtobuf.cmake
+++ b/cpp/cmake_modules/FindProtobuf.cmake
@@ -44,12 +44,12 @@ if (EXISTS "${_protobuf_path}/lib/${CMAKE_LIBRARY_ARCHITECTURE}")
set (lib_dirs "lib/${CMAKE_LIBRARY_ARCHITECTURE}" ${lib_dirs})
endif ()
-find_library (PROTOBUF_LIBRARY NAMES protobuf PATHS
+find_library (PROTOBUF_LIBRARY NAMES protobuf libprotobuf PATHS
${_protobuf_path}
NO_DEFAULT_PATH
PATH_SUFFIXES ${lib_dirs})
-find_library (PROTOC_LIBRARY NAMES protoc PATHS
+find_library (PROTOC_LIBRARY NAMES protoc libprotoc PATHS
${_protobuf_path}
NO_DEFAULT_PATH
PATH_SUFFIXES ${lib_dirs})
@@ -66,7 +66,7 @@ if (PROTOBUF_INCLUDE_DIR AND PROTOBUF_LIBRARY AND PROTOC_LIBRARY AND PROTOBUF_EX
get_filename_component (PROTOBUF_LIBS ${PROTOBUF_LIBRARY} PATH)
set (PROTOBUF_LIB_NAME protobuf)
set (PROTOC_LIB_NAME protoc)
- set (PROTOBUF_STATIC_LIB ${PROTOBUF_LIBS}/${CMAKE_STATIC_LIBRARY_PREFIX}${PROTOBUF_LIB_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX})
+ set (PROTOBUF_STATIC_LIB ${PROTOBUF_LIBS}/${CMAKE_STATIC_LIBRARY_PREFIX}${PROTOBUF_LIB_NAME}${PROTOBUF_MSVC_STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX})
set (PROTOC_STATIC_LIB ${PROTOBUF_LIBS}/${CMAKE_STATIC_LIBRARY_PREFIX}${PROTOC_LIB_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX})
else ()
set (PROTOBUF_FOUND FALSE)
@@ -81,7 +81,7 @@ if (PROTOBUF_FOUND)
message (STATUS "Found the Protoc executable: ${PROTOBUF_EXECUTABLE}")
else()
if (_protobuf_path)
- set (PROTOBUF_ERR_MSG "Could not find Protobuf. Looked in ${_protobuf_path}.")
+ set (PROTOBUF_ERR_MSG "Could not find Protobuf. Looked in ${_protobuf_path}")
else ()
set (PROTOBUF_ERR_MSG "Could not find Protobuf in system search paths.")
endif()
@@ -100,4 +100,3 @@ mark_as_advanced (
PROTOBUF_STATIC_LIB
PROTOC_STATIC_LIB
)
-
diff --git a/cpp/cmake_modules/FindRE2.cmake b/cpp/cmake_modules/FindRE2.cmake
index ae0f182..51b093f 100644
--- a/cpp/cmake_modules/FindRE2.cmake
+++ b/cpp/cmake_modules/FindRE2.cmake
@@ -45,14 +45,18 @@ if (EXISTS "${_re2_path}/lib/${CMAKE_LIBRARY_ARCHITECTURE}")
set (lib_dirs "lib/${CMAKE_LIBRARY_ARCHITECTURE}" ${lib_dirs})
endif ()
-find_library(RE2_STATIC_LIB NAMES libre2${CMAKE_STATIC_LIBRARY_SUFFIX}
+set(RE2_LIB_NAME re2)
+set(RE2_STATIC_LIB_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}${RE2_LIB_NAME}${RE2_MSVC_STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX})
+set(RE2_SHARED_LIB_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${RE2_LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX})
+
+find_library(RE2_STATIC_LIB NAMES ${RE2_STATIC_LIB_NAME}
PATHS ${_re2_path}
NO_DEFAULT_PATH
PATH_SUFFIXES ${lib_dirs}
DOC "Google's re2 regex static library"
)
-find_library(RE2_SHARED_LIB NAMES libre2${CMAKE_SHARED_LIBRARY_SUFFIX}
+find_library(RE2_SHARED_LIB NAMES ${RE2_SHARED_LIB_NAME}
PATHS ${_re2_path}
NO_DEFAULT_PATH
PATH_SUFFIXES ${lib_dirs}
diff --git a/cpp/cmake_modules/ThirdpartyToolchain.cmake b/cpp/cmake_modules/ThirdpartyToolchain.cmake
index ce5073f..fedeed4 100644
--- a/cpp/cmake_modules/ThirdpartyToolchain.cmake
+++ b/cpp/cmake_modules/ThirdpartyToolchain.cmake
@@ -769,24 +769,22 @@ if (ARROW_WITH_RAPIDJSON)
## Flatbuffers
if("${FLATBUFFERS_HOME}" STREQUAL "")
- set(FLATBUFFERS_CMAKE_CXX_FLAGS ${EP_CXX_FLAGS})
set(FLATBUFFERS_PREFIX "${THIRDPARTY_PREFIX}")
-
if (MSVC)
- set(FLATBUFFERS_CMAKE_CXX_FLAGS "/EHsc")
+ set(FLATBUFFERS_CMAKE_CXX_FLAGS /EHsc)
+ else()
+ set(FLATBUFFERS_CMAKE_CXX_FLAGS -fPIC)
endif()
-
- # RELEASE build is required for `flatc` to be installed.
- set(FLATBUFFERS_BUILD_TYPE RELEASE)
- set(FLATBUFFERS_CMAKE_ARGS ${EP_COMMON_CMAKE_ARGS}
- -DCMAKE_BUILD_TYPE=${FLATBUFFERS_BUILD_TYPE}
- -DCMAKE_INSTALL_PREFIX=${FLATBUFFERS_PREFIX}
- -DCMAKE_CXX_FLAGS=${FLATBUFFERS_CMAKE_CXX_FLAGS}
- -DFLATBUFFERS_BUILD_TESTS=OFF)
-
+ # We always need to do release builds, otherwise flatc will not be installed.
ExternalProject_Add(flatbuffers_ep
URL ${FLATBUFFERS_SOURCE_URL}
- CMAKE_ARGS ${FLATBUFFERS_CMAKE_ARGS}
+ CMAKE_ARGS
+ "-DCMAKE_CXX_FLAGS=${FLATBUFFERS_CMAKE_CXX_FLAGS}"
+ "-DCMAKE_INSTALL_PREFIX:PATH=${FLATBUFFERS_PREFIX}"
+ "-DFLATBUFFERS_BUILD_TESTS=OFF"
+ "-DCMAKE_BUILD_TYPE=RELEASE"
+ "-DCMAKE_CXX_FLAGS_${UPPERCASE_BUILD_TYPE}=${EP_CXX_FLAGS}"
+ "-DCMAKE_C_FLAGS_${UPPERCASE_BUILD_TYPE}=${EP_C_FLAGS}"
${EP_LOG_OPTIONS})
set(FLATBUFFERS_INCLUDE_DIR "${FLATBUFFERS_PREFIX}/include")
diff --git a/cpp/src/arrow/util/bit-util-test.cc b/cpp/src/arrow/util/bit-util-test.cc
index 6709ae4..6bcb6ea 100644
--- a/cpp/src/arrow/util/bit-util-test.cc
+++ b/cpp/src/arrow/util/bit-util-test.cc
@@ -788,6 +788,30 @@ TEST(BitUtil, CountLeadingZeros) {
EXPECT_EQ(BitUtil::CountLeadingZeros(U64(ULLONG_MAX)), 0);
}
+TEST(BitUtil, CountTrailingZeros) {
+ EXPECT_EQ(BitUtil::CountTrailingZeros(U32(0)), 32);
+ EXPECT_EQ(BitUtil::CountTrailingZeros(U32(1) << 31), 31);
+ EXPECT_EQ(BitUtil::CountTrailingZeros(U32(1) << 30), 30);
+ EXPECT_EQ(BitUtil::CountTrailingZeros(U32(1) << 29), 29);
+ EXPECT_EQ(BitUtil::CountTrailingZeros(U32(1) << 28), 28);
+ EXPECT_EQ(BitUtil::CountTrailingZeros(U32(8)), 3);
+ EXPECT_EQ(BitUtil::CountTrailingZeros(U32(4)), 2);
+ EXPECT_EQ(BitUtil::CountTrailingZeros(U32(2)), 1);
+ EXPECT_EQ(BitUtil::CountTrailingZeros(U32(1)), 0);
+ EXPECT_EQ(BitUtil::CountTrailingZeros(U32(ULONG_MAX)), 0);
+
+ EXPECT_EQ(BitUtil::CountTrailingZeros(U64(0)), 64);
+ EXPECT_EQ(BitUtil::CountTrailingZeros(U64(1) << 63), 63);
+ EXPECT_EQ(BitUtil::CountTrailingZeros(U64(1) << 62), 62);
+ EXPECT_EQ(BitUtil::CountTrailingZeros(U64(1) << 61), 61);
+ EXPECT_EQ(BitUtil::CountTrailingZeros(U64(1) << 60), 60);
+ EXPECT_EQ(BitUtil::CountTrailingZeros(U64(8)), 3);
+ EXPECT_EQ(BitUtil::CountTrailingZeros(U64(4)), 2);
+ EXPECT_EQ(BitUtil::CountTrailingZeros(U64(2)), 1);
+ EXPECT_EQ(BitUtil::CountTrailingZeros(U64(1)), 0);
+ EXPECT_EQ(BitUtil::CountTrailingZeros(U64(ULLONG_MAX)), 0);
+}
+
#undef U32
#undef U64
diff --git a/cpp/src/arrow/util/bit-util.h b/cpp/src/arrow/util/bit-util.h
index 8e6979f..bfdb44f 100644
--- a/cpp/src/arrow/util/bit-util.h
+++ b/cpp/src/arrow/util/bit-util.h
@@ -45,6 +45,7 @@
#if defined(_MSC_VER)
#include <intrin.h>
#pragma intrinsic(_BitScanReverse)
+#pragma intrinsic(_BitScanForward)
#define ARROW_BYTE_SWAP64 _byteswap_uint64
#define ARROW_BYTE_SWAP32 _byteswap_ulong
#else
@@ -182,6 +183,56 @@ static inline int CountLeadingZeros(uint64_t value) {
#endif
}
+static inline int CountTrailingZeros(uint32_t value) {
+#if defined(__clang__) || defined(__GNUC__)
+ if (value == 0) return 32;
+ return static_cast<int>(__builtin_ctzl(value));
+#elif defined(_MSC_VER)
+ unsigned long index; // NOLINT
+ if (_BitScanForward(&index, value)) {
+ return static_cast<int>(index);
+ } else {
+ return 32;
+ }
+#else
+ int bitpos = 0;
+ if (value) {
+ while (value & 1 == 0) {
+ value >>= 1;
+ ++bitpos;
+ }
+ } else {
+ bitpos = 32;
+ }
+ return bitpos;
+#endif
+}
+
+static inline int CountTrailingZeros(uint64_t value) {
+#if defined(__clang__) || defined(__GNUC__)
+ if (value == 0) return 64;
+ return static_cast<int>(__builtin_ctzll(value));
+#elif defined(_MSC_VER)
+ unsigned long index; // NOLINT
+ if (_BitScanForward64(&index, value)) {
+ return static_cast<int>(index);
+ } else {
+ return 64;
+ }
+#else
+ int bitpos = 0;
+ if (value) {
+ while (value & 1 == 0) {
+ value >>= 1;
+ ++bitpos;
+ }
+ } else {
+ bitpos = 64;
+ }
+ return bitpos;
+#endif
+}
+
// Returns the minimum number of bits needed to represent an unsigned value
static inline int NumRequiredBits(uint64_t x) { return 64 - CountLeadingZeros(x); }
diff --git a/cpp/src/arrow/util/parsing.h b/cpp/src/arrow/util/parsing.h
index 0d8eb97..fc6ca04 100644
--- a/cpp/src/arrow/util/parsing.h
+++ b/cpp/src/arrow/util/parsing.h
@@ -34,7 +34,7 @@
#include "arrow/type.h"
#include "arrow/type_traits.h"
#include "arrow/util/checked_cast.h"
-#include "arrow/vendored/datetime/date.h"
+#include "arrow/vendored/datetime.h"
namespace arrow {
namespace internal {
diff --git a/cpp/src/gandiva/function_holder.h b/cpp/src/arrow/vendored/datetime.h
similarity index 68%
copy from cpp/src/gandiva/function_holder.h
copy to cpp/src/arrow/vendored/datetime.h
index 4d007d1..424313a 100644
--- a/cpp/src/gandiva/function_holder.h
+++ b/cpp/src/arrow/vendored/datetime.h
@@ -15,21 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-#ifndef GANDIVA_FUNCTION_HOLDER_H
-#define GANDIVA_FUNCTION_HOLDER_H
+#pragma once
-#include <memory>
-
-namespace gandiva {
-
-/// Holder for a function that can be invoked from LLVM.
-class FunctionHolder {
- public:
- virtual ~FunctionHolder() = default;
-};
-
-using FunctionHolderPtr = std::shared_ptr<FunctionHolder>;
-
-} // namespace gandiva
-
-#endif // GANDIVA_FUNCTION_HOLDER_H
+#include "arrow/vendored/datetime/date.h"
+#include "arrow/vendored/datetime/tz.h"
diff --git a/cpp/src/arrow/vendored/datetime/ios.h b/cpp/src/arrow/vendored/datetime/ios.h
index ec8342f..23dc167 100644
--- a/cpp/src/arrow/vendored/datetime/ios.h
+++ b/cpp/src/arrow/vendored/datetime/ios.h
@@ -40,10 +40,10 @@
{
namespace iOSUtils
{
-
+
std::string get_tzdata_path();
std::string get_current_timezone();
-
+
} // namespace iOSUtils
} // namespace date
} // namespace util
diff --git a/cpp/src/arrow/vendored/datetime/tz.cpp b/cpp/src/arrow/vendored/datetime/tz.cpp
index ffea8d6..e05423e 100644
--- a/cpp/src/arrow/vendored/datetime/tz.cpp
+++ b/cpp/src/arrow/vendored/datetime/tz.cpp
@@ -30,6 +30,9 @@
// been invented (that would involve another several millennia of evolution).
// We did not mean to shout.
+// wesm: This is required so that symbols are properly exported from the DLL
+#include "visibility.h"
+
#ifdef _WIN32
// windows.h will be included directly and indirectly (e.g. by curl).
// We need to define these macros to prevent windows.h bringing in
diff --git a/cpp/src/gandiva/function_holder.h b/cpp/src/arrow/vendored/datetime/visibility.h
similarity index 68%
copy from cpp/src/gandiva/function_holder.h
copy to cpp/src/arrow/vendored/datetime/visibility.h
index 4d007d1..ae03123 100644
--- a/cpp/src/gandiva/function_holder.h
+++ b/cpp/src/arrow/vendored/datetime/visibility.h
@@ -15,21 +15,12 @@
// specific language governing permissions and limitations
// under the License.
-#ifndef GANDIVA_FUNCTION_HOLDER_H
-#define GANDIVA_FUNCTION_HOLDER_H
+#pragma once
-#include <memory>
-
-namespace gandiva {
-
-/// Holder for a function that can be invoked from LLVM.
-class FunctionHolder {
- public:
- virtual ~FunctionHolder() = default;
-};
-
-using FunctionHolderPtr = std::shared_ptr<FunctionHolder>;
-
-} // namespace gandiva
-
-#endif // GANDIVA_FUNCTION_HOLDER_H
+#if defined(ARROW_STATIC)
+// intentially empty
+#elif defined(ARROW_EXPORTING)
+#define DATE_BUILD_DLL
+#else
+#define DATE_USE_DLL
+#endif
diff --git a/cpp/src/gandiva/CMakeLists.txt b/cpp/src/gandiva/CMakeLists.txt
index 52784e7..d5f4364 100644
--- a/cpp/src/gandiva/CMakeLists.txt
+++ b/cpp/src/gandiva/CMakeLists.txt
@@ -32,8 +32,8 @@ set(GANDIVA_BC_INSTALL_DIR
${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/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_CURRENT_BINARY_DIR}/${GANDIVA_BC_FILE_NAME})
+set(GANDIVA_BC_INSTALL_PATH "${GANDIVA_BC_INSTALL_DIR}/${GANDIVA_BC_FILE_NAME}")
+set(GANDIVA_BC_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}/${GANDIVA_BC_FILE_NAME}")
install(FILES
${GANDIVA_BC_OUTPUT_PATH}
DESTINATION ${GANDIVA_BC_INSTALL_DIR})
@@ -95,16 +95,35 @@ if (ARROW_GANDIVA_STATIC_LIBSTDCPP
-static-libgcc)
endif()
+# if (MSVC)
+# # Symbols that need to be made public in gandiva.dll for LLVM IR
+# # compilation
+# set(MSVC_SYMBOL_EXPORTS _Init_thread_header)
+# foreach(SYMBOL ${MSVC_SYMBOL_EXPORTS})
+# set(GANDIVA_SHARED_LINK_FLAGS "${GANDIVA_SHARED_LINK_FLAGS} /EXPORT:${SYMBOL}")
+# endforeach()
+# endif()
+
ADD_ARROW_LIB(gandiva
SOURCES ${SRC_FILES}
OUTPUTS GANDIVA_LIBRARIES
DEPENDENCIES arrow_dependencies precompiled
EXTRA_INCLUDES
$<TARGET_PROPERTY:LLVM::LLVM_INTERFACE,INTERFACE_INCLUDE_DIRECTORIES>
+ SHARED_LINK_FLAGS ${GANDIVA_SHARED_LINK_FLAGS}
SHARED_LINK_LIBS arrow_shared
SHARED_PRIVATE_LINK_LIBS ${GANDIVA_SHARED_PRIVATE_LINK_LIBS}
STATIC_LINK_LIBS ${GANDIVA_STATIC_LINK_LIBS})
+foreach(LIB_TARGET ${GANDIVA_LIBRARIES})
+ target_compile_definitions(${LIB_TARGET}
+ PRIVATE GANDIVA_EXPORTING)
+endforeach()
+
+if (ARROW_BUILD_STATIC AND WIN32)
+ target_compile_definitions(gandiva_static PUBLIC GANDIVA_STATIC)
+endif()
+
add_dependencies(gandiva ${GANDIVA_LIBRARIES})
# install for gandiva
diff --git a/cpp/src/gandiva/annotator.h b/cpp/src/gandiva/annotator.h
index 6c2cd05..c0ddc02 100644
--- a/cpp/src/gandiva/annotator.h
+++ b/cpp/src/gandiva/annotator.h
@@ -27,12 +27,13 @@
#include "gandiva/eval_batch.h"
#include "gandiva/gandiva_aliases.h"
#include "gandiva/logging.h"
+#include "gandiva/visibility.h"
namespace gandiva {
/// \brief annotate the arrow fields in an expression, and use that
/// to convert the incoming arrow-format row batch to an EvalBatch.
-class Annotator {
+class GANDIVA_EXPORT Annotator {
public:
Annotator() : buffer_count_(0), local_bitmap_count_(0) {}
diff --git a/cpp/src/gandiva/bitmap_accumulator.h b/cpp/src/gandiva/bitmap_accumulator.h
index 157405d..15a2044 100644
--- a/cpp/src/gandiva/bitmap_accumulator.h
+++ b/cpp/src/gandiva/bitmap_accumulator.h
@@ -24,12 +24,13 @@
#include "gandiva/dex.h"
#include "gandiva/dex_visitor.h"
#include "gandiva/eval_batch.h"
+#include "gandiva/visibility.h"
namespace gandiva {
/// \brief Extract bitmap buffer from either the input/buffer vectors or the
/// local validity bitmap, and accumultes them to do the final computation.
-class BitMapAccumulator : public DexDefaultVisitor {
+class GANDIVA_EXPORT BitMapAccumulator : public DexDefaultVisitor {
public:
explicit BitMapAccumulator(const EvalBatch& eval_batch)
: eval_batch_(eval_batch), all_invalid_(false) {}
diff --git a/cpp/src/gandiva/bitmap_accumulator_test.cc b/cpp/src/gandiva/bitmap_accumulator_test.cc
index 53e8aac..51a8b09 100644
--- a/cpp/src/gandiva/bitmap_accumulator_test.cc
+++ b/cpp/src/gandiva/bitmap_accumulator_test.cc
@@ -21,24 +21,22 @@
#include <vector>
#include <gtest/gtest.h>
+
+#include "arrow/test-util.h"
+
#include "gandiva/dex.h"
namespace gandiva {
class TestBitMapAccumulator : public ::testing::Test {
protected:
- void FillBitMap(uint8_t* bmap, int nrecords);
+ void FillBitMap(uint8_t* bmap, uint32_t seed, int nrecords);
void ByteWiseIntersectBitMaps(uint8_t* dst, const std::vector<uint8_t*>& srcs,
int nrecords);
};
-void TestBitMapAccumulator::FillBitMap(uint8_t* bmap, int nbytes) {
- unsigned int cur = 0;
-
- for (int i = 0; i < nbytes; ++i) {
- rand_r(&cur);
- bmap[i] = static_cast<uint8_t>(cur % UINT8_MAX);
- }
+void TestBitMapAccumulator::FillBitMap(uint8_t* bmap, uint32_t seed, int nbytes) {
+ ::arrow::random_bytes(nbytes, seed, bmap);
}
void TestBitMapAccumulator::ByteWiseIntersectBitMaps(uint8_t* dst,
@@ -61,7 +59,7 @@ TEST_F(TestBitMapAccumulator, TestIntersectBitMaps) {
uint8_t expected_bitmap[length];
for (int i = 0; i < 4; i++) {
- FillBitMap(src_bitmaps[i], length);
+ FillBitMap(src_bitmaps[i], i, length);
}
for (int i = 0; i < 4; i++) {
diff --git a/cpp/src/gandiva/cast_time.cc b/cpp/src/gandiva/cast_time.cc
index ee3fd31..1d4293b 100644
--- a/cpp/src/gandiva/cast_time.cc
+++ b/cpp/src/gandiva/cast_time.cc
@@ -15,7 +15,10 @@
// specific language governing permissions and limitations
// under the License.
-#include "arrow/vendored/datetime/tz.h"
+#include <cstdint>
+
+#include "arrow/vendored/datetime.h"
+
#include "gandiva/precompiled/time_fields.h"
#ifndef GANDIVA_UNIT_TEST
diff --git a/cpp/src/gandiva/compiled_expr.h b/cpp/src/gandiva/compiled_expr.h
index 2f23971..b7799f1 100644
--- a/cpp/src/gandiva/compiled_expr.h
+++ b/cpp/src/gandiva/compiled_expr.h
@@ -18,7 +18,7 @@
#ifndef GANDIVA_COMPILED_EXPR_H
#define GANDIVA_COMPILED_EXPR_H
-#include <llvm/IR/IRBuilder.h>
+#include "gandiva/llvm_includes.h"
#include "gandiva/value_validity_pair.h"
namespace gandiva {
diff --git a/cpp/src/gandiva/configuration.h b/cpp/src/gandiva/configuration.h
index 04e2eed..480a95e 100644
--- a/cpp/src/gandiva/configuration.h
+++ b/cpp/src/gandiva/configuration.h
@@ -15,16 +15,18 @@
// specific language governing permissions and limitations
// under the License.
-#ifndef GANDIVA_CONFIGURATION_H
-#define GANDIVA_CONFIGURATION_H
+#pragma once
#include <memory>
#include <string>
#include "arrow/status.h"
+#include "gandiva/visibility.h"
+
namespace gandiva {
+GANDIVA_EXPORT
extern const char kByteCodeFilePath[];
class ConfigurationBuilder;
@@ -32,7 +34,7 @@ class ConfigurationBuilder;
///
/// It contains elements to customize gandiva execution
/// at run time.
-class Configuration {
+class GANDIVA_EXPORT Configuration {
public:
friend class ConfigurationBuilder;
@@ -53,7 +55,7 @@ class Configuration {
///
/// Provides a default configuration and convenience methods
/// to override specific values and build a custom instance
-class ConfigurationBuilder {
+class GANDIVA_EXPORT ConfigurationBuilder {
public:
ConfigurationBuilder() : byte_code_file_path_(kByteCodeFilePath) {}
@@ -83,4 +85,3 @@ class ConfigurationBuilder {
};
} // namespace gandiva
-#endif // GANDIVA_CONFIGURATION_H
diff --git a/cpp/src/gandiva/date_utils.cc b/cpp/src/gandiva/date_utils.cc
index 8a7e1f0..f0a80d3 100644
--- a/cpp/src/gandiva/date_utils.cc
+++ b/cpp/src/gandiva/date_utils.cc
@@ -16,6 +16,7 @@
// under the License.
#include <algorithm>
+#include <cstdint>
#include <memory>
#include <sstream>
#include <vector>
@@ -57,7 +58,7 @@ Status DateUtils::ToInternalFormat(const std::string& format,
std::stringstream buffer;
bool is_in_quoted_text = false;
- for (uint i = 0; i < format.length(); i++) {
+ for (size_t i = 0; i < format.size(); i++) {
char currentChar = format[i];
// logic before we append to the buffer
diff --git a/cpp/src/gandiva/date_utils.h b/cpp/src/gandiva/date_utils.h
index 64a150b..e87203b 100644
--- a/cpp/src/gandiva/date_utils.h
+++ b/cpp/src/gandiva/date_utils.h
@@ -23,12 +23,22 @@
#include <unordered_map>
#include <vector>
+#if defined(_MSC_VER)
+#include <ctime>
+#include <iomanip>
+#include <sstream>
+#endif
+
+#include "arrow/util/macros.h"
+#include "arrow/vendored/datetime.h"
+
#include "gandiva/arrow.h"
+#include "gandiva/visibility.h"
namespace gandiva {
/// \brief Utility class for converting sql date patterns to internal date patterns.
-class DateUtils {
+class GANDIVA_EXPORT DateUtils {
public:
static Status ToInternalFormat(const std::string& format,
std::shared_ptr<std::string>* internal_format);
@@ -47,6 +57,55 @@ class DateUtils {
static std::vector<std::string> GetExactMatches(const std::string& pattern);
};
+namespace internal {
+
+/// \brief Returns seconds since the UNIX epoch
+static inline bool ParseTimestamp(const char* buf, const char* format,
+ bool ignoreTimeInDay, int64_t* out) {
+#if defined(_MSC_VER)
+ static std::locale lc_all(setlocale(LC_ALL, NULLPTR));
+ std::istringstream stream(buf);
+ stream.imbue(lc_all);
+
+ // TODO: date::parse fails parsing when the hour value is 0.
+ // eg.1886-12-01 00:00:00
+ arrow::util::date::sys_seconds seconds;
+ if (ignoreTimeInDay) {
+ arrow::util::date::sys_days days;
+ stream >> arrow::util::date::parse(format, days);
+ if (stream.fail()) {
+ return false;
+ }
+ seconds = days;
+ } else {
+ stream >> arrow::util::date::parse(format, seconds);
+ if (stream.fail()) {
+ return false;
+ }
+ }
+ auto seconds_in_epoch = seconds.time_since_epoch().count();
+ *out = seconds_in_epoch;
+ return true;
+#else
+ struct tm result;
+ char* ret = strptime(buf, format, &result);
+ if (ret == NULLPTR) {
+ return false;
+ }
+ // ignore the time part
+ arrow::util::date::sys_seconds secs =
+ arrow::util::date::sys_days(arrow::util::date::year(result.tm_year + 1900) /
+ (result.tm_mon + 1) / result.tm_mday);
+ if (!ignoreTimeInDay) {
+ secs += (std::chrono::hours(result.tm_hour) + std::chrono::minutes(result.tm_min) +
+ std::chrono::seconds(result.tm_sec));
+ }
+ *out = secs.time_since_epoch().count();
+ return true;
+#endif
+}
+
+} // namespace internal
} // namespace gandiva
#endif // TO_DATE_HELPER_H
diff --git a/cpp/src/gandiva/decimal_type_util.cc b/cpp/src/gandiva/decimal_type_util.cc
index 2795e91..74c9326 100644
--- a/cpp/src/gandiva/decimal_type_util.cc
+++ b/cpp/src/gandiva/decimal_type_util.cc
@@ -20,11 +20,6 @@
namespace gandiva {
-constexpr int32_t DecimalTypeUtil::kMaxDecimal32Precision;
-constexpr int32_t DecimalTypeUtil::kMaxDecimal64Precision;
-constexpr int32_t DecimalTypeUtil::kMaxPrecision;
-
-constexpr int32_t DecimalTypeUtil::kMaxScale;
constexpr int32_t DecimalTypeUtil::kMinAdjustedScale;
#define DCHECK_TYPE(type) \
diff --git a/cpp/src/gandiva/decimal_type_util.h b/cpp/src/gandiva/decimal_type_util.h
index 2c095c1..aa3c255 100644
--- a/cpp/src/gandiva/decimal_type_util.h
+++ b/cpp/src/gandiva/decimal_type_util.h
@@ -24,12 +24,13 @@
#include <memory>
#include "gandiva/arrow.h"
+#include "gandiva/visibility.h"
namespace gandiva {
/// @brief Handles conversion of scale/precision for operations on decimal types.
/// TODO : do validations for all of these.
-class DecimalTypeUtil {
+class GANDIVA_EXPORT DecimalTypeUtil {
public:
enum Op {
kOpAdd,
@@ -65,7 +66,16 @@ class DecimalTypeUtil {
static Decimal128TypePtr MakeType(int32_t precision, int32_t scale);
private:
- static Decimal128TypePtr MakeAdjustedType(int32_t precision, int32_t scale);
+ // Reduce the scale if possible so that precision stays <= kMaxPrecision
+ static Decimal128TypePtr MakeAdjustedType(int32_t precision, int32_t scale) {
+ if (precision > kMaxPrecision) {
+ int32_t min_scale = std::min(scale, kMinAdjustedScale);
+ int32_t delta = precision - kMaxPrecision;
+ precision = kMaxPrecision;
+ scale = std::max(scale - delta, min_scale);
+ }
+ return MakeType(precision, scale);
+ }
};
inline Decimal128TypePtr DecimalTypeUtil::MakeType(int32_t precision, int32_t scale) {
@@ -73,18 +83,6 @@ inline Decimal128TypePtr DecimalTypeUtil::MakeType(int32_t precision, int32_t sc
arrow::decimal(precision, scale));
}
-// Reduce the scale if possible so that precision stays <= kMaxPrecision
-inline Decimal128TypePtr DecimalTypeUtil::MakeAdjustedType(int32_t precision,
- int32_t scale) {
- if (precision > kMaxPrecision) {
- int32_t min_scale = std::min(scale, kMinAdjustedScale);
- int32_t delta = precision - kMaxPrecision;
- precision = kMaxPrecision;
- scale = std::max(scale - delta, min_scale);
- }
- return MakeType(precision, scale);
-}
-
} // namespace gandiva
#endif // GANDIVA_DECIMAL_TYPE_SQL_H
diff --git a/cpp/src/gandiva/dex.h b/cpp/src/gandiva/dex.h
index afce44e..894d961 100644
--- a/cpp/src/gandiva/dex.h
+++ b/cpp/src/gandiva/dex.h
@@ -32,11 +32,12 @@
#include "gandiva/literal_holder.h"
#include "gandiva/native_function.h"
#include "gandiva/value_validity_pair.h"
+#include "gandiva/visibility.h"
namespace gandiva {
/// \brief Decomposed expression : the validity and value are separated.
-class Dex {
+class GANDIVA_EXPORT Dex {
public:
/// Derived classes should simply invoke the Visit api of the visitor.
virtual void Accept(DexVisitor& visitor) = 0;
@@ -44,7 +45,7 @@ class Dex {
};
/// Base class for other Vector related Dex.
-class VectorReadBaseDex : public Dex {
+class GANDIVA_EXPORT VectorReadBaseDex : public Dex {
public:
explicit VectorReadBaseDex(FieldDescriptorPtr field_desc) : field_desc_(field_desc) {}
@@ -59,7 +60,7 @@ class VectorReadBaseDex : public Dex {
};
/// validity component of a ValueVector
-class VectorReadValidityDex : public VectorReadBaseDex {
+class GANDIVA_EXPORT VectorReadValidityDex : public VectorReadBaseDex {
public:
explicit VectorReadValidityDex(FieldDescriptorPtr field_desc)
: VectorReadBaseDex(field_desc) {}
@@ -70,7 +71,7 @@ class VectorReadValidityDex : public VectorReadBaseDex {
};
/// value component of a fixed-len ValueVector
-class VectorReadFixedLenValueDex : public VectorReadBaseDex {
+class GANDIVA_EXPORT VectorReadFixedLenValueDex : public VectorReadBaseDex {
public:
explicit VectorReadFixedLenValueDex(FieldDescriptorPtr field_desc)
: VectorReadBaseDex(field_desc) {}
@@ -81,7 +82,7 @@ class VectorReadFixedLenValueDex : public VectorReadBaseDex {
};
/// value component of a variable-len ValueVector
-class VectorReadVarLenValueDex : public VectorReadBaseDex {
+class GANDIVA_EXPORT VectorReadVarLenValueDex : public VectorReadBaseDex {
public:
explicit VectorReadVarLenValueDex(FieldDescriptorPtr field_desc)
: VectorReadBaseDex(field_desc) {}
@@ -94,7 +95,7 @@ class VectorReadVarLenValueDex : public VectorReadBaseDex {
};
/// validity based on a local bitmap.
-class LocalBitMapValidityDex : public Dex {
+class GANDIVA_EXPORT LocalBitMapValidityDex : public Dex {
public:
explicit LocalBitMapValidityDex(int local_bitmap_idx)
: local_bitmap_idx_(local_bitmap_idx) {}
@@ -108,7 +109,7 @@ class LocalBitMapValidityDex : public Dex {
};
/// base function expression
-class FuncDex : public Dex {
+class GANDIVA_EXPORT FuncDex : public Dex {
public:
FuncDex(FuncDescriptorPtr func_descriptor, const NativeFunction* native_function,
FunctionHolderPtr function_holder, const ValueValidityPairVector& args)
@@ -134,7 +135,7 @@ class FuncDex : public Dex {
/// A function expression that only deals with non-null inputs, and generates non-null
/// outputs.
-class NonNullableFuncDex : public FuncDex {
+class GANDIVA_EXPORT NonNullableFuncDex : public FuncDex {
public:
NonNullableFuncDex(FuncDescriptorPtr func_descriptor,
const NativeFunction* native_function,
@@ -147,7 +148,7 @@ class NonNullableFuncDex : public FuncDex {
/// A function expression that deals with nullable inputs, but generates non-null
/// outputs.
-class NullableNeverFuncDex : public FuncDex {
+class GANDIVA_EXPORT NullableNeverFuncDex : public FuncDex {
public:
NullableNeverFuncDex(FuncDescriptorPtr func_descriptor,
const NativeFunction* native_function,
@@ -160,7 +161,7 @@ class NullableNeverFuncDex : public FuncDex {
/// A function expression that deals with nullable inputs, and
/// nullable outputs.
-class NullableInternalFuncDex : public FuncDex {
+class GANDIVA_EXPORT NullableInternalFuncDex : public FuncDex {
public:
NullableInternalFuncDex(FuncDescriptorPtr func_descriptor,
const NativeFunction* native_function,
@@ -179,17 +180,17 @@ class NullableInternalFuncDex : public FuncDex {
};
/// special validity type that always returns true.
-class TrueDex : public Dex {
+class GANDIVA_EXPORT TrueDex : public Dex {
void Accept(DexVisitor& visitor) override { visitor.Visit(*this); }
};
/// special validity type that always returns false.
-class FalseDex : public Dex {
+class GANDIVA_EXPORT FalseDex : public Dex {
void Accept(DexVisitor& visitor) override { visitor.Visit(*this); }
};
/// decomposed expression for a literal.
-class LiteralDex : public Dex {
+class GANDIVA_EXPORT LiteralDex : public Dex {
public:
LiteralDex(DataTypePtr type, const LiteralHolder& holder)
: type_(type), holder_(holder) {}
@@ -206,7 +207,7 @@ class LiteralDex : public Dex {
};
/// decomposed if-else expression.
-class IfDex : public Dex {
+class GANDIVA_EXPORT IfDex : public Dex {
public:
IfDex(ValueValidityPairPtr condition_vv, ValueValidityPairPtr then_vv,
ValueValidityPairPtr else_vv, DataTypePtr result_type, int local_bitmap_idx,
@@ -242,7 +243,7 @@ class IfDex : public Dex {
};
// decomposed boolean expression.
-class BooleanDex : public Dex {
+class GANDIVA_EXPORT BooleanDex : public Dex {
public:
BooleanDex(const ValueValidityPairVector& args, int local_bitmap_idx)
: args_(args), local_bitmap_idx_(local_bitmap_idx) {}
@@ -258,7 +259,7 @@ class BooleanDex : public Dex {
};
/// Boolean-AND expression
-class BooleanAndDex : public BooleanDex {
+class GANDIVA_EXPORT BooleanAndDex : public BooleanDex {
public:
BooleanAndDex(const ValueValidityPairVector& args, int local_bitmap_idx)
: BooleanDex(args, local_bitmap_idx) {}
@@ -267,7 +268,7 @@ class BooleanAndDex : public BooleanDex {
};
/// Boolean-OR expression
-class BooleanOrDex : public BooleanDex {
+class GANDIVA_EXPORT BooleanOrDex : public BooleanDex {
public:
BooleanOrDex(const ValueValidityPairVector& args, int local_bitmap_idx)
: BooleanDex(args, local_bitmap_idx) {}
diff --git a/cpp/src/gandiva/dex_visitor.h b/cpp/src/gandiva/dex_visitor.h
index 456fe43..c34629a 100644
--- a/cpp/src/gandiva/dex_visitor.h
+++ b/cpp/src/gandiva/dex_visitor.h
@@ -21,6 +21,7 @@
#include <string>
#include "gandiva/logging.h"
+#include "gandiva/visibility.h"
namespace gandiva {
@@ -41,7 +42,7 @@ template <typename Type>
class InExprDexBase;
/// \brief Visitor for decomposed expression.
-class DexVisitor {
+class GANDIVA_EXPORT DexVisitor {
public:
virtual ~DexVisitor() = default;
@@ -67,7 +68,7 @@ class DexVisitor {
#define VISIT_DCHECK(DEX_CLASS) \
void Visit(const DEX_CLASS& dex) override { DCHECK(0); }
-class DexDefaultVisitor : public DexVisitor {
+class GANDIVA_EXPORT DexDefaultVisitor : public DexVisitor {
VISIT_DCHECK(VectorReadValidityDex)
VISIT_DCHECK(VectorReadFixedLenValueDex)
VISIT_DCHECK(VectorReadVarLenValueDex)
diff --git a/cpp/src/gandiva/engine.cc b/cpp/src/gandiva/engine.cc
index 9aaafea..d073a3e 100644
--- a/cpp/src/gandiva/engine.cc
+++ b/cpp/src/gandiva/engine.cc
@@ -23,6 +23,15 @@
#include <unordered_set>
#include <utility>
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable : 4141)
+#pragma warning(disable : 4146)
+#pragma warning(disable : 4244)
+#pragma warning(disable : 4267)
+#pragma warning(disable : 4624)
+#endif
+
#include <llvm/Analysis/Passes.h>
#include <llvm/Analysis/TargetTransformInfo.h>
#include <llvm/Bitcode/BitcodeReader.h>
@@ -39,6 +48,11 @@
#include <llvm/Transforms/Scalar.h>
#include <llvm/Transforms/Scalar/GVN.h>
#include <llvm/Transforms/Vectorize.h>
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
#include "gandiva/decimal_ir.h"
#include "gandiva/exported_funcs_registry.h"
diff --git a/cpp/src/gandiva/engine.h b/cpp/src/gandiva/engine.h
index 1248014..7a976d5 100644
--- a/cpp/src/gandiva/engine.h
+++ b/cpp/src/gandiva/engine.h
@@ -23,24 +23,21 @@
#include <string>
#include <vector>
-#include <llvm/ExecutionEngine/ExecutionEngine.h>
-#include <llvm/IR/IRBuilder.h>
-#include <llvm/IR/LLVMContext.h>
-#include <llvm/IR/Module.h>
-
#include "arrow/status.h"
#include "arrow/util/macros.h"
#include "gandiva/configuration.h"
+#include "gandiva/llvm_includes.h"
#include "gandiva/llvm_types.h"
#include "gandiva/logging.h"
+#include "gandiva/visibility.h"
namespace gandiva {
class FunctionIRBuilder;
/// \brief LLVM Execution engine wrapper.
-class Engine {
+class GANDIVA_EXPORT Engine {
public:
llvm::LLVMContext* context() { return context_.get(); }
llvm::IRBuilder<>* ir_builder() { return ir_builder_.get(); }
diff --git a/cpp/src/gandiva/expr_decomposer.cc b/cpp/src/gandiva/expr_decomposer.cc
index bed84ed..91014f1 100644
--- a/cpp/src/gandiva/expr_decomposer.cc
+++ b/cpp/src/gandiva/expr_decomposer.cc
@@ -232,7 +232,7 @@ int ExprDecomposer::PushThenEntry(const IfNode& node) {
// push new entry to the stack.
std::unique_ptr<IfStackEntry> entry(new IfStackEntry(
node, kStackEntryThen, false /*is_terminal_else*/, local_bitmap_idx));
- if_entries_stack_.push(std::move(entry));
+ if_entries_stack_.emplace(std::move(entry));
return local_bitmap_idx;
}
@@ -250,7 +250,7 @@ void ExprDecomposer::PopThenEntry(const IfNode& node) {
void ExprDecomposer::PushElseEntry(const IfNode& node, int local_bitmap_idx) {
std::unique_ptr<IfStackEntry> entry(new IfStackEntry(
node, kStackEntryElse, true /*is_terminal_else*/, local_bitmap_idx));
- if_entries_stack_.push(std::move(entry));
+ if_entries_stack_.emplace(std::move(entry));
}
bool ExprDecomposer::PopElseEntry(const IfNode& node) {
@@ -268,7 +268,7 @@ bool ExprDecomposer::PopElseEntry(const IfNode& node) {
void ExprDecomposer::PushConditionEntry(const IfNode& node) {
std::unique_ptr<IfStackEntry> entry(new IfStackEntry(node, kStackEntryCondition));
- if_entries_stack_.push(std::move(entry));
+ if_entries_stack_.emplace(std::move(entry));
}
void ExprDecomposer::PopConditionEntry(const IfNode& node) {
diff --git a/cpp/src/gandiva/expr_decomposer.h b/cpp/src/gandiva/expr_decomposer.h
index bc21ed0..ab92ca3 100644
--- a/cpp/src/gandiva/expr_decomposer.h
+++ b/cpp/src/gandiva/expr_decomposer.h
@@ -27,6 +27,7 @@
#include "gandiva/expression.h"
#include "gandiva/node.h"
#include "gandiva/node_visitor.h"
+#include "gandiva/visibility.h"
namespace gandiva {
@@ -35,7 +36,7 @@ class Annotator;
/// \brief Decomposes an expression tree to seperate out the validity and
/// value expressions.
-class ExprDecomposer : public NodeVisitor {
+class GANDIVA_EXPORT ExprDecomposer : public NodeVisitor {
public:
explicit ExprDecomposer(const FunctionRegistry& registry, Annotator& annotator)
: registry_(registry), annotator_(annotator) {}
@@ -49,6 +50,8 @@ class ExprDecomposer : public NodeVisitor {
}
private:
+ ARROW_DISALLOW_COPY_AND_ASSIGN(ExprDecomposer);
+
FRIEND_TEST(TestExprDecomposer, TestStackSimple);
FRIEND_TEST(TestExprDecomposer, TestNested);
FRIEND_TEST(TestExprDecomposer, TestInternalIf);
@@ -83,6 +86,9 @@ class ExprDecomposer : public NodeVisitor {
StackEntryType entry_type_;
bool is_terminal_else_;
int local_bitmap_idx_;
+
+ private:
+ ARROW_DISALLOW_COPY_AND_ASSIGN(IfStackEntry);
};
// pop 'condition entry' into stack.
diff --git a/cpp/src/gandiva/expression.h b/cpp/src/gandiva/expression.h
index e3ae18f..2141e87 100644
--- a/cpp/src/gandiva/expression.h
+++ b/cpp/src/gandiva/expression.h
@@ -22,11 +22,12 @@
#include "gandiva/arrow.h"
#include "gandiva/gandiva_aliases.h"
+#include "gandiva/visibility.h"
namespace gandiva {
/// \brief An expression tree with a root node, and a result field.
-class Expression {
+class GANDIVA_EXPORT Expression {
public:
Expression(const NodePtr root, const FieldPtr result) : root_(root), result_(result) {}
diff --git a/cpp/src/gandiva/expression_registry.h b/cpp/src/gandiva/expression_registry.h
index a03deab..4524a07 100644
--- a/cpp/src/gandiva/expression_registry.h
+++ b/cpp/src/gandiva/expression_registry.h
@@ -24,6 +24,7 @@
#include "gandiva/arrow.h"
#include "gandiva/function_signature.h"
#include "gandiva/gandiva_aliases.h"
+#include "gandiva/visibility.h"
namespace gandiva {
@@ -33,13 +34,13 @@ class FunctionRegistry;
///
/// Has helper methods for clients to programatically discover
/// data types and functions supported by Gandiva.
-class ExpressionRegistry {
+class GANDIVA_EXPORT ExpressionRegistry {
public:
using iterator = const NativeFunction*;
ExpressionRegistry();
~ExpressionRegistry();
static DataTypeVector supported_types() { return supported_types_; }
- class FunctionSignatureIterator {
+ class GANDIVA_EXPORT FunctionSignatureIterator {
public:
explicit FunctionSignatureIterator(iterator it) : it_(it) {}
diff --git a/cpp/src/gandiva/filter.cc b/cpp/src/gandiva/filter.cc
index 6075e25..3bba190 100644
--- a/cpp/src/gandiva/filter.cc
+++ b/cpp/src/gandiva/filter.cc
@@ -37,6 +37,8 @@ Filter::Filter(std::unique_ptr<LLVMGenerator> llvm_generator, SchemaPtr schema,
schema_(schema),
configuration_(configuration) {}
+Filter::~Filter() {}
+
Status Filter::Make(SchemaPtr schema, ConditionPtr condition,
std::shared_ptr<Configuration> configuration,
std::shared_ptr<Filter>* filter) {
diff --git a/cpp/src/gandiva/filter.h b/cpp/src/gandiva/filter.h
index 6ff7010..4fbda80 100644
--- a/cpp/src/gandiva/filter.h
+++ b/cpp/src/gandiva/filter.h
@@ -15,8 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-#ifndef GANDIVA_EXPR_FILTER_H
-#define GANDIVA_EXPR_FILTER_H
+#pragma once
#include <memory>
#include <string>
@@ -29,6 +28,7 @@
#include "gandiva/condition.h"
#include "gandiva/configuration.h"
#include "gandiva/selection_vector.h"
+#include "gandiva/visibility.h"
namespace gandiva {
@@ -38,12 +38,14 @@ class LLVMGenerator;
///
/// A filter is built for a specific schema and condition. Once the filter is built, it
/// can be used to evaluate many row batches.
-class Filter {
+class GANDIVA_EXPORT Filter {
public:
Filter(std::unique_ptr<LLVMGenerator> llvm_generator, SchemaPtr schema,
std::shared_ptr<Configuration> config);
- ~Filter() = default;
+ // Inline dtor will attempt to resolve the destructor for
+ // LLVMGenerator on MSVC, so we compile the dtor in the object code
+ ~Filter();
/// Build a filter for the given schema and condition, with the default configuration.
///
@@ -81,5 +83,3 @@ class Filter {
};
} // namespace gandiva
-
-#endif // GANDIVA_EXPR_FILTER_H
diff --git a/cpp/src/gandiva/func_descriptor.h b/cpp/src/gandiva/func_descriptor.h
index 9b18a9b..08f7199 100644
--- a/cpp/src/gandiva/func_descriptor.h
+++ b/cpp/src/gandiva/func_descriptor.h
@@ -22,11 +22,12 @@
#include <vector>
#include "gandiva/arrow.h"
+#include "gandiva/visibility.h"
namespace gandiva {
/// Descriptor for a function in the expression.
-class FuncDescriptor {
+class GANDIVA_EXPORT FuncDescriptor {
public:
FuncDescriptor(const std::string& name, const DataTypeVector& params,
DataTypePtr return_type)
diff --git a/cpp/src/gandiva/function_holder.h b/cpp/src/gandiva/function_holder.h
index 4d007d1..43dbeac 100644
--- a/cpp/src/gandiva/function_holder.h
+++ b/cpp/src/gandiva/function_holder.h
@@ -20,10 +20,12 @@
#include <memory>
+#include "gandiva/visibility.h"
+
namespace gandiva {
/// Holder for a function that can be invoked from LLVM.
-class FunctionHolder {
+class GANDIVA_EXPORT FunctionHolder {
public:
virtual ~FunctionHolder() = default;
};
diff --git a/cpp/src/gandiva/function_registry.h b/cpp/src/gandiva/function_registry.h
index 810bf2d..f7aa3de 100644
--- a/cpp/src/gandiva/function_registry.h
+++ b/cpp/src/gandiva/function_registry.h
@@ -22,11 +22,12 @@
#include "gandiva/function_registry_common.h"
#include "gandiva/gandiva_aliases.h"
#include "gandiva/native_function.h"
+#include "gandiva/visibility.h"
namespace gandiva {
///\brief Registry of pre-compiled IR functions.
-class FunctionRegistry {
+class GANDIVA_EXPORT FunctionRegistry {
public:
using iterator = const NativeFunction*;
diff --git a/cpp/src/gandiva/function_signature.h b/cpp/src/gandiva/function_signature.h
index ee82abc..a5015ce 100644
--- a/cpp/src/gandiva/function_signature.h
+++ b/cpp/src/gandiva/function_signature.h
@@ -24,12 +24,13 @@
#include "gandiva/arrow.h"
#include "gandiva/logging.h"
+#include "gandiva/visibility.h"
namespace gandiva {
/// \brief Signature for a function : includes the base name, input param types and
/// output types.
-class FunctionSignature {
+class GANDIVA_EXPORT FunctionSignature {
public:
FunctionSignature(const std::string& base_name, const DataTypeVector& param_types,
DataTypePtr ret_type)
diff --git a/cpp/src/gandiva/like_holder.h b/cpp/src/gandiva/like_holder.h
index 23ed367..eab30bf 100644
--- a/cpp/src/gandiva/like_holder.h
+++ b/cpp/src/gandiva/like_holder.h
@@ -22,14 +22,17 @@
#include <string>
#include <re2/re2.h>
+
#include "arrow/status.h"
+
#include "gandiva/function_holder.h"
#include "gandiva/node.h"
+#include "gandiva/visibility.h"
namespace gandiva {
/// Function Holder for SQL 'like'
-class LikeHolder : public FunctionHolder {
+class GANDIVA_EXPORT LikeHolder : public FunctionHolder {
public:
~LikeHolder() override = default;
diff --git a/cpp/src/gandiva/llvm_generator.h b/cpp/src/gandiva/llvm_generator.h
index 937e5ac..2c1d5c1 100644
--- a/cpp/src/gandiva/llvm_generator.h
+++ b/cpp/src/gandiva/llvm_generator.h
@@ -36,13 +36,14 @@
#include "gandiva/llvm_types.h"
#include "gandiva/lvalue.h"
#include "gandiva/value_validity_pair.h"
+#include "gandiva/visibility.h"
namespace gandiva {
class FunctionHolder;
/// Builds an LLVM module and generates code for the specified set of expressions.
-class LLVMGenerator {
+class GANDIVA_EXPORT LLVMGenerator {
public:
/// \brief Factory method to initialize the generator.
static Status Make(std::shared_ptr<Configuration> config,
diff --git a/cpp/src/gandiva/function_holder.h b/cpp/src/gandiva/llvm_includes.h
similarity index 64%
copy from cpp/src/gandiva/function_holder.h
copy to cpp/src/gandiva/llvm_includes.h
index 4d007d1..9de1f45 100644
--- a/cpp/src/gandiva/function_holder.h
+++ b/cpp/src/gandiva/llvm_includes.h
@@ -15,21 +15,23 @@
// specific language governing permissions and limitations
// under the License.
-#ifndef GANDIVA_FUNCTION_HOLDER_H
-#define GANDIVA_FUNCTION_HOLDER_H
+#pragma once
-#include <memory>
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable : 4141)
+#pragma warning(disable : 4146)
+#pragma warning(disable : 4244)
+#pragma warning(disable : 4267)
+#pragma warning(disable : 4291)
+#pragma warning(disable : 4624)
+#endif
-namespace gandiva {
+#include <llvm/ExecutionEngine/ExecutionEngine.h>
+#include <llvm/IR/IRBuilder.h>
+#include <llvm/IR/LLVMContext.h>
+#include <llvm/IR/Module.h>
-/// Holder for a function that can be invoked from LLVM.
-class FunctionHolder {
- public:
- virtual ~FunctionHolder() = default;
-};
-
-using FunctionHolderPtr = std::shared_ptr<FunctionHolder>;
-
-} // namespace gandiva
-
-#endif // GANDIVA_FUNCTION_HOLDER_H
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
diff --git a/cpp/src/gandiva/llvm_types.h b/cpp/src/gandiva/llvm_types.h
index 9cf4dd5..2629d32 100644
--- a/cpp/src/gandiva/llvm_types.h
+++ b/cpp/src/gandiva/llvm_types.h
@@ -21,15 +21,15 @@
#include <map>
#include <vector>
-#include <llvm/IR/IRBuilder.h>
-#include <llvm/IR/LLVMContext.h>
#include "gandiva/arrow.h"
+#include "gandiva/llvm_includes.h"
#include "gandiva/logging.h"
+#include "gandiva/visibility.h"
namespace gandiva {
/// \brief Holder for llvm types, and mappings between arrow types and llvm types.
-class LLVMTypes {
+class GANDIVA_EXPORT LLVMTypes {
public:
explicit LLVMTypes(llvm::LLVMContext& context);
diff --git a/cpp/src/gandiva/lvalue.h b/cpp/src/gandiva/lvalue.h
index ce5040f..6c9814c 100644
--- a/cpp/src/gandiva/lvalue.h
+++ b/cpp/src/gandiva/lvalue.h
@@ -20,14 +20,15 @@
#include <vector>
-#include <llvm/IR/IRBuilder.h>
#include "arrow/util/macros.h"
+
+#include "gandiva/llvm_includes.h"
#include "gandiva/logging.h"
namespace gandiva {
/// \brief Tracks validity/value builders in LLVM.
-class LValue {
+class GANDIVA_EXPORT LValue {
public:
explicit LValue(llvm::Value* data, llvm::Value* length = NULLPTR,
llvm::Value* validity = NULLPTR)
@@ -54,7 +55,7 @@ class LValue {
llvm::Value* validity_;
};
-class DecimalLValue : public LValue {
+class GANDIVA_EXPORT DecimalLValue : public LValue {
public:
DecimalLValue(llvm::Value* data, llvm::Value* validity, llvm::Value* precision,
llvm::Value* scale)
diff --git a/cpp/src/gandiva/native_function.h b/cpp/src/gandiva/native_function.h
index 5b130a9..82714c7 100644
--- a/cpp/src/gandiva/native_function.h
+++ b/cpp/src/gandiva/native_function.h
@@ -23,6 +23,7 @@
#include <vector>
#include "gandiva/function_signature.h"
+#include "gandiva/visibility.h"
namespace gandiva {
@@ -37,7 +38,7 @@ enum ResultNullableType {
/// \brief Holder for the mapping from a function in an expression to a
/// precompiled function.
-class NativeFunction {
+class GANDIVA_EXPORT NativeFunction {
public:
// fucntion attributes.
static constexpr int32_t kNeedsContext = (1 << 1);
diff --git a/cpp/src/gandiva/node.h b/cpp/src/gandiva/node.h
index 77cde68..ca51123 100644
--- a/cpp/src/gandiva/node.h
+++ b/cpp/src/gandiva/node.h
@@ -30,12 +30,13 @@
#include "gandiva/gandiva_aliases.h"
#include "gandiva/literal_holder.h"
#include "gandiva/node_visitor.h"
+#include "gandiva/visibility.h"
namespace gandiva {
/// \brief Represents a node in the expression tree. Validity and value are
/// in a joined state.
-class Node {
+class GANDIVA_EXPORT Node {
public:
explicit Node(DataTypePtr return_type) : return_type_(return_type) {}
@@ -53,7 +54,7 @@ class Node {
};
/// \brief Node in the expression tree, representing a literal.
-class LiteralNode : public Node {
+class GANDIVA_EXPORT LiteralNode : public Node {
public:
LiteralNode(DataTypePtr type, const LiteralHolder& holder, bool is_null)
: Node(type), holder_(holder), is_null_(is_null) {}
@@ -95,7 +96,7 @@ class LiteralNode : public Node {
};
/// \brief Node in the expression tree, representing an arrow field.
-class FieldNode : public Node {
+class GANDIVA_EXPORT FieldNode : public Node {
public:
explicit FieldNode(FieldPtr field) : Node(field->type()), field_(field) {}
@@ -112,7 +113,7 @@ class FieldNode : public Node {
};
/// \brief Node in the expression tree, representing a function.
-class FunctionNode : public Node {
+class GANDIVA_EXPORT FunctionNode : public Node {
public:
FunctionNode(const std::string& name, const NodeVector& children, DataTypePtr retType);
@@ -154,7 +155,7 @@ inline FunctionNode::FunctionNode(const std::string& name, const NodeVector& chi
}
/// \brief Node in the expression tree, representing an if-else expression.
-class IfNode : public Node {
+class GANDIVA_EXPORT IfNode : public Node {
public:
IfNode(NodePtr condition, NodePtr then_node, NodePtr else_node, DataTypePtr result_type)
: Node(result_type),
@@ -183,7 +184,7 @@ class IfNode : public Node {
};
/// \brief Node in the expression tree, representing an and/or boolean expression.
-class BooleanNode : public Node {
+class GANDIVA_EXPORT BooleanNode : public Node {
public:
enum ExprType : char { AND, OR };
diff --git a/cpp/src/gandiva/node_visitor.h b/cpp/src/gandiva/node_visitor.h
index ba3645a..27d0564 100644
--- a/cpp/src/gandiva/node_visitor.h
+++ b/cpp/src/gandiva/node_visitor.h
@@ -23,6 +23,7 @@
#include "arrow/status.h"
#include "gandiva/logging.h"
+#include "gandiva/visibility.h"
namespace gandiva {
@@ -35,7 +36,7 @@ template <typename Type>
class InExpressionNode;
/// \brief Visitor for nodes in the expression tree.
-class NodeVisitor {
+class GANDIVA_EXPORT NodeVisitor {
public:
virtual ~NodeVisitor() = default;
diff --git a/cpp/src/gandiva/precompiled/CMakeLists.txt b/cpp/src/gandiva/precompiled/CMakeLists.txt
index 83183bc..5c40a6c 100644
--- a/cpp/src/gandiva/precompiled/CMakeLists.txt
+++ b/cpp/src/gandiva/precompiled/CMakeLists.txt
@@ -30,6 +30,18 @@ set(PRECOMPILED_SRCS
timestamp_arithmetic.cc
../../arrow/util/basic_decimal.cc)
+if (MSVC)
+ # clang pretends to be a particular version of MSVC. Version 1900 is
+ # Visual Studio 2015, and the standard library uses C++14 features,
+ # so we have to use that -std version to get the IR compilation to
+ # work
+ set(PLATFORM_CLANG_OPTIONS
+ -std=c++14 -fms-compatibility -fms-compatibility-version=19)
+else()
+ set(PLATFORM_CLANG_OPTIONS
+ -std=c++11)
+endif()
+
# Create bitcode for each of the source files.
foreach(SRC_FILE ${PRECOMPILED_SRCS})
get_filename_component(SRC_BASE ${SRC_FILE} NAME_WE)
@@ -38,10 +50,13 @@ foreach(SRC_FILE ${PRECOMPILED_SRCS})
add_custom_command(
OUTPUT ${BC_FILE}
COMMAND ${CLANG_EXECUTABLE}
+ ${PLATFORM_CLANG_OPTIONS}
-DGANDIVA_IR
- -std=c++11 -emit-llvm
+ -DNDEBUG # DCHECK macros not implemented in precompiled code
+ -DARROW_STATIC # Do not set __declspec(dllimport) on MSVC on Arrow symbols
+ -DGANDIVA_STATIC # Do not set __declspec(dllimport) on MSVC on Gandiva symbols
-fno-use-cxa-atexit # Workaround for unresolved __dso_handle
- -O3 -c ${ABSOLUTE_SRC} -o ${BC_FILE}
+ -emit-llvm -O3 -c ${ABSOLUTE_SRC} -o ${BC_FILE}
${ARROW_GANDIVA_PC_CXX_FLAGS}
-I${CMAKE_SOURCE_DIR}/src
DEPENDS ${SRC_FILE})
@@ -64,14 +79,20 @@ function(add_precompiled_unit_test REL_TEST_NAME)
set(TEST_NAME "gandiva-precompiled-${TEST_NAME}")
add_executable(${TEST_NAME} ${REL_TEST_NAME} ${ARGN})
- add_dependencies(gandiva-tests ${TEST_NAME})
target_include_directories(${TEST_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/src)
target_link_libraries(${TEST_NAME}
PRIVATE ${ARROW_TEST_LINK_LIBS} ${RE2_LIBRARY}
)
- target_compile_definitions(${TEST_NAME} PRIVATE GANDIVA_UNIT_TEST=1)
- add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME})
- set_property(TEST ${TEST_NAME} PROPERTY LABELS gandiva-tests {TEST_NAME})
+ target_compile_definitions(${TEST_NAME} PRIVATE
+ GANDIVA_UNIT_TEST=1
+ ARROW_STATIC
+ GANDIVA_STATIC)
+ set(TEST_PATH "${EXECUTABLE_OUTPUT_PATH}/${TEST_NAME}")
+ add_test(${TEST_NAME} ${TEST_PATH})
+ set_property(TEST ${TEST_NAME}
+ APPEND PROPERTY
+ LABELS "unittest;gandiva-tests")
+ add_dependencies(gandiva-tests ${TEST_NAME})
endfunction(add_precompiled_unit_test REL_TEST_NAME)
# testing
diff --git a/cpp/src/gandiva/precompiled/epoch_time_point_test.cc b/cpp/src/gandiva/precompiled/epoch_time_point_test.cc
index f489b7d..32cb9e8 100644
--- a/cpp/src/gandiva/precompiled/epoch_time_point_test.cc
+++ b/cpp/src/gandiva/precompiled/epoch_time_point_test.cc
@@ -15,36 +15,39 @@
// specific language governing permissions and limitations
// under the License.
-#include <time.h>
+#include <ctime>
#include <gtest/gtest.h>
#include "./epoch_time_point.h"
+#include "gandiva/precompiled/testing.h"
#include "gandiva/precompiled/types.h"
-namespace gandiva {
+#include "gandiva/date_utils.h"
-timestamp StringToTimestamp(const char* buf) {
- struct tm tm;
- strptime(buf, "%Y-%m-%d %H:%M:%S", &tm);
- return timegm(&tm) * 1000; // to millis
-}
+namespace gandiva {
TEST(TestEpochTimePoint, TestTm) {
auto ts = StringToTimestamp("2015-05-07 10:20:34");
EpochTimePoint tp(ts);
+ struct tm* tm_ptr;
+#if defined(_MSC_VER)
+ __time64_t tsec = ts / 1000;
+ tm_ptr = _gmtime64(&tsec);
+#else
struct tm tm;
time_t tsec = ts / 1000;
- gmtime_r(&tsec, &tm);
-
- EXPECT_EQ(tp.TmYear(), tm.tm_year);
- EXPECT_EQ(tp.TmMon(), tm.tm_mon);
- EXPECT_EQ(tp.TmYday(), tm.tm_yday);
- EXPECT_EQ(tp.TmMday(), tm.tm_mday);
- EXPECT_EQ(tp.TmWday(), tm.tm_wday);
- EXPECT_EQ(tp.TmHour(), tm.tm_hour);
- EXPECT_EQ(tp.TmMin(), tm.tm_min);
- EXPECT_EQ(tp.TmSec(), tm.tm_sec);
+ tm_ptr = gmtime_r(&tsec, &tm);
+#endif
+
+ EXPECT_EQ(tp.TmYear(), tm_ptr->tm_year);
+ EXPECT_EQ(tp.TmMon(), tm_ptr->tm_mon);
+ EXPECT_EQ(tp.TmYday(), tm_ptr->tm_yday);
+ EXPECT_EQ(tp.TmMday(), tm_ptr->tm_mday);
+ EXPECT_EQ(tp.TmWday(), tm_ptr->tm_wday);
+ EXPECT_EQ(tp.TmHour(), tm_ptr->tm_hour);
+ EXPECT_EQ(tp.TmMin(), tm_ptr->tm_min);
+ EXPECT_EQ(tp.TmSec(), tm_ptr->tm_sec);
}
TEST(TestEpochTimePoint, TestAddYears) {
diff --git a/cpp/src/gandiva/precompiled/extended_math_ops.cc b/cpp/src/gandiva/precompiled/extended_math_ops.cc
index 1b7642c..b17ccd8 100644
--- a/cpp/src/gandiva/precompiled/extended_math_ops.cc
+++ b/cpp/src/gandiva/precompiled/extended_math_ops.cc
@@ -33,30 +33,40 @@ extern "C" {
INNER(float64, OUT_TYPE)
// Cubic root
-#define CBRT(IN_TYPE, OUT_TYPE) \
- FORCE_INLINE \
- OUT_TYPE cbrt_##IN_TYPE(IN_TYPE in) { return static_cast<float64>(cbrtl(in)); }
+#define CBRT(IN_TYPE, OUT_TYPE) \
+ FORCE_INLINE \
+ OUT_TYPE cbrt_##IN_TYPE(IN_TYPE in) { \
+ return static_cast<float64>(cbrtl(static_cast<long double>(in))); \
+ }
ENUMERIC_TYPES_UNARY(CBRT, float64)
// Exponent
-#define EXP(IN_TYPE, OUT_TYPE) \
- FORCE_INLINE \
- OUT_TYPE exp_##IN_TYPE(IN_TYPE in) { return static_cast<float64>(expl(in)); }
+#define EXP(IN_TYPE, OUT_TYPE) \
+ FORCE_INLINE \
+ OUT_TYPE exp_##IN_TYPE(IN_TYPE in) { \
+ return static_cast<float64>(expl(static_cast<long double>(in))); \
+ }
ENUMERIC_TYPES_UNARY(EXP, float64)
// log
-#define LOG(IN_TYPE, OUT_TYPE) \
- FORCE_INLINE \
- OUT_TYPE log_##IN_TYPE(IN_TYPE in) { return static_cast<float64>(logl(in)); }
+#define LOG(IN_TYPE, OUT_TYPE) \
+ FORCE_INLINE \
+ OUT_TYPE log_##IN_TYPE(IN_TYPE in) { \
+ return static_cast<float64>(logl(static_cast<long double>(in))); \
+ }
ENUMERIC_TYPES_UNARY(LOG, float64)
// log base 10
-#define LOG10(IN_TYPE, OUT_TYPE) \
- FORCE_INLINE \
- OUT_TYPE log10_##IN_TYPE(IN_TYPE in) { return static_cast<float64>(log10l(in)); }
+#define LOG10(IN_TYPE, OUT_TYPE) \
+ FORCE_INLINE \
+ OUT_TYPE log10_##IN_TYPE(IN_TYPE in) { \
+ return static_cast<float64>(log10l(static_cast<long double>(in))); \
+ }
+
+#define LOGL(VALUE) static_cast<float64>(logl(static_cast<long double>(VALUE)))
ENUMERIC_TYPES_UNARY(LOG10, float64)
@@ -74,12 +84,12 @@ void set_error_for_logbase(int64_t execution_context, double base) {
#define LOG_WITH_BASE(IN_TYPE1, IN_TYPE2, OUT_TYPE) \
FORCE_INLINE \
OUT_TYPE log_##IN_TYPE1##_##IN_TYPE2(int64 context, IN_TYPE1 base, IN_TYPE2 value) { \
- OUT_TYPE log_of_base = static_cast<float64>(logl(base)); \
+ OUT_TYPE log_of_base = LOGL(base); \
if (log_of_base == 0) { \
set_error_for_logbase(context, static_cast<float64>(base)); \
return 0; \
} \
- return static_cast<float64>(logl(value) / logl(base)); \
+ return LOGL(value) / LOGL(base); \
}
LOG_WITH_BASE(int32, int32, float64)
diff --git a/cpp/src/gandiva/function_holder.h b/cpp/src/gandiva/precompiled/testing.h
similarity index 72%
copy from cpp/src/gandiva/function_holder.h
copy to cpp/src/gandiva/precompiled/testing.h
index 4d007d1..3214eec 100644
--- a/cpp/src/gandiva/function_holder.h
+++ b/cpp/src/gandiva/precompiled/testing.h
@@ -15,21 +15,23 @@
// specific language governing permissions and limitations
// under the License.
-#ifndef GANDIVA_FUNCTION_HOLDER_H
-#define GANDIVA_FUNCTION_HOLDER_H
+#pragma once
-#include <memory>
+#include <ctime>
-namespace gandiva {
+#include <gtest/gtest.h>
-/// Holder for a function that can be invoked from LLVM.
-class FunctionHolder {
- public:
- virtual ~FunctionHolder() = default;
-};
+#include "arrow/util/logging.h"
-using FunctionHolderPtr = std::shared_ptr<FunctionHolder>;
+#include "gandiva/date_utils.h"
+#include "gandiva/precompiled/types.h"
-} // namespace gandiva
+namespace gandiva {
-#endif // GANDIVA_FUNCTION_HOLDER_H
+timestamp StringToTimestamp(const char* buf) {
+ int64_t out = 0;
+ DCHECK(internal::ParseTimestamp(buf, "%Y-%m-%d %H:%M:%S", false, &out));
+ return out * 1000;
+}
+
+} // namespace gandiva
diff --git a/cpp/src/gandiva/precompiled/time_test.cc b/cpp/src/gandiva/precompiled/time_test.cc
index 36ba9b3..b8f8069 100644
--- a/cpp/src/gandiva/precompiled/time_test.cc
+++ b/cpp/src/gandiva/precompiled/time_test.cc
@@ -18,16 +18,11 @@
#include <gtest/gtest.h>
#include <time.h>
#include "../execution_context.h"
+#include "gandiva/precompiled/testing.h"
#include "gandiva/precompiled/types.h"
namespace gandiva {
-timestamp StringToTimestamp(const char* buf) {
- struct tm tm;
- strptime(buf, "%Y-%m-%d %H:%M:%S", &tm);
- return timegm(&tm) * 1000; // to millis
-}
-
TEST(TestTime, TestCastDate) {
ExecutionContext context;
int64_t context_ptr = reinterpret_cast<int64_t>(&context);
diff --git a/cpp/src/gandiva/projector.cc b/cpp/src/gandiva/projector.cc
index 8fc5b8c..7950fc7 100644
--- a/cpp/src/gandiva/projector.cc
+++ b/cpp/src/gandiva/projector.cc
@@ -36,6 +36,8 @@ Projector::Projector(std::unique_ptr<LLVMGenerator> llvm_generator, SchemaPtr sc
output_fields_(output_fields),
configuration_(configuration) {}
+Projector::~Projector() {}
+
Status Projector::Make(SchemaPtr schema, const ExpressionVector& exprs,
std::shared_ptr<Projector>* projector) {
return Projector::Make(schema, exprs, ConfigurationBuilder::DefaultConfiguration(),
diff --git a/cpp/src/gandiva/projector.h b/cpp/src/gandiva/projector.h
index c9d7271..58bac78 100644
--- a/cpp/src/gandiva/projector.h
+++ b/cpp/src/gandiva/projector.h
@@ -15,8 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-#ifndef GANDIVA_EXPR_PROJECTOR_H
-#define GANDIVA_EXPR_PROJECTOR_H
+#pragma once
#include <memory>
#include <string>
@@ -28,6 +27,7 @@
#include "gandiva/arrow.h"
#include "gandiva/configuration.h"
#include "gandiva/expression.h"
+#include "gandiva/visibility.h"
namespace gandiva {
@@ -37,8 +37,12 @@ class LLVMGenerator;
///
/// A projector is built for a specific schema and vector of expressions.
/// Once the projector is built, it can be used to evaluate many row batches.
-class Projector {
+class GANDIVA_EXPORT Projector {
public:
+ // Inline dtor will attempt to resolve the destructor for
+ // LLVMGenerator on MSVC, so we compile the dtor in the object code
+ ~Projector();
+
/// Build a default projector for the given schema to evaluate
/// the vector of expressions.
///
@@ -99,5 +103,3 @@ class Projector {
};
} // namespace gandiva
-
-#endif // GANDIVA_EXPR_PROJECTOR_H
diff --git a/cpp/src/gandiva/regex_util.h b/cpp/src/gandiva/regex_util.h
index 6a22af2..7ea7060 100644
--- a/cpp/src/gandiva/regex_util.h
+++ b/cpp/src/gandiva/regex_util.h
@@ -23,11 +23,12 @@
#include <string>
#include "gandiva/arrow.h"
+#include "gandiva/visibility.h"
namespace gandiva {
/// \brief Utility class for converting sql patterns to pcre patterns.
-class RegexUtil {
+class GANDIVA_EXPORT RegexUtil {
public:
// Convert an sql pattern to a pcre pattern
static Status SqlLikePatternToPcre(const std::string& like_pattern, char escape_char,
diff --git a/cpp/src/gandiva/selection_vector.cc b/cpp/src/gandiva/selection_vector.cc
index f89b80c..e643cec 100644
--- a/cpp/src/gandiva/selection_vector.cc
+++ b/cpp/src/gandiva/selection_vector.cc
@@ -22,6 +22,8 @@
#include <utility>
#include <vector>
+#include "arrow/util/bit-util.h"
+
#include "gandiva/selection_vector_impl.h"
namespace gandiva {
@@ -48,8 +50,18 @@ Status SelectionVector::PopulateFromBitMap(const uint8_t* bitmap, int64_t bitmap
uint64_t current_word = bitmap_64[bitmap_idx];
while (current_word != 0) {
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable : 4146)
+#endif
+ // MSVC warns about negating an unsigned type. We suppress it for now
uint64_t highest_only = current_word & -current_word;
- int pos_in_word = __builtin_ctzl(highest_only);
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+ int pos_in_word = arrow::BitUtil::CountTrailingZeros(highest_only);
int64_t pos_in_bitmap = bitmap_idx * 64 + pos_in_word;
if (pos_in_bitmap > max_bitmap_index) {
diff --git a/cpp/src/gandiva/selection_vector.h b/cpp/src/gandiva/selection_vector.h
index dcd2f6b..2e99417 100644
--- a/cpp/src/gandiva/selection_vector.h
+++ b/cpp/src/gandiva/selection_vector.h
@@ -24,12 +24,13 @@
#include "gandiva/arrow.h"
#include "gandiva/logging.h"
+#include "gandiva/visibility.h"
namespace gandiva {
/// \brief Selection Vector : vector of indices in a row-batch for a selection,
/// backed by an arrow-array.
-class SelectionVector {
+class GANDIVA_EXPORT SelectionVector {
public:
virtual ~SelectionVector() = default;
diff --git a/cpp/src/gandiva/tests/date_time_test.cc b/cpp/src/gandiva/tests/date_time_test.cc
index 643b8c8..7867a95 100644
--- a/cpp/src/gandiva/tests/date_time_test.cc
+++ b/cpp/src/gandiva/tests/date_time_test.cc
@@ -57,7 +57,7 @@ int64_t MillisSince(time_t base_line, int32_t yy, int32_t mm, int32_t dd, int32_
given_ts.tm_min = min;
given_ts.tm_sec = sec;
- return (lround(difftime(mktime(&given_ts), base_line)) * 1000 + millis);
+ return (static_cast<int64_t>(difftime(mktime(&given_ts), base_line)) * 1000 + millis);
}
TEST_F(TestProjector, TestIsNull) {
diff --git a/cpp/src/gandiva/tests/projector_test.cc b/cpp/src/gandiva/tests/projector_test.cc
index 5c32f50..ba0e632 100644
--- a/cpp/src/gandiva/tests/projector_test.cc
+++ b/cpp/src/gandiva/tests/projector_test.cc
@@ -86,10 +86,14 @@ TEST_F(TestProjector, TestProjectCache) {
EXPECT_EQ(cached_projector, projector);
// if configuration is different, should return a new projector.
+
+ // build a new path by replacing the first '/' with '//'
+ std::string alt_path(GANDIVA_BYTE_COMPILE_FILE_PATH);
+ auto pos = alt_path.find('/', 0);
+ EXPECT_NE(pos, std::string::npos);
+ alt_path.replace(pos, 1, "//");
auto other_configuration =
- ConfigurationBuilder()
- .set_byte_code_file_path("/" + std::string(GANDIVA_BYTE_COMPILE_FILE_PATH))
- .build();
+ ConfigurationBuilder().set_byte_code_file_path(alt_path).build();
std::shared_ptr<Projector> should_be_new_projector2;
status = Projector::Make(schema, {sum_expr, sub_expr}, other_configuration,
&should_be_new_projector2);
diff --git a/cpp/src/gandiva/to_date_holder.cc b/cpp/src/gandiva/to_date_holder.cc
index 6e02a6a..824654f 100644
--- a/cpp/src/gandiva/to_date_holder.cc
+++ b/cpp/src/gandiva/to_date_holder.cc
@@ -18,7 +18,7 @@
#include <algorithm>
#include <string>
-#include "arrow/vendored/datetime/date.h"
+#include "arrow/vendored/datetime.h"
#include "gandiva/date_utils.h"
#include "gandiva/execution_context.h"
@@ -64,8 +64,7 @@ Status ToDateHolder::Make(const FunctionNode& node,
Status ToDateHolder::Make(const std::string& sql_pattern, int32_t suppress_errors,
std::shared_ptr<ToDateHolder>* holder) {
std::shared_ptr<std::string> transformed_pattern;
- Status status = DateUtils::ToInternalFormat(sql_pattern, &transformed_pattern);
- ARROW_RETURN_NOT_OK(status);
+ ARROW_RETURN_NOT_OK(DateUtils::ToInternalFormat(sql_pattern, &transformed_pattern));
auto lholder = std::shared_ptr<ToDateHolder>(
new ToDateHolder(*(transformed_pattern.get()), suppress_errors));
*holder = lholder;
@@ -82,22 +81,14 @@ int64_t ToDateHolder::operator()(ExecutionContext* context, const std::string& d
// Issues
// 1. processes date that do not match the format.
// 2. does not process time in format +08:00 (or) id.
- struct tm result = {};
- char* ret = strptime(data.c_str(), pattern_.c_str(), &result);
- if (ret == nullptr) {
+ int64_t seconds_since_epoch = 0;
+ if (!internal::ParseTimestamp(data.c_str(), pattern_.c_str(), true,
+ &seconds_since_epoch)) {
return_error(context, data);
return 0;
}
+
*out_valid = true;
- // ignore the time part
- arrow::util::date::sys_seconds secs =
- arrow::util::date::sys_days(arrow::util::date::year(result.tm_year + 1900) /
- (result.tm_mon + 1) / result.tm_mday);
- int64_t seconds_since_epoch = secs.time_since_epoch().count();
- if (seconds_since_epoch == 0) {
- return_error(context, data);
- return 0;
- }
return seconds_since_epoch * 1000;
}
diff --git a/cpp/src/gandiva/to_date_holder.h b/cpp/src/gandiva/to_date_holder.h
index 91133cc..c0c5afb 100644
--- a/cpp/src/gandiva/to_date_holder.h
+++ b/cpp/src/gandiva/to_date_holder.h
@@ -27,11 +27,12 @@
#include "gandiva/execution_context.h"
#include "gandiva/function_holder.h"
#include "gandiva/node.h"
+#include "gandiva/visibility.h"
namespace gandiva {
/// Function Holder for SQL 'to_date'
-class ToDateHolder : public FunctionHolder {
+class GANDIVA_EXPORT ToDateHolder : public FunctionHolder {
public:
~ToDateHolder() override = default;
diff --git a/cpp/src/gandiva/to_date_holder_test.cc b/cpp/src/gandiva/to_date_holder_test.cc
index 2a207b2..0effffb 100644
--- a/cpp/src/gandiva/to_date_holder_test.cc
+++ b/cpp/src/gandiva/to_date_holder_test.cc
@@ -18,6 +18,8 @@
#include <memory>
#include <vector>
+#include "arrow/test-util.h"
+
#include "gandiva/execution_context.h"
#include "gandiva/to_date_holder.h"
#include "precompiled/epoch_time_point.h"
@@ -37,57 +39,68 @@ class TestToDateHolder : public ::testing::Test {
return FunctionNode("to_date_utf8_utf8_int32",
{field, pattern_node, suppres_error_node}, arrow::int64());
}
+
+ protected:
+ ExecutionContext execution_context_;
};
TEST_F(TestToDateHolder, TestSimpleDateTime) {
std::shared_ptr<ToDateHolder> to_date_holder;
+ ASSERT_OK(ToDateHolder::Make("YYYY-MM-DD HH:MI:SS", 1, &to_date_holder));
- auto status = ToDateHolder::Make("YYYY-MM-DD HH:MI:SS", 1, &to_date_holder);
- EXPECT_EQ(status.ok(), true) << status.message();
- ExecutionContext execution_context;
auto& to_date = *to_date_holder;
bool out_valid;
int64_t millis_since_epoch =
- to_date(&execution_context, "1986-12-01 01:01:01", true, &out_valid);
+ to_date(&execution_context_, "1986-12-01 01:01:01", true, &out_valid);
EXPECT_EQ(millis_since_epoch, 533779200000);
millis_since_epoch =
- to_date(&execution_context, "1986-12-01 01:01:01.11", true, &out_valid);
+ to_date(&execution_context_, "1986-12-01 01:01:01.11", true, &out_valid);
EXPECT_EQ(millis_since_epoch, 533779200000);
millis_since_epoch =
- to_date(&execution_context, "1986-12-01 01:01:01 +0800", true, &out_valid);
+ to_date(&execution_context_, "1986-12-01 01:01:01 +0800", true, &out_valid);
EXPECT_EQ(millis_since_epoch, 533779200000);
+#if 0
+ // TODO : this fails parsing with date::parse and strptime on linux
+ millis_since_epoch =
+ to_date(&execution_context_, "1886-12-01 00:00:00", true, &out_valid);
+ EXPECT_EQ(out_valid, true);
+ EXPECT_EQ(millis_since_epoch, -2621894400000);
+#endif
+
millis_since_epoch =
- to_date(&execution_context, "1986-12-11 01:30:00", true, &out_valid);
+ to_date(&execution_context_, "1886-12-01 01:01:01", true, &out_valid);
+ EXPECT_EQ(millis_since_epoch, -2621894400000);
+
+ millis_since_epoch =
+ to_date(&execution_context_, "1986-12-11 01:30:00", true, &out_valid);
EXPECT_EQ(millis_since_epoch, 534643200000);
}
TEST_F(TestToDateHolder, TestSimpleDate) {
std::shared_ptr<ToDateHolder> to_date_holder;
+ ASSERT_OK(ToDateHolder::Make("YYYY-MM-DD", 1, &to_date_holder));
- auto status = ToDateHolder::Make("YYYY-MM-DD", 1, &to_date_holder);
- EXPECT_EQ(status.ok(), true) << status.message();
- ExecutionContext execution_context;
auto& to_date = *to_date_holder;
bool out_valid;
int64_t millis_since_epoch =
- to_date(&execution_context, "1986-12-01", true, &out_valid);
+ to_date(&execution_context_, "1986-12-01", true, &out_valid);
EXPECT_EQ(millis_since_epoch, 533779200000);
- millis_since_epoch = to_date(&execution_context, "1986-12-1", true, &out_valid);
+ millis_since_epoch = to_date(&execution_context_, "1986-12-1", true, &out_valid);
EXPECT_EQ(millis_since_epoch, 533779200000);
- millis_since_epoch = to_date(&execution_context, "1886-12-1", true, &out_valid);
+ millis_since_epoch = to_date(&execution_context_, "1886-12-1", true, &out_valid);
EXPECT_EQ(millis_since_epoch, -2621894400000);
- millis_since_epoch = to_date(&execution_context, "2012-12-1", true, &out_valid);
+ millis_since_epoch = to_date(&execution_context_, "2012-12-1", true, &out_valid);
EXPECT_EQ(millis_since_epoch, 1354320000000);
// wrong month. should return 0 since we are suppresing errors.
millis_since_epoch =
- to_date(&execution_context, "1986-21-01 01:01:01 +0800", true, &out_valid);
+ to_date(&execution_context_, "1986-21-01 01:01:01 +0800", true, &out_valid);
EXPECT_EQ(millis_since_epoch, 0);
}
@@ -96,22 +109,22 @@ TEST_F(TestToDateHolder, TestSimpleDateTimeError) {
auto status = ToDateHolder::Make("YYYY-MM-DD HH:MI:SS", 0, &to_date_holder);
EXPECT_EQ(status.ok(), true) << status.message();
- ExecutionContext execution_context;
auto& to_date = *to_date_holder;
bool out_valid;
int64_t millis_since_epoch =
- to_date(&execution_context, "1986-21-01 01:01:01 +0800", true, &out_valid);
+ to_date(&execution_context_, "1986-01-40 01:01:01 +0800", true, &out_valid);
+ EXPECT_EQ(0, millis_since_epoch);
std::string expected_error =
- "Error parsing value 1986-21-01 01:01:01 +0800 for given format";
- EXPECT_TRUE(execution_context.get_error().find(expected_error) != std::string::npos)
+ "Error parsing value 1986-01-40 01:01:01 +0800 for given format";
+ EXPECT_TRUE(execution_context_.get_error().find(expected_error) != std::string::npos)
<< status.message();
// not valid should not return error
- execution_context.Reset();
- millis_since_epoch = to_date(&execution_context, "nullptr", false, &out_valid);
+ execution_context_.Reset();
+ millis_since_epoch = to_date(&execution_context_, "nullptr", false, &out_valid);
EXPECT_EQ(millis_since_epoch, 0);
- EXPECT_TRUE(execution_context.has_error() == false);
+ EXPECT_TRUE(execution_context_.has_error() == false);
}
TEST_F(TestToDateHolder, TestSimpleDateTimeMakeError) {
diff --git a/cpp/src/gandiva/tree_expr_builder.h b/cpp/src/gandiva/tree_expr_builder.h
index 3d60b5b..4b2789a 100644
--- a/cpp/src/gandiva/tree_expr_builder.h
+++ b/cpp/src/gandiva/tree_expr_builder.h
@@ -27,11 +27,12 @@
#include "gandiva/condition.h"
#include "gandiva/decimal_scalar.h"
#include "gandiva/expression.h"
+#include "gandiva/visibility.h"
namespace gandiva {
/// \brief Tree Builder for a nested expression.
-class TreeExprBuilder {
+class GANDIVA_EXPORT TreeExprBuilder {
public:
/// \brief create a node on a literal.
static NodePtr MakeLiteral(bool value);
diff --git a/cpp/src/gandiva/value_validity_pair.h b/cpp/src/gandiva/value_validity_pair.h
index 1bcd5d6..0de525d 100644
--- a/cpp/src/gandiva/value_validity_pair.h
+++ b/cpp/src/gandiva/value_validity_pair.h
@@ -21,11 +21,12 @@
#include <vector>
#include "gandiva/gandiva_aliases.h"
+#include "gandiva/visibility.h"
namespace gandiva {
/// Pair of vector/validities generated after decomposing an expression tree/subtree.
-class ValueValidityPair {
+class GANDIVA_EXPORT ValueValidityPair {
public:
ValueValidityPair(const DexVector& validity_exprs, DexPtr value_expr)
: validity_exprs_(validity_exprs), value_expr_(value_expr) {}
diff --git a/cpp/src/gandiva/function_holder.h b/cpp/src/gandiva/visibility.h
similarity index 54%
copy from cpp/src/gandiva/function_holder.h
copy to cpp/src/gandiva/visibility.h
index 4d007d1..450b305 100644
--- a/cpp/src/gandiva/function_holder.h
+++ b/cpp/src/gandiva/visibility.h
@@ -15,21 +15,34 @@
// specific language governing permissions and limitations
// under the License.
-#ifndef GANDIVA_FUNCTION_HOLDER_H
-#define GANDIVA_FUNCTION_HOLDER_H
+#pragma once
-#include <memory>
+#if defined(_WIN32) || defined(__CYGWIN__)
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable : 4251)
+#else
+#pragma GCC diagnostic ignored "-Wattributes"
+#endif
-namespace gandiva {
+#ifdef GANDIVA_STATIC
+#define GANDIVA_EXPORT
+#elif defined(GANDIVA_EXPORTING)
+#define GANDIVA_EXPORT __declspec(dllexport)
+#else
+#define GANDIVA_EXPORT __declspec(dllimport)
+#endif
-/// Holder for a function that can be invoked from LLVM.
-class FunctionHolder {
- public:
- virtual ~FunctionHolder() = default;
-};
+#define GANDIVA_NO_EXPORT
+#else // Not Windows
+#ifndef GANDIVA_EXPORT
+#define GANDIVA_EXPORT __attribute__((visibility("default")))
+#endif
+#ifndef GANDIVA_NO_EXPORT
+#define GANDIVA_NO_EXPORT __attribute__((visibility("hidden")))
+#endif
+#endif // Non-Windows
-using FunctionHolderPtr = std::shared_ptr<FunctionHolder>;
-
-} // namespace gandiva
-
-#endif // GANDIVA_FUNCTION_HOLDER_H
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
diff --git a/cpp/thirdparty/versions.txt b/cpp/thirdparty/versions.txt
index 00cd31e..e62a37b 100644
--- a/cpp/thirdparty/versions.txt
+++ b/cpp/thirdparty/versions.txt
@@ -27,7 +27,7 @@ BOOST_VERSION=1.67.0
BROTLI_VERSION=v0.6.0
CARES_VERSION=1.15.0
DOUBLE_CONVERSION_VERSION=v3.1.1
-FLATBUFFERS_VERSION=02a7807dd8d26f5668ffbbec0360dc107bbfabd5
+FLATBUFFERS_VERSION=v1.10.0
GBENCHMARK_VERSION=v1.4.1
GFLAGS_VERSION=v2.2.0
GLOG_VERSION=v0.3.5