Skip to content
Merged
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
12 changes: 9 additions & 3 deletions .github/workflows/cpp-linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,20 @@ jobs:
persist-credentials: false
- name: Install dependencies
shell: bash
run: sudo apt-get update && sudo apt-get install -y libcurl4-openssl-dev
run: |
sudo apt-get update
sudo apt-get install -y libcurl4-openssl-dev libsqlite3-dev libpq-dev default-libmysqlclient-dev
- name: Run build
env:
CC: gcc-14
CXX: g++-14
run: |
mkdir build && cd build
cmake .. -G Ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake .. -G Ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DICEBERG_BUILD_SQL_CATALOG=ON \
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It would be nice to enhance this in the future by enabling specific modules only when their paths are affected.

-DICEBERG_SQL_SQLITE=ON \
-DICEBERG_SQL_POSTGRESQL=ON \
-DICEBERG_SQL_MYSQL=ON
cmake --build .
- uses: cpp-linter/cpp-linter-action@0f6d1b8d7e38b584cbee606eb23d850c217d54f8 # v2.15.1
id: linter
Expand All @@ -66,7 +72,7 @@ jobs:
database: build
verbosity: 'debug'
# need '-fno-builtin-std-forward_like', see https://github.com/llvm/llvm-project/issues/101614
extra-args: '-std=c++23 -I$PWD/src -I$PWD/build/src -fno-builtin-std-forward_like'
extra-args: '-std=c++23 -I$PWD/src -I$PWD/build/src -I$PWD/build/_deps/sqlpp23-src/include -I/usr/include/postgresql -I/usr/include/mysql -fno-builtin-std-forward_like'
- name: Fail fast?!
if: steps.linter.outputs.checks-failed != 0
run: |
Expand Down
111 changes: 111 additions & 0 deletions .github/workflows/sql_catalog_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# 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.

name: SQL Catalog Tests

on:
push:
branches:
- '**'
- '!dependabot/**'
tags:
- '**'
pull_request:
types: [opened, synchronize, reopened, ready_for_review]

concurrency:
group: ${{ github.repository }}-${{ github.head_ref || github.sha }}-${{ github.workflow }}
cancel-in-progress: true

permissions:
contents: read

env:
ICEBERG_HOME: /tmp/iceberg

jobs:
sql-catalog:
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }}
name: SQL Catalog (${{ matrix.title }})
runs-on: ${{ matrix.runs-on }}
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
include:
- title: AMD64 Ubuntu 24.04
runs-on: ubuntu-24.04
CC: gcc-14
CXX: g++-14
cmake_build_type: Debug
cmake_extra_args: ""
- title: AArch64 macOS 26
runs-on: macos-26
cmake_build_type: Debug
cmake_extra_args: ""
- title: AMD64 Windows 2025
runs-on: windows-2025
cmake_build_type: Release
cmake_extra_args: -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake
steps:
- name: Checkout iceberg-cpp
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up MSVC Developer Command Prompt
if: ${{ startsWith(matrix.runs-on, 'windows') }}
uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
with:
arch: x64
- name: Install dependencies on Ubuntu
if: ${{ startsWith(matrix.runs-on, 'ubuntu') }}
shell: bash
run: sudo apt-get update && sudo apt-get install -y libsqlite3-dev
- name: Set Ubuntu Compilers
if: ${{ startsWith(matrix.runs-on, 'ubuntu') }}
run: |
echo "CC=${{ matrix.CC }}" >> $GITHUB_ENV
echo "CXX=${{ matrix.CXX }}" >> $GITHUB_ENV
- name: Install dependencies on macOS
if: ${{ startsWith(matrix.runs-on, 'macos') }}
shell: bash
run: |
brew install fmt
echo "CMAKE_PREFIX_PATH=$(brew --prefix fmt):${CMAKE_PREFIX_PATH:-}" >> "${GITHUB_ENV}"
- name: Install dependencies on Windows
if: ${{ startsWith(matrix.runs-on, 'windows') }}
shell: pwsh
run: |
vcpkg install zlib:x64-windows nlohmann-json:x64-windows nanoarrow:x64-windows roaring:x64-windows sqlite3:x64-windows
- name: Configure Iceberg
shell: bash
run: |
cmake -S . -B build -G Ninja \
-DCMAKE_INSTALL_PREFIX="${ICEBERG_HOME}" \
-DCMAKE_BUILD_TYPE=${{ matrix.cmake_build_type }} \
-DICEBERG_BUILD_STATIC=ON \
-DICEBERG_BUILD_SHARED=ON \
-DICEBERG_BUILD_REST=OFF \
-DICEBERG_BUILD_SQL_CATALOG=ON \
-DICEBERG_SQL_SQLITE=ON \
${{ matrix.cmake_extra_args }}
- name: Build SQL catalog tests
shell: bash
run: cmake --build build --target sql_catalog_test
- name: Run SQL catalog tests
shell: bash
run: ctest --test-dir build -R '^sql_catalog_test$' --output-on-failure -C ${{ matrix.cmake_build_type }}
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ cmake-build-release/
.vscode
.cache

