Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
2872b0c
Are we making it?
borodark Dec 2, 2025
ed71f5a
make makes a cube-driver. Before Phase 2.3
borodark Dec 2, 2025
c7cab31
we are done, accordng to Claudius Codisius
borodark Dec 3, 2025
30ed199
Actualy now we are done, accordng to Claudius Codisius
borodark Dec 3, 2025
f1f7bac
test the power of three with this branch
borodark Dec 3, 2025
1eb9201
-1 warning
borodark Dec 3, 2025
03a8205
no warnings
borodark Dec 3, 2025
720f482
test arrow with real cube
borodark Dec 8, 2025
07b7d20
try to go navive
borodark Dec 9, 2025
77c89a2
before intergration
borodark Dec 9, 2025
2934434
some milestone
borodark Dec 9, 2025
c46c1d6
maybe FlatBuffers
borodark Dec 9, 2025
2ee266a
WIP before FlatBuggers
borodark Dec 10, 2025
420404e
Stage I with FlatBuffers
borodark Dec 10, 2025
04088da
make builds with FlatBufffers
borodark Dec 10, 2025
f8d452a
pandas worked -> Explorier next
borodark Dec 11, 2025
4e60d6e
reflections posted to linkedin
borodark Dec 11, 2025
103d21a
before testing with Explorer
borodark Dec 11, 2025
6061337
add cmake files
borodark Dec 13, 2025
1dc1dc8
somewhat better
borodark Dec 13, 2025
51d436e
good place: take I
borodark Dec 13, 2025
da2bd46
GC
borodark Dec 13, 2025
2738c61
still works
borodark Dec 13, 2025
7ac68fb
and then there were IX
borodark Dec 13, 2025
203854f
I like to have an option
borodark Dec 13, 2025
d1c3fd4
to ignore
borodark Dec 13, 2025
214857e
GC
borodark Dec 13, 2025
c22d74a
:facepalm
borodark Dec 13, 2025
c5f5aeb
builds so far ...
borodark Dec 13, 2025
171299c
a few more
borodark Dec 13, 2025
bfe40fd
and then there were VIII
borodark Dec 13, 2025
ab380dc
not do a harm
borodark Dec 13, 2025
9599859
I more
borodark Dec 13, 2025
88615b4
new magic spell
borodark Dec 13, 2025
10de006
actualy works
borodark Dec 13, 2025
8f52cc5
libflatbuffers-dev
borodark Dec 13, 2025
73e05d4
brut force
borodark Dec 13, 2025
99233a2
:facepalm
borodark Dec 13, 2025
a2886ec
:facepalm
borodark Dec 13, 2025
1d5986c
still brute force
borodark Dec 13, 2025
a2f6f11
maybe Cmake changes is enoug
borodark Dec 13, 2025
a300069
not breaking things
borodark Dec 13, 2025
7b6fefd
cmake kung-fu
borodark Dec 13, 2025
0a8b145
OSXiest way
borodark Dec 13, 2025
86d8326
CMAKE kung-fu
borodark Dec 13, 2025
7c9469c
dig
borodark Dec 13, 2025
f45f405
deeper
borodark Dec 13, 2025
3ed6863
deeper
borodark Dec 13, 2025
ae949be
deeper
borodark Dec 13, 2025
39c648e
disable debug print
borodark Dec 14, 2025
e57d8c3
more cleanup
borodark Dec 15, 2025
86e7c65
formatted
borodark Dec 15, 2025
5b6c353
potential segfault fix
borodark Dec 16, 2025
84de2d7
Integer types fixes
borodark Dec 16, 2025
a348159
after phase 1
borodark Dec 16, 2025
e093329
dates
borodark Dec 16, 2025
e8b7459
c++ tests first
borodark Dec 16, 2025
2edef91
most of the types are handled
borodark Dec 16, 2025
9fb73be
we beleave _all integers are created equal_ ...
borodark Dec 16, 2025
c65ef3f
no segfault
borodark Dec 18, 2025
eb3a790
no debug
borodark Dec 18, 2025
c28b539
libflatbuffers2 perhaps
borodark Dec 19, 2025
c758c60
libflatbuffers perhaps
borodark Dec 19, 2025
0b013df
to build with CI
borodark Dec 19, 2025
edbac64
pkg-config
borodark Dec 19, 2025
6191758
FlatBuffers >= 2.0 from source
borodark Dec 19, 2025
d943692
ADBC Client → Arrow IPC (4445) → cubesqld → Pre-agg Matching → CubeSt…
borodark Dec 25, 2025
322633b
refined/tested with current cube fork
borodark Dec 26, 2025
354b6a3
consistent terminology that accurately reflects Cube as an ADBC Serve…
borodark Dec 27, 2025
02511ab
ADBC supports MEASURE syntax with or without AS
borodark Dec 28, 2025
b41344b
ADBC supports MEASURE syntax with or without AS with filtering
borodark Dec 28, 2025
39bbb8f
Cleanup, moving cube adbc to separeate repo: the ducks way
borodark Jan 9, 2026
4b86f35
test with cube driver in it's own repo
borodark Jan 9, 2026
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
17 changes: 16 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@ jobs:
otp-version: "26.2"
elixir-version: "1.15.8"

