diff --git a/.github/workflows/native-windows.yml b/.github/workflows/native-windows.yml index b2bf4d9310..434ff3bd5c 100644 --- a/.github/workflows/native-windows.yml +++ b/.github/workflows/native-windows.yml @@ -176,6 +176,65 @@ jobs: BUILD_DRIVER_SQLITE: "1" run: .\ci\scripts\cpp_test.ps1 $pwd\build + # ------------------------------------------------------------ + # C/C++ build w/ vcpkg (builds and tests) + # ------------------------------------------------------------ + drivers-build-vcpkg: + name: "C/C++ (vcpkg/${{ matrix.os }}/${{ matrix.arch }}/${{ matrix.config }})" + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: ["windows-latest"] + arch: ["x64"] + config: ["Debug"] + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # v2 + + - name: Clone vcpkg + run: | + git clone https://github.com/microsoft/vcpkg.git + cd vcpkg + git checkout 9e4b86d4871c47f125e9f631de07d963fcd38389 + .\bootstrap-vcpkg.bat + + - name: Cache vcpkg dependencies + uses: actions/cache@v4 + with: + path: | + ${{ github.workspace }}/vcpkg/packages + ${{ github.workspace }}/vcpkg/installed + ~\AppData\Local\vcpkg\archives + key: vcpkg-${{ runner.os }}-${{ matrix.arch }}-${{ hashFiles('c/vcpkg.json', 'c/driver/*/vcpkg.json') }} + + - name: Install vcpkg dependencies + working-directory: c + env: + VCPKG_ROOT: ${{ github.workspace }}/vcpkg + run: | + ${{ github.workspace }}/vcpkg/vcpkg.exe install --triplet ${{ matrix.arch }}-windows + + - name: Build + env: + BUILD_ALL: "1" + BUILD_DRIVER_MANAGER_USER_CONFIG_TEST: "1" + CMAKE_BUILD_TYPE: ${{ matrix.config }} + VCPKG_ROOT: ${{ github.workspace }}/vcpkg + run: .\ci\scripts\cpp_build.ps1 $pwd $pwd\build + + - name: Test + env: + BUILD_ALL: "0" + BUILD_DRIVER_MANAGER: "1" + BUILD_DRIVER_MANAGER_USER_CONFIG_TEST: "1" + BUILD_DRIVER_SQLITE: "1" + run: .\ci\scripts\cpp_test.ps1 $pwd\build + # ------------------------------------------------------------ # Go build # ------------------------------------------------------------ diff --git a/c/.gitignore b/c/.gitignore new file mode 100644 index 0000000000..6aaf67e6f6 --- /dev/null +++ b/c/.gitignore @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + +vcpkg_installed/ diff --git a/c/CMakePresets.json b/c/CMakePresets.json index fc4fdcb9a9..8c3fd75c38 100644 --- a/c/CMakePresets.json +++ b/c/CMakePresets.json @@ -39,6 +39,44 @@ "ADBC_USE_ASAN": "OFF", "ADBC_USE_UBSAN": "OFF" } + }, + { + "name": "vcpkg", + "hidden": true, + "generator": "Ninja", + "toolchainFile": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake", + "cacheVariables": { + "CMAKE_EXPORT_COMPILE_COMMANDS": "ON", + "CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake", + "ADBC_BUILD_TESTS": "ON", + "ADBC_DRIVER_FLIGHTSQL": "ON", + "ADBC_DRIVER_MANAGER": "ON", + "ADBC_DRIVER_POSTGRESQL": "ON", + "ADBC_DRIVER_SNOWFLAKE": "ON", + "ADBC_DRIVER_SQLITE": "ON", + "ADBC_BUILD_SHARED": "ON", + "ADBC_BUILD_STATIC": "OFF", + "ADBC_USE_ASAN": "OFF", + "ADBC_USE_UBSAN": "OFF" + } + }, + { + "name": "windows-debug", + "displayName": "Windows x64 Debug", + "inherits": "vcpkg", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } + }, + { + "name": "windows-release", + "displayName": "Windows x64 Release", + "inherits": "vcpkg", + "binaryDir": "${sourceDir}/build-release", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } } ], "testPresets": [ diff --git a/c/cmake_modules/AdbcDefines.cmake b/c/cmake_modules/AdbcDefines.cmake index 11fe1a5d2a..d905b119f0 100644 --- a/c/cmake_modules/AdbcDefines.cmake +++ b/c/cmake_modules/AdbcDefines.cmake @@ -84,6 +84,8 @@ if(MSVC) # Nanoarrow emits a lot of conversion warnings add_compile_options(/wd4365) add_compile_options(/wd4242) + # Don't warn about hidden virtual functions (see DriverQuirks) + add_compile_options(/wd4266) add_compile_options(/wd4458) add_compile_options(/wd4514) add_compile_options(/wd4582) @@ -97,6 +99,18 @@ if(MSVC) add_compile_options(/wd4820) # Don't warn about enforcing left-to-right evaluation order for operator[] add_compile_options(/wd4866) + # Don't warn about unary minus applied to unsigned type + add_compile_options(/wd4146) + # Don't warn about type conversions that may lose data + add_compile_options(/wd4244) + # Don't warn about size_t to int conversions + add_compile_options(/wd4267) + # Don't warn about double to float truncation + add_compile_options(/wd4305) + # Don't warn about signed integral constant overflow + add_compile_options(/wd4307) + # Don't warn about implicitly deleted move constructors in GoogleTest fixtures + add_compile_options(/wd5026) add_compile_options(/wd5027) add_compile_options(/wd5039) add_compile_options(/wd5045) diff --git a/c/cmake_modules/GoUtils.cmake b/c/cmake_modules/GoUtils.cmake index a0e2ccef75..569b800960 100644 --- a/c/cmake_modules/GoUtils.cmake +++ b/c/cmake_modules/GoUtils.cmake @@ -18,6 +18,21 @@ find_program(GO_BIN "go" REQUIRED) message(STATUS "Detecting Go executable: Found ${GO_BIN}") +if(WIN32) + # Find tools for generating import libraries from Go DLLs since Go doesn't + # produce .lib files + find_program(GENDEF_BIN NAMES gendef) + find_program(DLLTOOL_BIN NAMES dlltool) + if(GENDEF_BIN AND DLLTOOL_BIN) + message(STATUS "Found gendef: ${GENDEF_BIN}") + message(STATUS "Found dlltool: ${DLLTOOL_BIN}") + else() + message(WARNING "gendef and/or dlltool not found - Go driver import libraries won't be automatically created" + ) + message(WARNING "Install MinGW64 and add it to your PATH to make them available") + endif() +endif() + set(ADBC_GO_PACKAGE_INIT [=[ get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH) @@ -184,36 +199,88 @@ function(add_go_lib GO_MOD_DIR GO_LIBNAME) list(APPEND GO_ENV_VARS "GOARCH=arm64") endif() - add_custom_command(OUTPUT "${LIBOUT_SHARED}.${ADBC_FULL_SO_VERSION}" - WORKING_DIRECTORY ${GO_MOD_DIR} - DEPENDS ${ARG_SOURCES} - COMMAND ${CMAKE_COMMAND} -E env ${GO_ENV_VARS} ${GO_BIN} build - ${GO_BUILD_TAGS} "${GO_BUILD_FLAGS}" -o - ${LIBOUT_SHARED}.${ADBC_FULL_SO_VERSION} - -buildmode=c-shared ${GO_LDFLAGS} . - COMMAND ${CMAKE_COMMAND} -E remove -f - "${LIBOUT_SHARED}.${ADBC_SO_VERSION}.0.h" - COMMENT "Building Go Shared lib ${GO_LIBNAME}" - COMMAND_EXPAND_LISTS) + # Set platform-specific library output paths and generate header name + if(WIN32) + # On Windows, Go generates .dll and .lib with the base name (no version suffix) + set(GO_OUTPUT_LIB "${LIBOUT_SHARED}") + set(GO_OUTPUT_HEADER "${CMAKE_CURRENT_BINARY_DIR}/${GO_LIBNAME}.h") + set(LIBIMPLIB_SHARED + "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_IMPORT_LIBRARY_PREFIX}${GO_LIBNAME}${CMAKE_IMPORT_LIBRARY_SUFFIX}" + ) + set(LIBDEF_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${GO_LIBNAME}.def") + else() + # On Unix-like systems, use version suffixes + set(GO_OUTPUT_LIB "${LIBOUT_SHARED}.${ADBC_FULL_SO_VERSION}") + set(GO_OUTPUT_HEADER "${LIBOUT_SHARED}.${ADBC_SO_VERSION}.0.h") + endif() - add_custom_command(OUTPUT "${LIBOUT_SHARED}.${ADBC_SO_VERSION}" "${LIBOUT_SHARED}" - DEPENDS "${LIBOUT_SHARED}.${ADBC_FULL_SO_VERSION}" - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E create_symlink - "${LIB_NAME_SHARED}.${ADBC_FULL_SO_VERSION}" - "${LIB_NAME_SHARED}.${ADBC_SO_VERSION}" - COMMAND ${CMAKE_COMMAND} -E create_symlink - "${LIB_NAME_SHARED}.${ADBC_SO_VERSION}" - "${LIB_NAME_SHARED}") - - add_custom_target(${GO_LIBNAME}_target ALL - DEPENDS "${LIBOUT_SHARED}.${ADBC_FULL_SO_VERSION}" - "${LIBOUT_SHARED}.${ADBC_SO_VERSION}" "${LIBOUT_SHARED}") + # Common Go build command + set(GO_BUILD_COMMAND + ${CMAKE_COMMAND} -E env ${GO_ENV_VARS} ${GO_BIN} build ${GO_BUILD_TAGS} + "${GO_BUILD_FLAGS}" -o ${GO_OUTPUT_LIB} -buildmode=c-shared ${GO_LDFLAGS} .) + + if(WIN32) + if(GENDEF_BIN AND DLLTOOL_BIN) + # Generate import library using gendef + dlltool + add_custom_command(OUTPUT "${GO_OUTPUT_LIB}" "${LIBIMPLIB_SHARED}" + WORKING_DIRECTORY ${GO_MOD_DIR} + DEPENDS ${ARG_SOURCES} + COMMAND ${GO_BUILD_COMMAND} + COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_CURRENT_BINARY_DIR} + ${GENDEF_BIN} ${GO_OUTPUT_LIB} -a + COMMAND ${DLLTOOL_BIN} --input-def ${LIBDEF_OUTPUT} --dllname + ${LIB_NAME_SHARED} --output-lib ${LIBIMPLIB_SHARED} + COMMAND ${CMAKE_COMMAND} -E remove -f "${GO_OUTPUT_HEADER}" + COMMENT "Building Go Shared lib ${GO_LIBNAME}" + COMMAND_EXPAND_LISTS) + set(TARGET_DEPENDS "${GO_OUTPUT_LIB}" "${LIBIMPLIB_SHARED}") + else() + # Fallback: try to build without import library generation + add_custom_command(OUTPUT "${GO_OUTPUT_LIB}" + WORKING_DIRECTORY ${GO_MOD_DIR} + DEPENDS ${ARG_SOURCES} + COMMAND ${GO_BUILD_COMMAND} + COMMAND ${CMAKE_COMMAND} -E remove -f "${GO_OUTPUT_HEADER}" + COMMENT "Building Go Shared lib ${GO_LIBNAME}" + COMMAND_EXPAND_LISTS) + set(TARGET_DEPENDS "${GO_OUTPUT_LIB}") + endif() + else() + add_custom_command(OUTPUT "${GO_OUTPUT_LIB}" + WORKING_DIRECTORY ${GO_MOD_DIR} + DEPENDS ${ARG_SOURCES} + COMMAND ${GO_BUILD_COMMAND} + COMMAND ${CMAKE_COMMAND} -E remove -f "${GO_OUTPUT_HEADER}" + COMMENT "Building Go Shared lib ${GO_LIBNAME}" + COMMAND_EXPAND_LISTS) + + add_custom_command(OUTPUT "${LIBOUT_SHARED}.${ADBC_SO_VERSION}" "${LIBOUT_SHARED}" + DEPENDS "${GO_OUTPUT_LIB}" + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E create_symlink + "${LIB_NAME_SHARED}.${ADBC_FULL_SO_VERSION}" + "${LIB_NAME_SHARED}.${ADBC_SO_VERSION}" + COMMAND ${CMAKE_COMMAND} -E create_symlink + "${LIB_NAME_SHARED}.${ADBC_SO_VERSION}" + "${LIB_NAME_SHARED}") + set(TARGET_DEPENDS "${GO_OUTPUT_LIB}" "${LIBOUT_SHARED}.${ADBC_SO_VERSION}" + "${LIBOUT_SHARED}") + endif() + + # Create custom target with platform-specific dependencies + add_custom_target(${GO_LIBNAME}_target ALL DEPENDS ${TARGET_DEPENDS}) + + # Create imported library with platform-specific properties add_library(${GO_LIBNAME}_shared SHARED IMPORTED GLOBAL) - set_target_properties(${GO_LIBNAME}_shared - PROPERTIES IMPORTED_LOCATION - "${LIBOUT_SHARED}.${ADBC_FULL_SO_VERSION}" - IMPORTED_SONAME "${LIB_NAME_SHARED}") + if(WIN32) + set_target_properties(${GO_LIBNAME}_shared + PROPERTIES IMPORTED_LOCATION "${LIBOUT_SHARED}" + IMPORTED_IMPLIB "${LIBIMPLIB_SHARED}") + else() + set_target_properties(${GO_LIBNAME}_shared + PROPERTIES IMPORTED_LOCATION "${GO_OUTPUT_LIB}" + IMPORTED_SONAME "${LIB_NAME_SHARED}") + endif() add_dependencies(${GO_LIBNAME}_shared ${GO_LIBNAME}_target) if(ARG_OUTPUTS) list(APPEND ${ARG_OUTPUTS} ${GO_LIBNAME}_shared) @@ -259,8 +326,7 @@ function(add_go_lib GO_MOD_DIR GO_LIBNAME) ${CMAKE_INSTALL_LIBDIR}) endif() if(WIN32) - # This symlink doesn't get installed - install(FILES "${LIBOUT_SHARED}.${ADBC_SO_VERSION}" TYPE BIN) + install(FILES "${LIBIMPLIB_SHARED}" TYPE LIB) else() install(FILES "${LIBOUT_SHARED}" "${LIBOUT_SHARED}.${ADBC_SO_VERSION}" TYPE LIB) endif() diff --git a/c/driver/postgresql/CMakeLists.txt b/c/driver/postgresql/CMakeLists.txt index e044a20d14..3689f4569a 100644 --- a/c/driver/postgresql/CMakeLists.txt +++ b/c/driver/postgresql/CMakeLists.txt @@ -62,6 +62,20 @@ foreach(LIB_TARGET ${ADBC_LIBRARIES}) if(NOT ADBC_DEFINE_COMMON_ENTRYPOINTS) target_compile_definitions(${LIB_TARGET} PRIVATE ${ADBC_TARGET_COMPILE_DEFINITIONS}) endif() + + # On Windows, install libpq.dll and its dependencies alongside the driver + if(WIN32 AND CMAKE_VERSION VERSION_GREATER_EQUAL "3.21") + install(RUNTIME_DEPENDENCY_SET + ${LIB_TARGET}_runtime_deps + PRE_EXCLUDE_REGEXES + "api-ms-" + "ext-ms-" + POST_EXCLUDE_REGEXES + ".*system32/.*\\.dll" + DESTINATION + ${RUNTIME_INSTALL_DIR}) + install(TARGETS ${LIB_TARGET} RUNTIME_DEPENDENCY_SET ${LIB_TARGET}_runtime_deps) + endif() endforeach() if(ADBC_TEST_LINKAGE STREQUAL "shared") diff --git a/c/driver/sqlite/CMakeLists.txt b/c/driver/sqlite/CMakeLists.txt index 4c6bb1f1a7..46e3a9ca52 100644 --- a/c/driver/sqlite/CMakeLists.txt +++ b/c/driver/sqlite/CMakeLists.txt @@ -68,6 +68,20 @@ foreach(LIB_TARGET ${ADBC_LIBRARIES}) if(NOT ADBC_DEFINE_COMMON_ENTRYPOINTS) target_compile_definitions(${LIB_TARGET} PRIVATE ${ADBC_TARGET_COMPILE_DEFINITIONS}) endif() + + # On Windows, install sqlite3.dll alongside the driver + if(WIN32 AND CMAKE_VERSION VERSION_GREATER_EQUAL "3.21") + install(RUNTIME_DEPENDENCY_SET + ${LIB_TARGET}_runtime_deps + PRE_EXCLUDE_REGEXES + "api-ms-" + "ext-ms-" + POST_EXCLUDE_REGEXES + ".*system32/.*\\.dll" + DESTINATION + ${RUNTIME_INSTALL_DIR}) + install(TARGETS ${LIB_TARGET} RUNTIME_DEPENDENCY_SET ${LIB_TARGET}_runtime_deps) + endif() endforeach() include(CheckTypeSize) diff --git a/c/driver/sqlite/statement_reader.c b/c/driver/sqlite/statement_reader.c index 554bdaf203..0df5d8e4f6 100644 --- a/c/driver/sqlite/statement_reader.c +++ b/c/driver/sqlite/statement_reader.c @@ -451,8 +451,15 @@ AdbcStatusCode InternalAdbcSqliteBinderBindNext(struct AdbcSqliteBinder* binder, } case NANOARROW_TYPE_TIMESTAMP: { struct ArrowSchemaView bind_schema_view; +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4244) // ArrowErrorCode to AdbcStatusCode conversion +#endif RAISE_NA(ArrowSchemaViewInit(&bind_schema_view, binder->schema.children[col], &arrow_error)); +#ifdef _MSC_VER +#pragma warning(pop) +#endif enum ArrowTimeUnit unit = bind_schema_view.time_unit; int64_t value = ArrowArrayViewGetIntUnsafe(binder->batch.children[col], binder->next_row); diff --git a/c/driver/sqlite/vcpkg.json b/c/driver/sqlite/vcpkg.json new file mode 100644 index 0000000000..a355b8de4a --- /dev/null +++ b/c/driver/sqlite/vcpkg.json @@ -0,0 +1,7 @@ +{ + "name": "adbc-driver-sqlite", + "version-string": "1.0.0a0", + "dependencies": [ + "sqlite3" + ] +} diff --git a/c/driver_manager/CMakeLists.txt b/c/driver_manager/CMakeLists.txt index 7057cc78e8..198c3f9792 100644 --- a/c/driver_manager/CMakeLists.txt +++ b/c/driver_manager/CMakeLists.txt @@ -99,7 +99,7 @@ if(ADBC_BUILD_TESTS) if(ADBC_DRIVER_SQLITE) target_compile_definitions(adbc-driver-manager-test - PRIVATE ADBC_DRIVER_MANAGER_TEST_LIB="${CMAKE_BINARY_DIR}/driver/sqlite/libadbc_driver_sqlite${CMAKE_SHARED_LIBRARY_SUFFIX}" + PRIVATE ADBC_DRIVER_MANAGER_TEST_LIB="${CMAKE_BINARY_DIR}/driver/sqlite/${CMAKE_SHARED_LIBRARY_PREFIX}adbc_driver_sqlite${CMAKE_SHARED_LIBRARY_SUFFIX}" ) endif() if(ADBC_DRIVER_MANAGER_TEST_MANIFEST_USER_LEVEL) diff --git a/c/driver_manager/adbc_driver_manager.cc b/c/driver_manager/adbc_driver_manager.cc index 3943fd81b0..8aa43c8944 100644 --- a/c/driver_manager/adbc_driver_manager.cc +++ b/c/driver_manager/adbc_driver_manager.cc @@ -449,8 +449,8 @@ SearchPaths GetEnvPaths(const char_type* env_var) { std::string path(path_var); #endif // _WIN32 SearchPaths paths; - for (auto path : InternalAdbcParsePath(path)) { - paths.emplace_back(SearchPathSource::kEnv, path); + for (auto search_path : InternalAdbcParsePath(path)) { + paths.emplace_back(SearchPathSource::kEnv, search_path); } return paths; } @@ -1451,7 +1451,7 @@ std::string InternalAdbcDriverManagerDefaultEntrypoint(const std::string& driver // if pos == npos this is the entire filename std::string token = filename.substr(prev, pos - prev); // capitalize first letter - token[0] = std::toupper(static_cast(token[0])); + token[0] = static_cast(std::toupper(static_cast(token[0]))); entrypoint += token; diff --git a/c/validation/adbc_validation.h b/c/validation/adbc_validation.h index fad84137e6..b0be6ac87c 100644 --- a/c/validation/adbc_validation.h +++ b/c/validation/adbc_validation.h @@ -39,6 +39,8 @@ using SqlInfoValue = std::variant; /// \brief Configuration for driver-specific behavior. class DriverQuirks { public: + virtual ~DriverQuirks() = default; + /// \brief Do any initialization between New and Init. virtual AdbcStatusCode SetupDatabase(struct AdbcDatabase* database, struct AdbcError* error) const { @@ -253,6 +255,8 @@ class DriverQuirks { class DatabaseTest { public: + virtual ~DatabaseTest() = default; + virtual const DriverQuirks* quirks() const = 0; void SetUpTest(); @@ -275,6 +279,8 @@ class DatabaseTest { class ConnectionTest { public: + virtual ~ConnectionTest() = default; + virtual const DriverQuirks* quirks() const = 0; void SetUpTest(); @@ -355,6 +361,8 @@ class ConnectionTest { class StatementTest { public: + virtual ~StatementTest() = default; + virtual const DriverQuirks* quirks() const = 0; void SetUpTest(); diff --git a/c/validation/adbc_validation_statement.cc b/c/validation/adbc_validation_statement.cc index ae5ef518a3..b05e425f7c 100644 --- a/c/validation/adbc_validation_statement.cc +++ b/c/validation/adbc_validation_statement.cc @@ -1358,23 +1358,27 @@ void StatementTest::TestSqlIngestTemporaryAppend() { ASSERT_THAT((MakeBatch(&schema.value, &array.value, &na_error, {0, 1, 2})), IsOkErrno()); - Handle statement; - ASSERT_THAT(AdbcStatementNew(&connection, &statement.value, &error), + Handle append_statement; + ASSERT_THAT(AdbcStatementNew(&connection, &append_statement.value, &error), IsOkStatus(&error)); - ASSERT_THAT(AdbcStatementSetOption(&statement.value, ADBC_INGEST_OPTION_TEMPORARY, - ADBC_OPTION_VALUE_ENABLED, &error), - IsOkStatus(&error)); - ASSERT_THAT(AdbcStatementSetOption(&statement.value, ADBC_INGEST_OPTION_MODE, + ASSERT_THAT( + AdbcStatementSetOption(&append_statement.value, ADBC_INGEST_OPTION_TEMPORARY, + ADBC_OPTION_VALUE_ENABLED, &error), + IsOkStatus(&error)); + ASSERT_THAT(AdbcStatementSetOption(&append_statement.value, ADBC_INGEST_OPTION_MODE, ADBC_INGEST_OPTION_MODE_APPEND, &error), IsOkStatus(&error)); - ASSERT_THAT(AdbcStatementSetOption(&statement.value, ADBC_INGEST_OPTION_TARGET_TABLE, - name.c_str(), &error), - IsOkStatus(&error)); - ASSERT_THAT(AdbcStatementBind(&statement.value, &array.value, &schema.value, &error), - IsOkStatus(&error)); - ASSERT_THAT(AdbcStatementExecuteQuery(&statement.value, nullptr, nullptr, &error), - IsOkStatus(&error)); + ASSERT_THAT( + AdbcStatementSetOption(&append_statement.value, ADBC_INGEST_OPTION_TARGET_TABLE, + name.c_str(), &error), + IsOkStatus(&error)); + ASSERT_THAT( + AdbcStatementBind(&append_statement.value, &array.value, &schema.value, &error), + IsOkStatus(&error)); + ASSERT_THAT( + AdbcStatementExecuteQuery(&append_statement.value, nullptr, nullptr, &error), + IsOkStatus(&error)); } // Append to the normal table @@ -1533,23 +1537,27 @@ void StatementTest::TestSqlIngestTemporaryReplace() { {"foo", "bar", std::nullopt})), IsOkErrno()); - Handle statement; - ASSERT_THAT(AdbcStatementNew(&connection, &statement.value, &error), + Handle append_statement; + ASSERT_THAT(AdbcStatementNew(&connection, &append_statement.value, &error), IsOkStatus(&error)); - ASSERT_THAT(AdbcStatementSetOption(&statement.value, ADBC_INGEST_OPTION_TEMPORARY, - ADBC_OPTION_VALUE_ENABLED, &error), - IsOkStatus(&error)); - ASSERT_THAT(AdbcStatementSetOption(&statement.value, ADBC_INGEST_OPTION_MODE, + ASSERT_THAT( + AdbcStatementSetOption(&append_statement.value, ADBC_INGEST_OPTION_TEMPORARY, + ADBC_OPTION_VALUE_ENABLED, &error), + IsOkStatus(&error)); + ASSERT_THAT(AdbcStatementSetOption(&append_statement.value, ADBC_INGEST_OPTION_MODE, ADBC_INGEST_OPTION_MODE_APPEND, &error), IsOkStatus(&error)); - ASSERT_THAT(AdbcStatementSetOption(&statement.value, ADBC_INGEST_OPTION_TARGET_TABLE, - name.c_str(), &error), - IsOkStatus(&error)); - ASSERT_THAT(AdbcStatementBind(&statement.value, &array.value, &schema.value, &error), - IsOkStatus(&error)); - ASSERT_THAT(AdbcStatementExecuteQuery(&statement.value, nullptr, nullptr, &error), - IsOkStatus(&error)); + ASSERT_THAT( + AdbcStatementSetOption(&append_statement.value, ADBC_INGEST_OPTION_TARGET_TABLE, + name.c_str(), &error), + IsOkStatus(&error)); + ASSERT_THAT( + AdbcStatementBind(&append_statement.value, &array.value, &schema.value, &error), + IsOkStatus(&error)); + ASSERT_THAT( + AdbcStatementExecuteQuery(&append_statement.value, nullptr, nullptr, &error), + IsOkStatus(&error)); } { diff --git a/c/validation/adbc_validation_util.h b/c/validation/adbc_validation_util.h index d3eab643d1..f0071062f5 100644 --- a/c/validation/adbc_validation_util.h +++ b/c/validation/adbc_validation_util.h @@ -432,8 +432,8 @@ void CompareArray(struct ArrowArrayView* array, } else if constexpr (std::is_same>::value) { struct ArrowBufferView view = ArrowArrayViewGetBytesUnsafe(array, i); ASSERT_EQ(v->size(), view.size_bytes); - for (int64_t i = 0; i < view.size_bytes; i++) { - ASSERT_EQ((*v)[i], std::byte{view.data.as_uint8[i]}); + for (int64_t byte_i = 0; byte_i < view.size_bytes; byte_i++) { + ASSERT_EQ((*v)[byte_i], std::byte{view.data.as_uint8[byte_i]}); } } else if constexpr (std::is_same::value) { ASSERT_NE(array->buffer_views[1].data.data, nullptr); diff --git a/c/vcpkg.json b/c/vcpkg.json new file mode 100644 index 0000000000..8d0e0c4b82 --- /dev/null +++ b/c/vcpkg.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", + "name": "arrow-adbc", + "version-string": "1.9.0-SNAPSHOT", + "dependencies": [ + "libpq", + "sqlite3" + ], + "$comment": "We can update builtin-baseline by 'vcpkg x-update-baseline'", + "builtin-baseline": "9e4b86d4871c47f125e9f631de07d963fcd38389" +} diff --git a/ci/scripts/cpp_build.ps1 b/ci/scripts/cpp_build.ps1 index 926fd7235c..8bdb6272b5 100755 --- a/ci/scripts/cpp_build.ps1 +++ b/ci/scripts/cpp_build.ps1 @@ -31,30 +31,44 @@ $BuildDriverSnowflake = ($BuildAll -and (-not ($env:BUILD_DRIVER_SNOWFLAKE -eq " $BuildDriverSqlite = ($BuildAll -and (-not ($env:BUILD_DRIVER_SQLITE -eq "0"))) -or ($env:BUILD_DRIVER_SQLITE -eq "1") $BuildDriverManagerUserConfigTest = ($env:BUILD_DRIVER_MANAGER_USER_CONFIG_TEST -eq "1") +$BuildType = if ($env:CMAKE_BUILD_TYPE) { $env:CMAKE_BUILD_TYPE } else { "Release" } function Build-Subproject { New-Item -ItemType Directory -Force -Path $BuildDir | Out-Null Push-Location $BuildDir + # Note: Args are factored out to make it simple to override + # DCMAKE_TOOLCHAIN_FILE for VCPKG # XXX(apache/arrow-adbc#616): must use Release build to line up with gtest - cmake ` - $(Join-Path $SourceDir "c\") ` - -DADBC_BUILD_SHARED=ON ` - -DADBC_BUILD_STATIC=OFF ` - -DADBC_BUILD_TESTS=ON ` - -DADBC_DRIVER_MANAGER="$($BuildDriverManager)" ` - -DADBC_DRIVER_BIGQUERY="$($BuildDriverBigQuery)" ` - -DADBC_DRIVER_FLIGHTSQL="$($BuildDriverFlightSql)" ` - -DADBC_DRIVER_POSTGRESQL="$($BuildDriverPostgreSQL)" ` - -DADBC_DRIVER_SNOWFLAKE="$($BuildDriverSnowflake)" ` - -DADBC_DRIVER_SQLITE="$($BuildDriverSqlite)" ` - -DCMAKE_BUILD_TYPE=Release ` - -DCMAKE_INSTALL_PREFIX="$($InstallDir)" ` - -DCMAKE_VERBOSE_MAKEFILE=ON ` - -DADBC_DRIVER_MANAGER_TEST_MANIFEST_USER_LEVEL="$($BuildDriverManagerUserConfigTest)" + $cmakeArgs = @( + $(Join-Path $SourceDir "c\"), + "-DADBC_BUILD_SHARED=ON", + "-DADBC_BUILD_STATIC=OFF", + "-DADBC_BUILD_TESTS=ON", + "-DADBC_DRIVER_MANAGER=$($BuildDriverManager)", + "-DADBC_DRIVER_BIGQUERY=$($BuildDriverBigQuery)", + "-DADBC_DRIVER_FLIGHTSQL=$($BuildDriverFlightSql)", + "-DADBC_DRIVER_POSTGRESQL=$($BuildDriverPostgreSQL)", + "-DADBC_DRIVER_SNOWFLAKE=$($BuildDriverSnowflake)", + "-DADBC_DRIVER_SQLITE=$($BuildDriverSqlite)", + "-DCMAKE_BUILD_TYPE=$BuildType", + "-DCMAKE_INSTALL_PREFIX=$($InstallDir)", + "-DCMAKE_VERBOSE_MAKEFILE=ON", + "-DADBC_DRIVER_MANAGER_TEST_MANIFEST_USER_LEVEL=$($BuildDriverManagerUserConfigTest)" + ) + + # If VCPKG_ROOT is set, set DCMAKE_TOOLCHAIN_FILE to it + if ($env:VCPKG_ROOT) { + $vcpkgToolchain = "$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" + $cmakeArgs += "-DCMAKE_TOOLCHAIN_FILE=$vcpkgToolchain" + } + + & cmake $cmakeArgs if (-not $?) { exit 1 } - cmake --build . --target install -j + # Build with configuration for multi-config generators (like MSVC) + # For single-config generators (like Ninja), --config is ignored + cmake --build . --target install --config $BuildType -j if (-not $?) { exit 1 } Pop-Location diff --git a/go/adbc/drivermgr/adbc_driver_manager.cc b/go/adbc/drivermgr/adbc_driver_manager.cc index 3943fd81b0..8aa43c8944 100644 --- a/go/adbc/drivermgr/adbc_driver_manager.cc +++ b/go/adbc/drivermgr/adbc_driver_manager.cc @@ -449,8 +449,8 @@ SearchPaths GetEnvPaths(const char_type* env_var) { std::string path(path_var); #endif // _WIN32 SearchPaths paths; - for (auto path : InternalAdbcParsePath(path)) { - paths.emplace_back(SearchPathSource::kEnv, path); + for (auto search_path : InternalAdbcParsePath(path)) { + paths.emplace_back(SearchPathSource::kEnv, search_path); } return paths; } @@ -1451,7 +1451,7 @@ std::string InternalAdbcDriverManagerDefaultEntrypoint(const std::string& driver // if pos == npos this is the entire filename std::string token = filename.substr(prev, pos - prev); // capitalize first letter - token[0] = std::toupper(static_cast(token[0])); + token[0] = static_cast(std::toupper(static_cast(token[0]))); entrypoint += token;