# mkdocs generated output
/mkdocs/site/
/mkdocs/docs/api/

# devcontainer
.devcontainer/*
!.devcontainer/*.template
Expand Down
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ option(ICEBERG_BUILD_BUNDLE "Build the battery included library" ON)
option(ICEBERG_BUILD_REST "Build rest catalog client" ON)
option(ICEBERG_BUILD_REST_INTEGRATION_TESTS "Build rest catalog integration tests" OFF)
option(ICEBERG_BUILD_HIVE "Build hive (HMS) catalog client" OFF)
option(ICEBERG_BUILD_SQL_CATALOG "Build SQL catalog client" OFF)
# Built-in SQL catalog database connectors. Disable all of them to build a SQL
# catalog that only works with a user-supplied CatalogStore.
option(ICEBERG_SQL_SQLITE "Build the SQLite connector for the SQL catalog" OFF)
option(ICEBERG_SQL_POSTGRESQL "Build the PostgreSQL connector for the SQL catalog" OFF)
option(ICEBERG_SQL_MYSQL "Build the MySQL connector for the SQL catalog" OFF)
option(ICEBERG_S3 "Build with S3 support" OFF)
option(ICEBERG_ENABLE_ASAN "Enable Address Sanitizer" OFF)
option(ICEBERG_ENABLE_UBSAN "Enable Undefined Behavior Sanitizer" OFF)
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ cmake --install build
| `ICEBERG_BUILD_REST` | `ON` | Build REST catalog client |
| `ICEBERG_BUILD_REST_INTEGRATION_TESTS` | `OFF` | Build REST catalog integration tests |
| `ICEBERG_BUILD_HIVE` | `OFF` | Build Hive (HMS) catalog client |
| `ICEBERG_BUILD_SQL_CATALOG` | `OFF` | Build SQL catalog client |
| `ICEBERG_SQL_SQLITE` | `OFF` | Build the SQLite connector for the SQL catalog |
| `ICEBERG_SQL_POSTGRESQL` | `OFF` | Build the PostgreSQL connector for the SQL catalog |
| `ICEBERG_SQL_MYSQL` | `OFF` | Build the MySQL connector for the SQL catalog |
| `ICEBERG_ENABLE_ASAN` | `OFF` | Enable Address Sanitizer |
| `ICEBERG_ENABLE_UBSAN` | `OFF` | Enable Undefined Behavior Sanitizer |

Expand Down
88 changes: 88 additions & 0 deletions cmake_modules/IcebergThirdpartyToolchain.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,90 @@ function(resolve_cpr_dependency)
PARENT_SCOPE)
endfunction()

# ----------------------------------------------------------------------
# SQL catalog database connectors (sqlpp23)
#
# The SQL catalog talks to the database through a semantic `CatalogStore`
# interface (src/iceberg/catalog/sql/catalog_store.h). The built-in stores are
# implemented on top of sqlpp23, a header-only, compile-time type-safe SQL
# library. Each connector is opt-in and pulls in its native client library:
#
# ICEBERG_SQL_SQLITE -> sqlpp23::sqlite3 (SQLite::SQLite3)
# ICEBERG_SQL_POSTGRESQL -> sqlpp23::postgresql (PostgreSQL::PostgreSQL)
# ICEBERG_SQL_MYSQL -> sqlpp23::mysql (MySQL::MySQL)
#
# Users who inject their own `CatalogStore` do not need sqlpp23 or any connector.

function(resolve_sql_catalog_dependencies)
if(NOT ICEBERG_SQL_SQLITE
AND NOT ICEBERG_SQL_POSTGRESQL
AND NOT ICEBERG_SQL_MYSQL)
message(STATUS "SQL catalog: no built-in connectors enabled")
return()
endif()

if(CMAKE_VERSION VERSION_LESS 3.28)
message(FATAL_ERROR "Built-in SQL catalog connectors require CMake >= 3.28; disable "
"ICEBERG_SQL_SQLITE, ICEBERG_SQL_POSTGRESQL, and ICEBERG_SQL_MYSQL "
"or use CMake >= 3.28")
endif()

prepare_fetchcontent()

# sqlpp23 requires C++23 and CMake >= 3.28.
set(CMAKE_CXX_STANDARD 23)
# Header-only consumption; do not scan for C++20 modules.
set(BUILD_WITH_MODULES OFF)
# Let sqlpp23 verify and locate the native client libraries for the connectors
# we enable, exposing the sqlpp23::<connector> targets.
set(BUILD_SQLITE3_CONNECTOR ${ICEBERG_SQL_SQLITE})
set(BUILD_POSTGRESQL_CONNECTOR ${ICEBERG_SQL_POSTGRESQL})
set(BUILD_MYSQL_CONNECTOR ${ICEBERG_SQL_MYSQL})

if(DEFINED ENV{ICEBERG_SQLPP23_URL})
set(SQLPP23_URL "$ENV{ICEBERG_SQLPP23_URL}")
else()
set(SQLPP23_URL "https://github.com/rbock/sqlpp23/archive/refs/tags/0.69.tar.gz")
endif()

fetchcontent_declare(sqlpp23
${FC_DECLARE_COMMON_OPTIONS}
URL ${SQLPP23_URL}
FIND_PACKAGE_ARGS
NAMES
Sqlpp23
CONFIG)
fetchcontent_makeavailable(sqlpp23)

# sqlpp23 locates the native client libraries within its own subdirectory
# scope. Re-run find_package with GLOBAL so the imported targets are visible
# where the SQL catalog library is defined, and record them as downstream
# system dependencies for the installed interface.
if(ICEBERG_SQL_SQLITE)
find_package(SQLite3 REQUIRED GLOBAL)
list(APPEND ICEBERG_SYSTEM_DEPENDENCIES SQLite3)
message(STATUS "SQL catalog: SQLite connector enabled (sqlpp23::sqlite3)")
endif()
if(ICEBERG_SQL_POSTGRESQL)
find_package(PostgreSQL REQUIRED GLOBAL)
list(APPEND ICEBERG_SYSTEM_DEPENDENCIES PostgreSQL)
message(STATUS "SQL catalog: PostgreSQL connector enabled (sqlpp23::postgresql)")
endif()
if(ICEBERG_SQL_MYSQL)
# MySQL has no standard CMake module; reuse the one sqlpp23 ships.
if(sqlpp23_SOURCE_DIR)
list(APPEND CMAKE_MODULE_PATH "${sqlpp23_SOURCE_DIR}/cmake/modules")
endif()
find_package(MySQL REQUIRED GLOBAL)
list(APPEND ICEBERG_SYSTEM_DEPENDENCIES MySQL)
message(STATUS "SQL catalog: MySQL connector enabled (sqlpp23::mysql)")
endif()

set(ICEBERG_SYSTEM_DEPENDENCIES
${ICEBERG_SYSTEM_DEPENDENCIES}
PARENT_SCOPE)
endfunction()

# ----------------------------------------------------------------------
# Zstd

Expand Down Expand Up @@ -539,3 +623,7 @@ endif()
if(ICEBERG_BUILD_REST)
resolve_cpr_dependency()
endif()

if(ICEBERG_BUILD_SQL_CATALOG)
resolve_sql_catalog_dependencies()
endif()
5 changes: 5 additions & 0 deletions mkdocs/docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ cmake --install build
| `ICEBERG_BUILD_BUNDLE` | `ON` | Build the battery-included library |
| `ICEBERG_BUILD_REST` | `ON` | Build REST catalog client |
| `ICEBERG_BUILD_REST_INTEGRATION_TESTS` | `OFF` | Build REST catalog integration tests |
| `ICEBERG_BUILD_HIVE` | `OFF` | Build Hive (HMS) catalog client |
| `ICEBERG_BUILD_SQL_CATALOG` | `OFF` | Build SQL catalog client |
| `ICEBERG_SQL_SQLITE` | `OFF` | Build the SQLite connector for the SQL catalog |
| `ICEBERG_SQL_POSTGRESQL` | `OFF` | Build the PostgreSQL connector for the SQL catalog |
| `ICEBERG_SQL_MYSQL` | `OFF` | Build the MySQL connector for the SQL catalog |
| `ICEBERG_ENABLE_ASAN` | `OFF` | Enable Address Sanitizer |
| `ICEBERG_ENABLE_UBSAN` | `OFF` | Enable Undefined Behavior Sanitizer |

Expand Down
69 changes: 69 additions & 0 deletions mkdocs/docs/sql-catalog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<!--
~ 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.
-->

# SQL Catalog

`SqlCatalog` implements the Iceberg `Catalog` API on top of a relational
database. Its schema is compatible with the Apache Iceberg Java `JdbcCatalog`
and stores catalog rows in `iceberg_tables` and
`iceberg_namespace_properties`.

## Build

The SQL catalog is currently available through the CMake build only. Meson does
not build or install it yet.

Enable the catalog at configure time:

```bash
cmake -S . -B build -DICEBERG_BUILD_SQL_CATALOG=ON
```

Built-in connectors are optional:

| CMake option | Default | Native dependency |
|--------------|---------|-------------------|
| `ICEBERG_SQL_SQLITE` | `OFF` | SQLite3 |
| `ICEBERG_SQL_POSTGRESQL` | `OFF` | libpq |
| `ICEBERG_SQL_MYSQL` | `OFF` | libmysqlclient |

The built-in connectors use
[sqlpp23](https://github.com/rbock/sqlpp23), which is fetched by CMake when a
connector is enabled. Projects can also supply their own `CatalogStore`
implementation and disable all built-in connectors.

## Usage

```cpp
#include "iceberg/catalog/sql/sql_catalog.h"

using iceberg::sql::SqlCatalog;
using iceberg::sql::SqlCatalogConfig;

SqlCatalogConfig config{
.name = "prod",
.uri = "/var/lib/iceberg/catalog.db",
.warehouse_location = "s3://my-bucket/warehouse",
};

auto catalog = SqlCatalog::MakeSqliteCatalog(config, file_io).value();
```

Connector factories are always declared in the public headers. If a connector
was not built, its factory returns `ErrorKind::kNotSupported`.
1 change: 1 addition & 0 deletions mkdocs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ nav:
- Release Process: release-process.md
- Verify a Release Candidate: verify-rc.md
- API Documentation: api/index.html
- SQL Catalog: sql-catalog.md

extra:
social:
Expand Down
4 changes: 4 additions & 0 deletions src/iceberg/catalog/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ endif()
if(ICEBERG_BUILD_HIVE)
add_subdirectory(hive)
endif()

if(ICEBERG_BUILD_SQL_CATALOG)
add_subdirectory(sql)
endif()
Loading
Loading