Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions c/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ if(ADBC_DRIVER_SNOWFLAKE)
add_subdirectory(driver/snowflake)
endif()

if(ADBC_DRIVER_DB2)
install(FILES "${REPOSITORY_ROOT}/c/include/arrow-adbc/driver/db2.h"
DESTINATION include/arrow-adbc/driver)
add_subdirectory(driver/db2)
endif()

if(ADBC_INTEGRATION_DUCKDB)
add_subdirectory(integration/duckdb)
endif()
Expand Down Expand Up @@ -145,6 +151,10 @@ LIBRARY=$<TARGET_FILE:adbc_driver_${TARGET}_shared>" ${Python3_EXECUTABLE} -m pi
if(ADBC_DRIVER_SNOWFLAKE)
adbc_install_python_package(snowflake)
endif()

if(ADBC_DRIVER_DB2)
adbc_install_python_package(db2)
endif()
endif()

validate_config()
Expand Down
1 change: 1 addition & 0 deletions c/cmake_modules/DefineOptions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
define_option(ADBC_DRIVER_POSTGRESQL "Build the PostgreSQL driver" OFF)
define_option(ADBC_DRIVER_SQLITE "Build the SQLite driver" OFF)
define_option(ADBC_DRIVER_SNOWFLAKE "Build the Snowflake driver" OFF)
define_option(ADBC_DRIVER_DB2 "Build the IBM DB2 driver" OFF)

define_option(ADBC_INTEGRATION_DUCKDB "Build the test suite for DuckDB" OFF)

Expand Down
26 changes: 26 additions & 0 deletions c/driver/db2/AdbcDriverDb2Config.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# 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.

@PACKAGE_INIT@

include(CMakeFindDependencyMacro)

set(ADBC_VERSION "@ADBC_VERSION@")

include("${CMAKE_CURRENT_LIST_DIR}/AdbcDriverDb2Targets.cmake")

check_required_components(AdbcDriverDb2)
124 changes: 124 additions & 0 deletions c/driver/db2/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# 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.

# --- Locate the IBM Db2 CLI driver --------------------------------------------
#
# We rely on the CLI driver shipped with IBM Data Server Driver Package
# (sometimes called the Db2 "clidriver"), located either via DB2_HOME (set by
# IBM tooling), IBM_DB_HOME (set by `pip install ibm_db`), or the standard
# CMake variables. Generic ODBC libraries are intentionally not used as a
# fallback: Db2-specific behavior (extended SQLSTATEs, native error codes)
# requires the IBM CLI driver.

set(DB2_HOME_HINTS "")
if(DEFINED ENV{DB2_HOME})
list(APPEND DB2_HOME_HINTS "$ENV{DB2_HOME}")
endif()
if(DEFINED ENV{IBM_DB_HOME})
list(APPEND DB2_HOME_HINTS "$ENV{IBM_DB_HOME}")
endif()

find_path(DB2_INCLUDE_DIR
NAMES sqlcli1.h
HINTS ${DB2_HOME_HINTS}
PATH_SUFFIXES include
DOC "IBM Db2 CLI header directory (contains sqlcli1.h)")

if(WIN32)
set(_db2_lib_names db2cli64 db2cli)
else()
set(_db2_lib_names db2)
endif()

find_library(DB2_LIBRARY
NAMES ${_db2_lib_names}
HINTS ${DB2_HOME_HINTS}
PATH_SUFFIXES lib lib64
DOC "IBM Db2 CLI library")

if(NOT DB2_INCLUDE_DIR OR NOT DB2_LIBRARY)
message(FATAL_ERROR
"IBM Db2 CLI driver not found. Install the IBM Data Server Driver "
"Package (clidriver) and set DB2_HOME (or IBM_DB_HOME) to its root, "
"or set DB2_INCLUDE_DIR and DB2_LIBRARY directly.")
endif()