- name: Install FlatBuffers 2.0.8 from source
run: |
sudo apt-get update && sudo apt install -y build-essential cmake
cd /tmp
wget https://github.com/google/flatbuffers/archive/v2.0.8.tar.gz
tar -xzf v2.0.8.tar.gz
cd flatbuffers-2.0.8
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local
make -j$(nproc)
sudo make install
sudo ldconfig

- name: Compile and Test
run: |
mix deps.get
Expand Down Expand Up @@ -70,7 +82,7 @@ jobs:

macos:
if: contains(github.event.pull_request.labels.*.name, 'skip ci') != true
runs-on: macos-13
runs-on: macos-14
env:
MIX_ENV: test
OTP_VERSION: "26.2"
Expand All @@ -80,6 +92,9 @@ jobs:
- name: Checkout
uses: actions/checkout@v4

- name: Install Flatbuffers using Homebrew
run: brew install gcc flatbuffers

- name: Install OTP and Elixir
run: |
curl -fsSO https://elixir-lang.org/install.sh
Expand Down
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,14 @@ adbc-*.tar

# checksum
checksum.exs

# Make temporary

/cmake_adbc/
/cmake_adbc_nif/
**/CMakeFiles/*
cmake_install.cmake
CTestTestfile.cmake

# Build artifacts
/priv/
10 changes: 10 additions & 0 deletions 3rd_party/apache-arrow-adbc/c/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ if(ADBC_DRIVER_BIGQUERY)
add_subdirectory(driver/bigquery)
endif()

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

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

if(ADBC_DRIVER_CUBE)
adbc_install_python_package(cube)
endif()
endif()

validate_config()
Expand Down
181 changes: 181 additions & 0 deletions 3rd_party/apache-arrow-adbc/c/driver/postgresql/copy/statement.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
// 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 <cstring>
#include <memory>
#include <string>
#include <vector>

#include <arrow-adbc/adbc.h>
#include <libpq-fe.h>
#include <nanoarrow/nanoarrow.h>

#include "copy/reader.h"
#include "driver/common/utils.h"
#include "postgres_type.h"

#define ADBC_POSTGRESQL_OPTION_BATCH_SIZE_HINT_BYTES \
"adbc.postgresql.batch_size_hint_bytes"

#define ADBC_POSTGRESQL_OPTION_USE_COPY "adbc.postgresql.use_copy"

namespace adbcpq {
class PostgresConnection;
class PostgresStatement;

constexpr static int64_t kDefaultBatchSizeHintBytes = 16777216;

/// \brief An ArrowArrayStream that reads tuples from a PGresult.
class TupleReader final : public std::enable_shared_from_this<TupleReader> {
public:
TupleReader(PGconn* conn)
: status_(ADBC_STATUS_OK),
error_(ADBC_ERROR_INIT),
conn_(conn),
result_(nullptr),
pgbuf_(nullptr),
copy_reader_(nullptr),
row_id_(-1),
batch_size_hint_bytes_(kDefaultBatchSizeHintBytes),
is_finished_(false) {
ArrowErrorInit(&na_error_);
data_.data.as_char = nullptr;
data_.size_bytes = 0;
}

int GetSchema(struct ArrowSchema* out);
int GetNext(struct ArrowArray* out);
const char* last_error() const { return error_.message; }
void Release();
void ExportTo(struct ArrowArrayStream* stream);

static const struct AdbcError* ErrorFromArrayStream(struct ArrowArrayStream* stream,
AdbcStatusCode* status);

private:
friend class PostgresStatement;

int GetCopyData();
int AppendRowAndFetchNext();
int BuildOutput(struct ArrowArray* out);

static int GetSchemaTrampoline(struct ArrowArrayStream* self, struct ArrowSchema* out);
static int GetNextTrampoline(struct ArrowArrayStream* self, struct ArrowArray* out);
static const char* GetLastErrorTrampoline(struct ArrowArrayStream* self);
static void ReleaseTrampoline(struct ArrowArrayStream* self);

AdbcStatusCode status_;
struct AdbcError error_;
struct ArrowError na_error_;
PGconn* conn_;
PGresult* result_;
char* pgbuf_;
struct ArrowBufferView data_;
std::unique_ptr<PostgresCopyStreamReader> copy_reader_;
int64_t row_id_;
int64_t batch_size_hint_bytes_;
bool is_finished_;
};

class PostgresStatement {
public:
PostgresStatement()
: connection_(nullptr),
query_(),
prepared_(false),
use_copy_(-1),
reader_(nullptr),
batch_size_hint_bytes_(kDefaultBatchSizeHintBytes) {
std::memset(&bind_, 0, sizeof(bind_));
}

// ---------------------------------------------------------------------
// ADBC API implementation

AdbcStatusCode Bind(struct ArrowArray* values, struct ArrowSchema* schema,
struct AdbcError* error);
AdbcStatusCode Bind(struct ArrowArrayStream* stream, struct AdbcError* error);
AdbcStatusCode Cancel(struct AdbcError* error);
AdbcStatusCode ExecuteQuery(struct ArrowArrayStream* stream, int64_t* rows_affected,
struct AdbcError* error);
AdbcStatusCode ExecuteSchema(struct ArrowSchema* schema, struct AdbcError* error);
AdbcStatusCode GetOption(const char* key, char* value, size_t* length,
struct AdbcError* error);
AdbcStatusCode GetOptionBytes(const char* key, uint8_t* value, size_t* length,
struct AdbcError* error);
AdbcStatusCode GetOptionDouble(const char* key, double* value, struct AdbcError* error);
AdbcStatusCode GetOptionInt(const char* key, int64_t* value, struct AdbcError* error);
AdbcStatusCode GetParameterSchema(struct ArrowSchema* schema, struct AdbcError* error);
AdbcStatusCode New(struct AdbcConnection* connection, struct AdbcError* error);
AdbcStatusCode Prepare(struct AdbcError* error);
AdbcStatusCode Release(struct AdbcError* error);
AdbcStatusCode SetOption(const char* key, const char* value, struct AdbcError* error);
AdbcStatusCode SetOptionBytes(const char* key, const uint8_t* value, size_t length,
struct AdbcError* error);
AdbcStatusCode SetOptionDouble(const char* key, double value, struct AdbcError* error);
AdbcStatusCode SetOptionInt(const char* key, int64_t value, struct AdbcError* error);
AdbcStatusCode SetSqlQuery(const char* query, struct AdbcError* error);

// ---------------------------------------------------------------------
// Helper methods

void ClearResult();
AdbcStatusCode CreateBulkTable(const std::string& current_schema,
const struct ArrowSchema& source_schema,
std::string* escaped_table,
std::string* escaped_field_list,
struct AdbcError* error);
AdbcStatusCode ExecuteIngest(struct ArrowArrayStream* stream, int64_t* rows_affected,
struct AdbcError* error);
AdbcStatusCode ExecuteBind(struct ArrowArrayStream* stream, int64_t* rows_affected,
struct AdbcError* error);

private:
std::shared_ptr<PostgresTypeResolver> type_resolver_;
std::shared_ptr<PostgresConnection> connection_;

// Query state
std::string query_;
bool prepared_;
struct ArrowArrayStream bind_;

// Bulk ingest state
enum class IngestMode {
kCreate,
kAppend,
kReplace,
kCreateAppend,
};

// Options
int use_copy_;

struct {
std::string db_schema;
std::string target;
IngestMode mode = IngestMode::kCreate;
bool temporary = false;
} ingest_;

std::shared_ptr<TupleReader> reader_;
int64_t batch_size_hint_bytes_;

int UseCopy();
};
} // namespace adbcpq
19 changes: 18 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,19 @@ if(NOT DEFINED PRIV_DIR)
endif()
message(STATUS "Using PRIV_DIR: ${PRIV_DIR}")

if(UNIX AND NOT APPLE)
# Find the FlatBuffers package
include_directories(/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/cmake/flatbuffers)
find_package(FlatBuffers CONFIG REQUIRED)
# Print the directory where the config file was found
if(FlatBuffers_FOUND)
message(STATUS "FlatBuffers found in directory: ${FlatBuffers_DIR}")
message(STATUS "FlatBuffers config file path: ${FlatBuffers_CONFIG}")
else()
message(FATAL_ERROR "Could not find FlatBuffers package")
endif()
endif()

if(DEFINED ERTS_INCLUDE_DIR AND NOT "${ERTS_INCLUDE_DIR}" STREQUAL "")
set(ERTS_INCLUDE_DIR "${ERTS_INCLUDE_DIR}")
else()
Expand All @@ -35,7 +48,11 @@ if(DEFINED ENV{TARGET_GCC_FLAGS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{TARGET_GCC_FLAGS}")
endif()

message(STATUS "CMAKE_TOOLCHAIN_FILE: ${CMAKE_TOOLCHAIN_FILE}")
if(DEFINED CMAKE_TOOLCHAIN_FILE AND NOT "${CMAKE_TOOLCHAIN_FILE}" STREQUAL "")
message(STATUS "CMAKE_TOOLCHAIN_FILE: ${CMAKE_TOOLCHAIN_FILE}")
else()
message(STATUS "CMAKE_TOOLCHAIN_FILE: not set")
endif()

find_package(AdbcDriverManager REQUIRED PATHS "${PRIV_DIR}/" NO_DEFAULT_PATH)
include_directories("${PRIV_DIR}/include")
Expand Down
27 changes: 14 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ ifdef CMAKE_TOOLCHAIN_FILE
endif

CMAKE_BUILD_TYPE ?= Release
DEFAULT_JOBS ?= 1
CMAKE_ADBC_BUILD_DIR = $(MIX_APP_PATH)/cmake_adbc
CMAKE_ADBC_OPTIONS ?= ""
CMAKE_ADBC_NIF_BUILD_DIR = $(MIX_APP_PATH)/cmake_adbc_nif
CMAKE_ADBC_NIF_OPTIONS ?= ""
DEFAULT_JOBS ?= 22
BUILD_DIR = $(MIX_APP_PATH)/_build
CMAKE_ADBC_BUILD_DIR = $(BUILD_DIR)/cmake/adbc
CMAKE_ADBC_OPTIONS ?=
CMAKE_ADBC_NIF_BUILD_DIR = $(BUILD_DIR)/cmake/nif
CMAKE_ADBC_NIF_OPTIONS ?=
MAKE_BUILD_FLAGS ?= -j$(DEFAULT_JOBS)

.DEFAULT_GLOBAL := build
Expand All @@ -51,8 +52,7 @@ build: $(NIF_SO_REL)
clean:
@rm -rf "$(NIF_SO_REL)"
@rm -rf "$(NIF_SO)"
@rm -rf "$(CMAKE_ADBC_NIF_BUILD_DIR)"
@rm -rf "$(CMAKE_ADBC_BUILD_DIR)"
@rm -rf "$(BUILD_DIR)"
@rm -rf "$(PRIV_DIR)"

priv_dir:
Expand All @@ -70,6 +70,7 @@ adbc: priv_dir
cmake --no-warn-unused-cli \
-DADBC_BUILD_SHARED="ON" \
-DADBC_DRIVER_MANAGER="ON" \
-DADBC_DRIVER_CUBE="OFF" \
-DADBC_DRIVER_POSTGRESQL="OFF" \
-DADBC_DRIVER_SQLITE="OFF" \
-DADBC_DRIVER_FLIGHTSQL="OFF" \
Expand All @@ -89,12 +90,12 @@ $(NIF_SO_REL): priv_dir adbc $(C_SRC_REL)/adbc_nif_resource.hpp $(C_SRC_REL)/adb
@ mkdir -p "$(CMAKE_ADBC_NIF_BUILD_DIR)" && \
cd "$(CMAKE_ADBC_NIF_BUILD_DIR)" && \
cmake --no-warn-unused-cli \
-D CMAKE_BUILD_TYPE="$(CMAKE_BUILD_TYPE)" \
-D C_SRC="$(C_SRC)" \
-D ADBC_SRC="$(ADBC_SRC)" \
-D MIX_APP_PATH="$(MIX_APP_PATH)" \
-D PRIV_DIR="$(PRIV_DIR)" \
-D ERTS_INCLUDE_DIR="$(ERTS_INCLUDE_DIR)" \
-DCMAKE_BUILD_TYPE="$(CMAKE_BUILD_TYPE)" \
-DC_SRC="$(C_SRC)" \
-DADBC_SRC="$(ADBC_SRC)" \
-DMIX_APP_PATH="$(MIX_APP_PATH)" \
-DPRIV_DIR="$(PRIV_DIR)" \
$(if $(ERTS_INCLUDE_DIR),-DERTS_INCLUDE_DIR="$(ERTS_INCLUDE_DIR)") \
$(CMAKE_CONFIGURE_FLAGS) $(CMAKE_ADBC_NIF_OPTIONS) "$(shell pwd)" && \
make "$(MAKE_BUILD_FLAGS)" && \
cp "$(CMAKE_ADBC_NIF_BUILD_DIR)/adbc_nif.so" "$(NIF_SO)"
4 changes: 2 additions & 2 deletions c_src/adbc_arrow_schema.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ static int get_map_schema(ErlNifEnv *env, struct ArrowSchema * schema, uint64_t
return erlang::nif::error(env, "invalid ArrowSchema (map), its entries n_children != 2");
}

ERL_NIF_TERM key_schema, value_schema;
ERL_NIF_TERM key_schema = kAtomNil, value_schema = kAtomNil;
int kv = 0;
for (int64_t child_i = 0; child_i < 2; child_i++) {
struct ArrowSchema * entry_schema = entries_schema->children[child_i];
Expand Down Expand Up @@ -141,7 +141,7 @@ static int get_map_schema(ErlNifEnv *env, struct ArrowSchema * schema, uint64_t
}

ERL_NIF_TERM map_kv_keys[] = { kAtomKey, kAtomValue };
ERL_NIF_TERM map_kv_values[] = { key_schema, value_schema };
ERL_NIF_TERM map_kv_values[] = { key_schema, value_schema }; // Now guaranteed to be initialized
// only fail if there are duplicated keys
// so we don't need to check the return value
enif_make_map_from_arrays(env, map_kv_keys, map_kv_values, 2, &map_kv_schema);
Expand Down
2 changes: 1 addition & 1 deletion c_src/adbc_nif_resource.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ template <typename T> struct NifRes {
error = erlang::nif::error(env, "cannot allocate Nif resource\n");
return res;
}
memset(&res->val, 0, sizeof(val_type));
res->val = val_type();
res->private_data = nullptr;
return res;
}
Expand Down
Loading
Loading