ClickHouse driver for MATLAB. Speaks the native TCP protocol (not HTTP) via a MEX binding around clickhouse-cpp.
- Native TCP protocol with optional TLS
- Native-protocol block compression (LZ4 by default, ZSTD or none selectable)
- Auto-reconnect and protocol-level retry, tunable via
maxRetries - Bidirectional conversion:
queryreturns a MATLABtable;insertaccepts atableor scalar struct of arrays - Broad ClickHouse type coverage (see Supported types)
NaN↔NULLfor numerics,missing↔NULLfor strings
- MATLAB: R2023b – R2025a tested in CI; newer releases likely work
- CMake: ≥ 3.20
- C++ compiler: g++-9 recommended — avoids GLIBCXX mismatches with MATLAB's bundled libstdc++. Override with
-DCMAKE_CXX_COMPILER=...for a different compiler. - Platform: Linux, macOS, Windows. MEX outputs are
.mexa64/.mexmaca64/.mexw64respectively.
The repository uses a git submodule for clickhouse-cpp. Clone with submodules:
git clone --recurse-submodules <repo-url>
# or, if already cloned:
git submodule update --init --recursiveFrom MATLAB:
buildFrom a shell:
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DMatlab_ROOT_DIR=$(matlabroot)
cmake --build build --config Release
cp build/clickhouse_mex.mex* src/Add src/ to your MATLAB path before use:
addpath(fullfile(pwd, 'src'))% Connect
c = ClickHouseClient('localhost', 9000, 'default', '');
% Query — returns a MATLAB table
t = c.query('SELECT number, toString(number) AS s FROM numbers(10)');
% Create a table and insert rows from a MATLAB table
c.query(['CREATE TABLE IF NOT EXISTS demo (' ...
' id Int32, val Float64' ...
') ENGINE = MergeTree() ORDER BY id']);
data = table(int32([1;2;3]), [1.1;2.2;3.3], 'VariableNames', {'id','val'});
c.insert('demo', data);
% Cleanup
delete(c);Block compression on the native protocol is set per connection via
options.compression and defaults to Compression.LZ4:
% Use ZSTD (higher ratio, more CPU) instead of the LZ4 default
opts = struct('compression', Compression.ZSTD);
c = ClickHouseClient('localhost', 9000, 'default', '', opts);
% ...or disable compression entirely
opts = struct('compression', Compression.None);
c = ClickHouseClient('localhost', 9000, 'default', '', opts);ClickHouseClient(host, port, user, password, options) accepts an options struct:
| Field | Type | Default | Notes |
|---|---|---|---|
tls.enabled |
logical | false |
Enable TLS. Typically used with port 9440. |
tls.skip_verification |
logical | false |
Disable certificate verification (dev only). |
tls.ca_file |
string | "" |
Path to CA bundle for verification. |
maxRetries |
integer | 3 |
Retry attempts on query/insert failure. 0 = fail-fast (no ping-before-query, no protocol-level retry, no MATLAB-level retry). |
compression |
Compression enum |
Compression.LZ4 |
Native-protocol block compression: Compression.None, Compression.LZ4, or Compression.ZSTD. Default changed to LZ4 — set Compression.None to restore the previous no-compression behavior. |
settings |
containers.Map | — | Parsed but not applied — clickhouse-cpp's ClientOptions does not expose per-connection settings. |
useragent |
string | — | Parsed but not applied — ClientOptions does not expose SetClientName. |
| ClickHouse | MATLAB |
|---|---|
Int8–Int64, UInt8–UInt64 |
matching native integer class |
Float32 / Float64 |
single / double |
String |
string (query) / string or cellstr (insert) |
FixedString(N) |
string / cellstr |
Date, Date32, DateTime |
double (POSIX seconds) |
DateTime64(p) |
double (POSIX seconds with sub-second precision) |
Decimal32(S), Decimal64(S), Decimal128(S), Decimal(P,S) |
double |
Enum8, Enum16 |
string |
IPv4, IPv6 |
string |
LowCardinality(T) |
mapping of inner type T |
Nullable(T) |
inner-type mapping with NaN or missing for nulls |
Array(T) |
cell array of inner-type vectors |
./test/run_tests.sh # default: ClickHouse 25.3
./test/run_tests.sh 25.8 # pin a version
./test/run_tests.sh latest # latest stableThe script builds the MEX, spins up a ClickHouse container in Docker, and runs run_all_tests in MATLAB batch mode.
A small set of socket-recovery tests in TestRetry require CAP_NET_ADMIN (root) to issue ss -K; they auto-skip when not run as root.
CI runs the test suite on every push to main and on pull requests across a matrix of ClickHouse versions (see .github/workflows/ci.yml).
options.settingsandoptions.useragentare silently ignored — see above.queryaccumulates the entire result set in MEX memory before producing the MATLABtable. Peak memory ≈ 2× result size. For very large results, paginate withLIMIT … OFFSET …orSAMPLE.insertissues oneDESCRIBE TABLEround-trip per call to infer column types. Batch many rows into a singleinsertrather than looping with small batches.
Apache 2.0. See LICENSE.