message(STATUS "Db2 CLI include: ${DB2_INCLUDE_DIR}")
message(STATUS "Db2 CLI library: ${DB2_LIBRARY}")

add_arrow_lib(adbc_driver_db2
SOURCES
connection.cc
database.cc
db2.cc
error.cc
OUTPUTS
ADBC_LIBRARIES
CMAKE_PACKAGE_NAME
AdbcDriverDb2
PKG_CONFIG_NAME
adbc-driver-db2
SHARED_LINK_FLAGS
${ADBC_LINK_FLAGS}
SHARED_LINK_LIBS
${DB2_LIBRARY}
adbc_driver_common
adbc_driver_framework
STATIC_LINK_LIBS
${DB2_LIBRARY}
adbc_driver_common
adbc_driver_framework)

foreach(LIB_TARGET ${ADBC_LIBRARIES})
target_compile_definitions(${LIB_TARGET} PRIVATE ADBC_EXPORTING)
target_include_directories(${LIB_TARGET} SYSTEM
PRIVATE ${REPOSITORY_ROOT}/c/
${REPOSITORY_ROOT}/c/include/
${DB2_INCLUDE_DIR}
${REPOSITORY_ROOT}/c/driver)

if(NOT ADBC_DEFINE_COMMON_ENTRYPOINTS)
target_compile_definitions(${LIB_TARGET} PRIVATE ${ADBC_TARGET_COMPILE_DEFINITIONS})
endif()
endforeach()

if(ADBC_TEST_LINKAGE STREQUAL "shared")
set(TEST_LINK_LIBS adbc_driver_db2_shared)
else()
set(TEST_LINK_LIBS adbc_driver_db2_static)
endif()

if(ADBC_BUILD_TESTS)
add_test_case(driver_db2_test
PREFIX
adbc
EXTRA_LABELS
driver-db2
SOURCES
db2_test.cc
EXTRA_LINK_LIBS
adbc_driver_common
adbc_validation
${TEST_LINK_LIBS})
target_compile_features(adbc-driver-db2-test PRIVATE cxx_std_17)
target_include_directories(adbc-driver-db2-test SYSTEM
PRIVATE ${REPOSITORY_ROOT}/c/
${REPOSITORY_ROOT}/c/include/
${DB2_INCLUDE_DIR}
${REPOSITORY_ROOT}/c/driver)
adbc_configure_target(adbc-driver-db2-test)
endif()
56 changes: 56 additions & 0 deletions c/driver/db2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<!---
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.
-->

# ADBC IBM Db2 Driver

An ADBC driver for [IBM Db2 LUW](https://www.ibm.com/products/db2),
implemented on top of the Db2 CLI / ODBC API.

> **Status:** Initial scope is connection management only. The driver
> can establish, configure, and tear down connections, and surfaces
> Db2 SQLSTATEs as ADBC error codes. Statement execution, metadata
> APIs, transactions, and bulk ingestion will be added in follow-up
> pull requests.
## Building

Requires the IBM Data Server Driver Package (the so-called
"clidriver"), which provides `sqlcli1.h` and `libdb2`. Generic ODBC
driver managers (unixODBC, iODBC) are not used as a fallback because
the driver relies on Db2-specific SQLSTATE classes for error mapping.

Point CMake at the clidriver via `DB2_HOME` (set by IBM tooling) or
`IBM_DB_HOME` (set by `pip install ibm_db`):

```bash
export DB2_HOME=/opt/ibm/db2/V11.5/clidriver # or IBM_DB_HOME=...
cmake -S c -B build -DADBC_DRIVER_DB2=ON
cmake --build build
```

## Testing

The C++ test suite expects a reachable Db2 instance. Set
`ADBC_DB2_TEST_URI` to a Db2 CLI connection string and run:

```bash
ctest --test-dir build -L driver-db2 --output-on-failure
```

When `ADBC_DB2_TEST_URI` is unset, all DB-bound tests skip.
27 changes: 27 additions & 0 deletions c/driver/db2/adbc-driver-db2.pc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# 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.

prefix=@CMAKE_INSTALL_PREFIX@
includedir=@ADBC_PKG_CONFIG_INCLUDEDIR@
libdir=@ADBC_PKG_CONFIG_LIBDIR@

Name: Apache Arrow Database Connectivity (ADBC) DB2 driver
Description: The ADBC DB2 driver provides an ADBC driver for IBM DB2.
URL: https://github.com/apache/arrow-adbc
Version: @ADBC_VERSION@
Libs: -L${libdir} -ladbc_driver_db2
Cflags: -I${includedir}
60 changes: 60 additions & 0 deletions c/driver/db2/connection.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// 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.

#include "connection.h"

#include "error.h"

namespace adbc::db2 {

Status Db2Connection::InitImpl(void* parent) {
database_ = reinterpret_cast<Db2Database*>(parent);

UNWRAP_RESULT(hdbc_, database_->AllocConnection());

// SQLDriverConnect mutates the input string; copy to a stable buffer.
const std::string& conn_str = database_->connection_string();
SQLCHAR out_str[1024];
SQLSMALLINT out_len = 0;
SQLRETURN rc = SQLDriverConnect(
hdbc_, /*WindowHandle=*/nullptr,
const_cast<SQLCHAR*>(reinterpret_cast<const SQLCHAR*>(conn_str.c_str())),
static_cast<SQLSMALLINT>(conn_str.size()), out_str, sizeof(out_str), &out_len,
Comment on lines +29 to +36
SQL_DRIVER_NOPROMPT);
UNWRAP_STATUS(CheckRc(SQL_HANDLE_DBC, hdbc_, rc, "SQLDriverConnect"));

// ADBC's contract is autocommit-on by default; set it explicitly so the
// driver behavior is independent of the underlying CLI configuration.
rc = SQLSetConnectAttr(hdbc_, SQL_ATTR_AUTOCOMMIT,
reinterpret_cast<SQLPOINTER>(SQL_AUTOCOMMIT_ON), 0);
UNWRAP_STATUS(CheckRc(SQL_HANDLE_DBC, hdbc_, rc, "SQLSetConnectAttr(AUTOCOMMIT)"));

return status::Ok();
}

Status Db2Connection::ReleaseImpl() {
if (hdbc_ != SQL_NULL_HDBC) {
SQLDisconnect(hdbc_);
if (database_ != nullptr) {
database_->FreeConnection(hdbc_);
}
hdbc_ = SQL_NULL_HDBC;
}
return status::Ok();
}

} // namespace adbc::db2
61 changes: 61 additions & 0 deletions c/driver/db2/connection.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// 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.

#pragma once

#include <string_view>

#include <arrow-adbc/adbc.h>

#include "db2_odbc.h"

#define ADBC_FRAMEWORK_USE_FMT
#include "driver/framework/connection.h"
#include "driver/framework/status.h"

#include "database.h"

namespace adbc::db2 {

using driver::Option;
using driver::Result;
using driver::Status;
namespace status = adbc::driver::status;

/// \brief ADBC connection for IBM Db2.
///
/// Connection lifecycle wraps a single SQLHDBC obtained from the
/// owning Db2Database. Statement execution, metadata retrieval, and
/// transaction management are intentionally not implemented in this
/// initial driver scope and will be added in subsequent pull requests
/// (the framework default returns ADBC_STATUS_NOT_IMPLEMENTED).
class Db2Connection : public driver::Connection<Db2Connection> {
public:
[[maybe_unused]] constexpr static std::string_view kErrorPrefix = "[DB2]";

Db2Connection() = default;
~Db2Connection() = default;

Status InitImpl(void* parent);
Status ReleaseImpl();

private:
Db2Database* database_ = nullptr;
SQLHDBC hdbc_ = SQL_NULL_HDBC;
};

} // namespace adbc::db2
Loading