Skip to content

MDEV-39834: Add TidesDB 9 storage engine#5166

Open
guycipher wants to merge 17 commits into
MariaDB:11.4from
tidesdb:tidesdb-engine
Open

MDEV-39834: Add TidesDB 9 storage engine#5166
guycipher wants to merge 17 commits into
MariaDB:11.4from
tidesdb:tidesdb-engine

Conversation

@guycipher

Copy link
Copy Markdown

The libtidesdb C library is vendored under storage/tidesdb/libtidesdb/ and compiled into a static archive that is statically linked into the loadable plugin module, mirroring storage/rocksdb, the engine is self-contained and needs no system-installed libtidesdb. include/providers is removed from the
engine's include dirs so the bundled zstd/lz4/snappy link directly instead of routing through MariaDB's compression-provider plugins.

For cross-version portability, spatial- and fulltext-index detection uses the HA_SPATIAL / HA_FULLTEXT key flags (with a HA_SPATIAL/HA_FULLTEXT -> *_legacy rename shim) rather than KEY::algorithm, which older servers leave
unset; my_global.h is included before handler.h so the server typedefs it needs are defined.

Adds the tidesdb mysql-test suite covering CRUD, MVCC and pessimistic locking, transactions/savepoints, isolation levels, compression, encryption, TTL, full-text, spatial, partitioning, object-store offload and crash/durability. The vector test auto-skips where the VECTOR type is unavailable (before 11.7).

Builds and full mysql-test suite shows green on MariaDB 11.4 (LTS) through to 13.0.2

The libtidesdb C library is vendored under storage/tidesdb/libtidesdb/ and
compiled into a static archive that is statically linked into the loadable
plugin module, mirroring storage/rocksdb, the engine is self-contained and
needs no system-installed libtidesdb. include/providers is removed from
the
engine's include dirs so the bundled zstd/lz4/snappy link directly instead
of routing through MariaDB's compression-provider plugins.

For cross-version portability, spatial- and fulltext-index detection uses
the HA_SPATIAL / HA_FULLTEXT key flags (with a HA_SPATIAL/HA_FULLTEXT ->
*_legacy rename shim) rather than KEY::algorithm, which older servers
leave
unset; my_global.h is included before handler.h so the server typedefs it
needs are defined.

Adds the tidesdb mysql-test suite covering CRUD, MVCC and
pessimistic locking, transactions/savepoints, isolation levels,
compression, encryption, TTL, full-text, spatial, partitioning, object-store offload
and crash/durability. The vector test auto-skips where the VECTOR type is
unavailable (before 11.7).

Builds and full mysql-test suite shows green on MariaDB 11.4 (LTS) through to
13.0.2
@CLAassistant

CLAassistant commented Jun 2, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request integrates the TidesDB storage engine into MariaDB, adding the core handler implementation in ha_tidesdb.h, build configuration in CMakeLists.txt, vendored libtidesdb source files, and an extensive test suite. The reviewer provided several constructive suggestions, including moving the public header copy operation in CMakeLists.txt from configure time to build time to prevent stale headers during incremental builds. Additionally, the reviewer recommended using C++11 in-class member initializers for various member variables in ha_tidesdb.h to avoid uninitialized memory issues, and explicitly marking the ha_tidesdb destructor with override.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread storage/tidesdb/CMakeLists.txt
Comment thread storage/tidesdb/ha_tidesdb.h
Comment thread storage/tidesdb/ha_tidesdb.h
Comment thread storage/tidesdb/ha_tidesdb.h
Comment thread storage/tidesdb/ha_tidesdb.h
Comment thread storage/tidesdb/ha_tidesdb.h Outdated
@guycipher

Copy link
Copy Markdown
Author

Base (11.4) >> 11.5 >> 12.0 >> … >> 12.x >> 13.0 >> main

Can propagate forward to every newer branch automatically.

@guycipher

Copy link
Copy Markdown
Author

Full TideSQL reference: https://tidesdb.com/reference/tidesql/

@guycipher

Copy link
Copy Markdown
Author

I see

/home/buildbot/storage/tidesdb/ha_tidesdb.cc: In member function 'virtual int ha_tidesdb::write_row(const uchar*)':
/home/buildbot/storage/tidesdb/ha_tidesdb.cc:6694:28: error: structured bindings only available with '-std=c++17' or '-std=gnu++17' [-Werror=c++17-extensions]
 6694 |                 for (auto &[term, tf] : tf_map)
      |                            ^
/home/buildbot/storage/tidesdb/ha_tidesdb.cc: In member function 'virtual int ha_tidesdb::update_row(const uchar*, const uchar*)':
/home/buildbot/storage/tidesdb/ha_tidesdb.cc:7898:32: error: structured bindings only available with '-std=c++17' or '-std=gnu++17' [-Werror=c++17-extensions]
 7898 |                     for (auto &[term, tf] : old_tf)
      |                                ^
/home/buildbot/storage/tidesdb/ha_tidesdb.cc:7906:32: error: structured bindings only available with '-std=c++17' or '-std=gnu++17' [-Werror=c++17-extensions]
 7906 |                     for (auto &[term, tf] : new_tf)
      |                                ^
/home/buildbot/storage/tidesdb/ha_tidesdb.cc:7926:32: error: structured bindings only available with '-std=c++17' or '-std=gnu++17' [-Werror=c++17-extensions]
 7926 |                     for (auto &[term, old_cnt] : old_tf)
      |                                ^
/home/buildbot/storage/tidesdb/ha_tidesdb.cc:7936:32: error: structured bindings only available with '-std=c++17' or '-std=gnu++17' [-Werror=c++17-extensions]
 7936 |                     for (auto &[term, new_cnt] : new_tf)
      |                                ^
/home/buildbot/storage/tidesdb/ha_tidesdb.cc: In member function 'virtual int ha_tidesdb::delete_row(const uchar*)':
/home/buildbot/storage/tidesdb/ha_tidesdb.cc:8206:28: error: structured bindings only available with '-std=c++17' or '-std=gnu++17' [-Werror=c++17-extensions]
 8206 |                 for (auto &[term, tf] : tf_map)
      |                            ^
/home/buildbot/storage/tidesdb/ha_tidesdb.cc: In member function 'virtual ha_rows ha_tidesdb::multi_range_read_info_const(uint, RANGE_SEQ_IF*, void*, uint, uint*, uint*, ha_rows, Cost_estimate*)':
/home/buildbot/storage/tidesdb/ha_tidesdb.cc:8609:25: error: 'struct TABLE' has no member named 'part_info'
 8609 |     if (table && table->part_info) return rows;
      |                         ^~~~~~~~~
/home/buildbot/storage/tidesdb/ha_tidesdb.cc: In member function 'virtual FT_INFO* ha_tidesdb::ft_init_ext(uint, uint, String*)':
/home/buildbot/storage/tidesdb/ha_tidesdb.cc:9850:16: error: structured bindings only available with '-std=c++17' or '-std=gnu++17' [-Werror=c++17-extensions]
 9850 |     for (auto &[pk_str, score] : doc_scores)
      |                ^
cc1plus: all warnings being treated as errors
make[2]: *** [storage/tidesdb/CMakeFiles/tidesdb.dir/build.make:79: storage/tidesdb/CMakeFiles/tidesdb.dir/ha_tidesdb.cc.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:10332: storage/tidesdb/CMakeFiles/tidesdb.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....

Having a look as I'm gonna guess we need to pass that wf.

@guycipher

Copy link
Copy Markdown
Author

C++11 is base I am going to assume, 13 seems to be C++17. I'll keep the engine at bay with C++11 as the library aligns with C11.

Build fixes for MariaDB 11.4-11.7 (C++11; buildbot builds with -Werror):
- Replace C++17 structured bindings with C++11 iterator access in the
  FTS write_row/update_row/delete_row and ft_init_ext paths.
- Guard TABLE::part_info with WITH_PARTITION_STORAGE_ENGINE, which only
  defines that member when partitioning is compiled in.

Initialization hardening (PR review feedback):
- Value-initialize TidesDB_share encryption members (encrypted,
  encryption_key_id, encryption_key_version) in the constructor.
- Mark ~ha_tidesdb() override.
@guycipher

guycipher commented Jun 2, 2026

Copy link
Copy Markdown
Author

Something to have a look at: https://buildbot.mariadb.org/#/builders/554/builds/22266 and https://buildbot.mariadb.org/#/builders/554/builds/22266/steps/3/logs/stdio not sure if CI or something I need to touch on at plugin level.

@guycipher

Copy link
Copy Markdown
Author

Caught it, had to create mariadb-plugin-tidesdb.install

@guycipher

Copy link
Copy Markdown
Author

https://buildbot.mariadb.org/#/builders/534/builds/39281/steps/6/logs/stdio buildbot/amd64-ubuntu-2204-debug-ps does not seem to be due to TidesDB implementation. v9.3.3 of TidesDB and v4.5.4 of TideSQL plugin implemented. Ready for review.

@dr-m

dr-m commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

https://buildbot.mariadb.org/#/builders/534/builds/39281/steps/6/logs/stdio buildbot/amd64-ubuntu-2204-debug-ps does not seem to be due to TidesDB implementation.

Right, there is an open ticket MDEV-38195 about failures of the test events.events_restart.

@gkodinov gkodinov added the External Contribution All PRs from entities outside of MariaDB Foundation, Corporation, Codership agreements. label Jun 3, 2026
@gkodinov gkodinov self-assigned this Jun 3, 2026

@gkodinov gkodinov left a comment

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.

Thank you for your contribution! This is a preliminary review.

I'm approving it as it is, as there're no major violations. Or, if there are any, they're in the competency of the final reviewer. Nevertheless, I'll mention what I see that can be improved.

First of all: please consider merging some of the commits. Ideally there should be one commit per distinct "feature". I'd guess that makes 1 in your case.

Next: this technically is a new feature. As such, I'd suggest considering rebasing to the main branch. Unless of course, there is some special consideration why the targed should be as is.

Finally, there should be a Jira for house-keeping. I'll start one for you, using the PR explanation. But this needs to be improved significantly I'd guess, until it evolves into a proper design specification that would help with the final review.

There's also one small thing I've noticed below.

Please stand by for the final review.

Comment thread storage/tidesdb/plug.in Outdated

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.

I do not think you need this file.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thank you @gkodinov understood for 1. For 2, to be able to propagate forward to newer branches selectively or not and main with a floor of support for 11.4. For 3 understood, I appreciate the help with that and I can work off it from there.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I do not think you need this file.

You're right it's a fossil.

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.

Thank you @gkodinov understood for 1. For 2, to be able to propagate forward to newer branches selectively or not and main with a floor of support for 11.4. For 3 understood, I appreciate the help with that and I can work off it from there.

Have you tried just plaining atop of the main branch and re-compiling. You're not changing anything in the server itself. So it might work just as well. You could maybe need to alter some of the calls back to the server, but I do not think it has changed that much. Then it's a matter of running the regression tests successfully (and debugging any failures).
I (and the final reviewer) can guide you through that.

@guycipher guycipher Jun 4, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

All conditionals are handled from 11.4 to 13.02, though verified sparingly there is a full list. Main sounds ok, if condenses is main, we can do that.

@gkodinov gkodinov changed the title Adds TidesDB 9(v9.3.3) storage engine MDEV-39834: Add TidesDB 9(v9.3.3) storage engine Jun 3, 2026
@gkodinov gkodinov requested a review from sanja-byelkin June 3, 2026 09:08
@gkodinov gkodinov assigned sanja-byelkin and unassigned gkodinov Jun 3, 2026
@sanja-byelkin sanja-byelkin requested a review from Copilot June 5, 2026 14:45

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

@sanja-byelkin

sanja-byelkin commented Jun 5, 2026

Copy link
Copy Markdown
Member

AFAIK 11.4 closed for the new features, why 11.4 not main?

Especially taking into account required dependencies zstd, lz4, and snappy

@sanja-byelkin

Copy link
Copy Markdown
Member

target_compile_options(tidesdb_embedded PRIVATE -w)

Why all warning supressed in so big code (we have enough problems with warnings with existing things why add more)

@guycipher

Copy link
Copy Markdown
Author

AFAIK 11.4 closed for the new features, why 11.4 not main?

Especially taking into account required dependencies zstd, lz4, and snappy

Well, I originally thought per getting it into a lower branch and merging upwards for visibility was a goal per discussion with foundation, I've brought up a few times. If the goal is newer versions only you guys can tell me and I can correct accordingly. TideSQL was written for 11.4 onwards to modern 13.02 in testing. Hitting many granular versions. We have a list if you require. These versions I've supported have conditionals a lot because things do move around quite a bit as you probably know. Thus we want I'm certain the same thing where a user and everyone is happy.

Cheers

@guycipher

guycipher commented Jun 5, 2026

Copy link
Copy Markdown
Author

target_compile_options(tidesdb_embedded PRIVATE -w)

Can you further explain? We build and develop with all sanitizers on and debug flags and running on 16 different platforms and x86 and x64 in continuous integration.

Please if you have a moment look at the TidesDB repository and the TideSQL main repositories.

If you have a concern specifically with this PRs build let me know how you'd prefer it because I am not following currently properly. The plugin itself I'm highly doubtful would have any warnings as we would catch them in engine testing and continuous integration and plugin testing and integration, but i cant remember right now why it's set the way it is, we can modify a compile option for inclusion? Is this what you're pointing out?

Thank you kindly

@guycipher

guycipher commented Jun 5, 2026

Copy link
Copy Markdown
Author

Hm so @sanja-byelkin do you prefer vendored thirdparty code to use not ignore compiler warnings? I can do

TARGET_COMPILE_OPTIONS(tidesdb_embedded PRIVATE -Wno-error)

Which is review friendly I believe. Do let me know, I shall make the change ASAP. Thank you for your review.

Cheers.

@guycipher

Copy link
Copy Markdown
Author

Upstream on the TidesDB library I am doing a scrub with what you've asked for to assure all is well. The flag you brought up is known to have false positives so I will take time with diligence there.

libtidesdb uses C11 stdatomic.h, which MSVC only enables under
/experimental:c11atomics; without it the Windows build fails with C1189
"C atomic support is not enabled". Add an MSVC branch to the tidesdb_embedded
target setting /std:c17 /experimental:c11atomics plus the same targeted /wd
warning disables the library uses upstream (the Windows build compiles with
/WX). The GCC and Clang warning handling is unchanged.
@guycipher

guycipher commented Jun 6, 2026

Copy link
Copy Markdown
Author

MSVC pthreads issue reviewing builtbot, we handle differently at library level. Investigating to see if another patch is required at library level to fit MariaDB.

edit: yeah I'm gonna have to adjust compat layer a bit to comply. Working on that now.

…ds backend

Re-vendor the libtidesdb 9.3.6 sources. 9.3.6 adds a native Win32 threading
backend in compat.h (SRWLOCK mutexes and rwlocks, CONDITION_VARIABLE condition
variables, _beginthreadex threads, and fiber-local storage so thread-local
destructors still run), so on MSVC it no longer includes pthread.h and needs
no pthreads-win32 library.

This fixes the MariaDB MSVC build, which has no pthreads-win32 and was failing
with C1083 "Cannot open include file pthread.h". POSIX, macOS and MinGW keep
using pthreads as before. Only compat.h, tidesdb.c and tidesdb.h change from
9.3.5; the C11 atomics flag added earlier (/experimental:c11atomics) is still
required on MSVC.
balagrivine pushed a commit to balagrivine/tidesdb that referenced this pull request Jun 7, 2026
decode_varint returns negative without writing its output when max_bytes is zero, which
happens on a truncated or corrupt block, and several indexed read and iterator decode sites
used the result without checking the return, so a handful of locals (ks vs vo seq_val
vlog_off) could be read uninitialized. zero initialize those locals so the failure path
yields a defined zero rather than garbage. also add a TIDESDB_WARN_MAYBE_UNINIT option, gcc
only and off by default, that turns the warning on for an optimized dev build where the
analysis actually runs.

analyzed for MariaDB engine addition MariaDB/server#5166 review

-

correct an iterator scan miss under reaper eviction and stop the cross cf atomicity test flaking on commit backpressure

iter_new pinned the level array once then skipped any sstable it could not
immediately ref treating it as dead when in fact the reaper had it in a
transient evicting window with the descriptor still live in the level. a
reader iterator snapshots only once so that skip dropped a live sstable for
the whole life of the scan and a key in it read back as not found. now we
spin on try_ref while the level array is unchanged and only bail to retry
when the array actually changed under us same shape as the point get reaper
evict skip we already correctd.

the cross cf atomicity test counted a transient busy commit as a hard error
which tripped the errors assert on slow loaded ci boxes. commit through
tdb_test_commit_with_retry like the sibling writers so a backpressure stall
retries instead of failing the run.
@guycipher guycipher changed the title MDEV-39834: Add TidesDB 9(v9.3.3) storage engine MDEV-39834: Add TidesDB 9 storage engine Jun 7, 2026
guycipher added 3 commits June 7, 2026 18:58
Re-vendor the current libtidesdb sources, picking up the latest fixes
made upstream to pass the Windows build. Changes are confined to btree.c,
compat.h and tidesdb.c; the plugin and the test suite are unchanged.
Mirror libtidesdb's own MSVC flags by adding /wd4267 next to the existing
/wd4244 narrowing-warning disable on the tidesdb_embedded target. Under the
MariaDB Windows build's /WX, the library's size_t to int narrowings (e.g.
"const int total = queue_size(...)") were promoted to C2220 errors. The
library accepts this warning class (it already disables the sibling C4244),
so disable C4267 as well and handles explicit checks where applicable. GCC,
Clang and the Linux build are unaffected.
…fset

Field::val_int_offset() takes a uint row offset, so cast the record-buffer
offset to uint instead of my_ptrdiff_t. Under the MariaDB Windows build's /WX
the my_ptrdiff_t to uint conversion was promoted to a C2220 error. The offset
is record[1] - record[0] (rec_buff_length), which always fits in uint, so the
cast is value-preserving. GCC and the Linux build are unaffected.
@sanja-byelkin

Copy link
Copy Markdown
Member

I just tried to build it on my system (Fedora 44).

  1. It is default plugin - in 11.4? people who have stable version got new pluging out of the blue IMHO it is not correct, but OK all question about version is discutable
  2. I got this
FAILED: [code=1] storage/tidesdb/CMakeFiles/tidesdb_embedded.dir/libtidesdb/src/objstore_s3.c.o 
/usr/bin/cc -DHAVE_CONFIG_H -DTIDESDB_HAVE_LZ4 -DTIDESDB_HAVE_SNAPPY -DTIDESDB_HAVE_ZSTD -DTIDESDB_WITH_S3 -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -I/home/sanja/maria/git/11.4/wsrep-lib/include -I/home/sanja/maria/git/11.4/wsrep-lib/wsrep-API/v26 -I/home/sanja/maria/git/11.4/include -I/home/sanja/maria/git/11.4/sql -I/home/sanja/maria/git/11.4/extra/wolfssl -I/home/sanja/maria/git/11.4/extra/wolfssl/wolfssl -I/home/sanja/maria/git/11.4/extra/wolfssl/wolfssl/wolfssl -I/home/sanja/maria/git/11.4/zlib -I/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src -I/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/external -pie -fPIC -fstack-protector --param=ssp-buffer-size=4 -fPIC -Werror -g -DPROTECT_STATEMENT_MEMROOT -DDBUG_TRACE -DENABLED_DEBUG_SYNC -ggdb3 -DSAFE_MUTEX -DSAFEMALLOC -DTRASH_FREED_MEMORY -Wall -Wdeclaration-after-statement -Wenum-compare -Wenum-conversion -Wextra -Wmissing-braces -Wno-format-truncation -Wno-init-self -Wno-nonnull-compare -Wno-unused-parameter -Wvla -Wwrite-strings -Wframe-larger-than=16384 -std=gnu11 -fPIC -Wno-declaration-after-statement -Wno-frame-larger-than -Wno-discarded-qualifiers -DWITH_GZFILEOP -MD -MT storage/tidesdb/CMakeFiles/tidesdb_embedded.dir/libtidesdb/src/objstore_s3.c.o -MF storage/tidesdb/CMakeFiles/tidesdb_embedded.dir/libtidesdb/src/objstore_s3.c.o.d -o storage/tidesdb/CMakeFiles/tidesdb_embedded.dir/libtidesdb/src/objstore_s3.c.o -c /home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c
In file included from /home/sanja/maria/git/11.4/extra/wolfssl/wolfssl/wolfssl/wolfcrypt/types.h:34,
                 from /home/sanja/maria/git/11.4/extra/wolfssl/wolfssl/wolfssl/openssl/evp.h:33,
                 from /home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c:26:
/home/sanja/maria/git/11.4/extra/wolfssl/wolfssl/wolfssl/wolfcrypt/settings.h:372:6: error: #warning "No configuration for wolfSSL detected, check header order" [-Werror=cpp]
  372 |     #warning "No configuration for wolfSSL detected, check header order"
      |      ^~~~~~~
/home/sanja/maria/git/11.4/extra/wolfssl/wolfssl/wolfssl/wolfcrypt/settings.h:4164:14: error: #warning "For timing resistance / side-channel attack prevention consider using harden options" [-Werror=cpp]
 4164 |             #warning "For timing resistance / side-channel attack prevention consider using harden options"
      |              ^~~~~~~
/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c: In Funktion »sha256_hex«:
/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c:228:5: error: Unbekannter Typname »EVP_MD_CTX«; meinten Sie »RIPEMD_CTX«?
  228 |     EVP_MD_CTX *ctx = EVP_MD_CTX_new();
      |     ^~~~~~~~~~
      |     RIPEMD_CTX
/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c:228:23: error: Implizite Deklaration der Funktion »EVP_MD_CTX_new« [-Wimplicit-function-declaration]
  228 |     EVP_MD_CTX *ctx = EVP_MD_CTX_new();
      |                       ^~~~~~~~~~~~~~
/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c:228:23: error: Initialisierung von »int *« von »int« wandelt eine Zahl in einen Zeiger um, ohne explizite Typkonvertierung [-Wint-conversion]
/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c:229:5: error: Implizite Deklaration der Funktion »EVP_DigestInit_ex« [-Wimplicit-function-declaration]
  229 |     EVP_DigestInit_ex(ctx, EVP_sha256(), NULL);
      |     ^~~~~~~~~~~~~~~~~
/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c:229:28: error: Implizite Deklaration der Funktion »EVP_sha256«; meinten Sie »SN_sha256«? [-Wimplicit-function-declaration]
  229 |     EVP_DigestInit_ex(ctx, EVP_sha256(), NULL);
      |                            ^~~~~~~~~~
      |                            SN_sha256
/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c:230:5: error: Implizite Deklaration der Funktion »EVP_DigestUpdate«; meinten Sie »wolfSSL_EVP_DigestUpdate«? [-Wimplicit-function-declaration]
  230 |     EVP_DigestUpdate(ctx, data, len);
      |     ^~~~~~~~~~~~~~~~
      |     wolfSSL_EVP_DigestUpdate
/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c:231:5: error: Implizite Deklaration der Funktion »EVP_DigestFinal_ex«; meinten Sie »wolfSSL_EVP_DigestFinal_ex«? [-Wimplicit-function-declaration]
  231 |     EVP_DigestFinal_ex(ctx, hash, NULL);
      |     ^~~~~~~~~~~~~~~~~~
      |     wolfSSL_EVP_DigestFinal_ex
/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c:232:5: error: Implizite Deklaration der Funktion »EVP_MD_CTX_free« [-Wimplicit-function-declaration]
  232 |     EVP_MD_CTX_free(ctx);
      |     ^~~~~~~~~~~~~~~
/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c: In Funktion »hmac_sha256«:
/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c:250:10: error: Übergabe des Arguments 1 von »wolfSSL_HMAC« wandelt eine Zahl in einen Zeiger um, ohne explizite Typkonvertierung [-Wint-conversion]
  250 |     HMAC(EVP_sha256(), key, (int)key_len, (const unsigned char *)data, data_len, out, out_len);
      |          ^~~~~~~~~~~~
      |          |
      |          int
In file included from /home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c:27:
/home/sanja/maria/git/11.4/extra/wolfssl/wolfssl/wolfssl/openssl/hmac.h:47:63: note: »const WOLFSSL_EVP_MD *« {alias »const char *«} erwartet, aber Argument hat Typ »int«
   47 | WOLFSSL_API unsigned char* wolfSSL_HMAC(const WOLFSSL_EVP_MD* evp_md,
      |                                         ~~~~~~~~~~~~~~~~~~~~~~^~~~~~
cc1: all warnings being treated as errors
[929/1833] Linking CXX static library storage/innobase/libinnobase.a
ninja: build stopped: subcommand failed.

Compilation options was

cmake ./ -GNinja -DCMAKE_BUILD_TYPE=Debug -DMYSQL_MAINTAINER_MODE=ON -DMAX_INDEXES=64 -DWITH_ASAN=NO -DWITH_EMBEDDED_SERVER=NO -DWITH_MSAN=NO -DWITH_PCRE=bundled -DWITH_SSL=bundled -DWITH_UBSAN=NO -DWITH_VALGRIND=NO -DWITH_ZLIB=bundled -DPLUGIN_S4=NO -DPLUGIN_COLUMNSTORE=NO -DPLUGIN_MROONGA=NO -DPLUGIN_CONNECT=NO -DPLUGIN_ROCKSDB=NO -DPLUGIN_SPIDER=NO -DCMAKE_EXPORT_COMPILE_COMMANDS=ON

@guycipher

Copy link
Copy Markdown
Author

I just tried to build it on my system (Fedora 44).

  1. It is default plugin - in 11.4? people who have stable version got new pluging out of the blue IMHO it is not correct, but OK all question about version is discutable
  2. I got this
FAILED: [code=1] storage/tidesdb/CMakeFiles/tidesdb_embedded.dir/libtidesdb/src/objstore_s3.c.o 
/usr/bin/cc -DHAVE_CONFIG_H -DTIDESDB_HAVE_LZ4 -DTIDESDB_HAVE_SNAPPY -DTIDESDB_HAVE_ZSTD -DTIDESDB_WITH_S3 -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -I/home/sanja/maria/git/11.4/wsrep-lib/include -I/home/sanja/maria/git/11.4/wsrep-lib/wsrep-API/v26 -I/home/sanja/maria/git/11.4/include -I/home/sanja/maria/git/11.4/sql -I/home/sanja/maria/git/11.4/extra/wolfssl -I/home/sanja/maria/git/11.4/extra/wolfssl/wolfssl -I/home/sanja/maria/git/11.4/extra/wolfssl/wolfssl/wolfssl -I/home/sanja/maria/git/11.4/zlib -I/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src -I/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/external -pie -fPIC -fstack-protector --param=ssp-buffer-size=4 -fPIC -Werror -g -DPROTECT_STATEMENT_MEMROOT -DDBUG_TRACE -DENABLED_DEBUG_SYNC -ggdb3 -DSAFE_MUTEX -DSAFEMALLOC -DTRASH_FREED_MEMORY -Wall -Wdeclaration-after-statement -Wenum-compare -Wenum-conversion -Wextra -Wmissing-braces -Wno-format-truncation -Wno-init-self -Wno-nonnull-compare -Wno-unused-parameter -Wvla -Wwrite-strings -Wframe-larger-than=16384 -std=gnu11 -fPIC -Wno-declaration-after-statement -Wno-frame-larger-than -Wno-discarded-qualifiers -DWITH_GZFILEOP -MD -MT storage/tidesdb/CMakeFiles/tidesdb_embedded.dir/libtidesdb/src/objstore_s3.c.o -MF storage/tidesdb/CMakeFiles/tidesdb_embedded.dir/libtidesdb/src/objstore_s3.c.o.d -o storage/tidesdb/CMakeFiles/tidesdb_embedded.dir/libtidesdb/src/objstore_s3.c.o -c /home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c
In file included from /home/sanja/maria/git/11.4/extra/wolfssl/wolfssl/wolfssl/wolfcrypt/types.h:34,
                 from /home/sanja/maria/git/11.4/extra/wolfssl/wolfssl/wolfssl/openssl/evp.h:33,
                 from /home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c:26:
/home/sanja/maria/git/11.4/extra/wolfssl/wolfssl/wolfssl/wolfcrypt/settings.h:372:6: error: #warning "No configuration for wolfSSL detected, check header order" [-Werror=cpp]
  372 |     #warning "No configuration for wolfSSL detected, check header order"
      |      ^~~~~~~
/home/sanja/maria/git/11.4/extra/wolfssl/wolfssl/wolfssl/wolfcrypt/settings.h:4164:14: error: #warning "For timing resistance / side-channel attack prevention consider using harden options" [-Werror=cpp]
 4164 |             #warning "For timing resistance / side-channel attack prevention consider using harden options"
      |              ^~~~~~~
/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c: In Funktion »sha256_hex«:
/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c:228:5: error: Unbekannter Typname »EVP_MD_CTX«; meinten Sie »RIPEMD_CTX«?
  228 |     EVP_MD_CTX *ctx = EVP_MD_CTX_new();
      |     ^~~~~~~~~~
      |     RIPEMD_CTX
/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c:228:23: error: Implizite Deklaration der Funktion »EVP_MD_CTX_new« [-Wimplicit-function-declaration]
  228 |     EVP_MD_CTX *ctx = EVP_MD_CTX_new();
      |                       ^~~~~~~~~~~~~~
/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c:228:23: error: Initialisierung von »int *« von »int« wandelt eine Zahl in einen Zeiger um, ohne explizite Typkonvertierung [-Wint-conversion]
/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c:229:5: error: Implizite Deklaration der Funktion »EVP_DigestInit_ex« [-Wimplicit-function-declaration]
  229 |     EVP_DigestInit_ex(ctx, EVP_sha256(), NULL);
      |     ^~~~~~~~~~~~~~~~~
/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c:229:28: error: Implizite Deklaration der Funktion »EVP_sha256«; meinten Sie »SN_sha256«? [-Wimplicit-function-declaration]
  229 |     EVP_DigestInit_ex(ctx, EVP_sha256(), NULL);
      |                            ^~~~~~~~~~
      |                            SN_sha256
/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c:230:5: error: Implizite Deklaration der Funktion »EVP_DigestUpdate«; meinten Sie »wolfSSL_EVP_DigestUpdate«? [-Wimplicit-function-declaration]
  230 |     EVP_DigestUpdate(ctx, data, len);
      |     ^~~~~~~~~~~~~~~~
      |     wolfSSL_EVP_DigestUpdate
/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c:231:5: error: Implizite Deklaration der Funktion »EVP_DigestFinal_ex«; meinten Sie »wolfSSL_EVP_DigestFinal_ex«? [-Wimplicit-function-declaration]
  231 |     EVP_DigestFinal_ex(ctx, hash, NULL);
      |     ^~~~~~~~~~~~~~~~~~
      |     wolfSSL_EVP_DigestFinal_ex
/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c:232:5: error: Implizite Deklaration der Funktion »EVP_MD_CTX_free« [-Wimplicit-function-declaration]
  232 |     EVP_MD_CTX_free(ctx);
      |     ^~~~~~~~~~~~~~~
/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c: In Funktion »hmac_sha256«:
/home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c:250:10: error: Übergabe des Arguments 1 von »wolfSSL_HMAC« wandelt eine Zahl in einen Zeiger um, ohne explizite Typkonvertierung [-Wint-conversion]
  250 |     HMAC(EVP_sha256(), key, (int)key_len, (const unsigned char *)data, data_len, out, out_len);
      |          ^~~~~~~~~~~~
      |          |
      |          int
In file included from /home/sanja/maria/git/11.4/storage/tidesdb/libtidesdb/src/objstore_s3.c:27:
/home/sanja/maria/git/11.4/extra/wolfssl/wolfssl/wolfssl/openssl/hmac.h:47:63: note: »const WOLFSSL_EVP_MD *« {alias »const char *«} erwartet, aber Argument hat Typ »int«
   47 | WOLFSSL_API unsigned char* wolfSSL_HMAC(const WOLFSSL_EVP_MD* evp_md,
      |                                         ~~~~~~~~~~~~~~~~~~~~~~^~~~~~
cc1: all warnings being treated as errors
[929/1833] Linking CXX static library storage/innobase/libinnobase.a
ninja: build stopped: subcommand failed.

Compilation options was

cmake ./ -GNinja -DCMAKE_BUILD_TYPE=Debug -DMYSQL_MAINTAINER_MODE=ON -DMAX_INDEXES=64 -DWITH_ASAN=NO -DWITH_EMBEDDED_SERVER=NO -DWITH_MSAN=NO -DWITH_PCRE=bundled -DWITH_SSL=bundled -DWITH_UBSAN=NO -DWITH_VALGRIND=NO -DWITH_ZLIB=bundled -DPLUGIN_S4=NO -DPLUGIN_COLUMNSTORE=NO -DPLUGIN_MROONGA=NO -DPLUGIN_CONNECT=NO -DPLUGIN_ROCKSDB=NO -DPLUGIN_SPIDER=NO -DCMAKE_EXPORT_COMPILE_COMMANDS=ON

Working on that, OpenSSL dep was removed from library to play nicely, we were only using it on 2 methods for object store mode; we ended up writing the sha256, hmac algorithms as they were small enough, the next commit will pass.

It is default plugin - in 11.4? people who have stable version got new pluging out of the blue IMHO it is not correct, but OK all question about version is discutable

Understood and no it's not default, its just available, similar to RocksDB.

@sanja-byelkin

sanja-byelkin commented Jun 8, 2026

Copy link
Copy Markdown
Member

We discussed version issue. Final decision is not made yet.

My opinion is that it is OK to make it in 11.4 but not OK to make it by default. becouase it will disturb distributives and user who build it from sources. Stable version should be stable.

@sanja-byelkin

Copy link
Copy Markdown
Member

For clarity, "default" I mean build by default without enabling it through cmake options.

@guycipher

Copy link
Copy Markdown
Author

No problem, thank you @sanja-byelkin

@guycipher

guycipher commented Jun 8, 2026

Copy link
Copy Markdown
Author

@sanja-byelkin currently the plugin is built but not loaded by default. Reading the code i'll add DISABLED to the MYSQL_ADD_PLUGIN call then to actually build the plugin -DPLUGIN_TIDESDB=YES/DYNAMIC would have to be utilized which is fine I do believe for now as well. It allows to as you stated not perturb preexisting builds.

@guycipher

Copy link
Copy Markdown
Author

Before I do this though, will this affect testing TidesDB builds and MTR? Do let me know how you'd like to approach if possible so I can line next commit up properly.

@sanja-byelkin

sanja-byelkin commented Jun 8, 2026

Copy link
Copy Markdown
Member

About tests, it would be way better if tests will be placed under storage/tidedb (see rocksdb, columnstore or connect for example). Regression test suite looks in mysql-test directories of the storage engines. Old tests placed in main mysql-test mostly historically.

Also the other general observation (i have not looked deep yet), I see stress tests (at least by name) mixed with regression tests, it is better divide them in different suites, because one should be run always the other (again at least by name) something time consuming.

Also just to remember that for really heavy long running tests (not stress tests just something huge) we have --big option and i can be checked inside such tests to avoid running them each time. It is not for stress testing just for really big tests, I mentioned it here to give full impression about our test suite abilities.

@guycipher

Copy link
Copy Markdown
Author

About tests, it would be way better if tests will be placed under storage/tidedb (see rocksdb, columnstore or connect for example). Regression test suite looks in mysql-test directories of the storage engines. Old tests placed in main mysql-test mostly historically.

No problem at all, will move into storage directory out of historical.

Also the other general observation (i have not looked deep yet), I see stress tests (at least by name) mixed with regression tests, it is better divide them in different suites, because one should be run always the other (again at least by name) something time consuming.

Also just to remember that for really heavy long running tests (not stress tests just something huge) we have --big option and i can be checked inside such tests to avoid running them each time. It is not for stress testing just for really big tests, I mentioned it here to give full impression about our test suite abilities.

The 300+ tests are all short, their all primarily integration tests, I wouldn't consider real "stress" per se, we test isolation on concurrent load, autocommit stress, but stress mostly on concurrency. Naming can be refactored, I'll go through and assure naming describes the running tests a bit better. No problem for me.

@sanja-byelkin

Copy link
Copy Markdown
Member

tidesdb_object_store.test - should check somehow that the host setup S3 (I do not have S3 setup on my computer but still want to run the test suite without S3, the same for buildbot builders (at least some).

It would be nice to detect absence of S3 by asking server/plugin, in worst case by environment variable. For inspiration you can check mysq-test/include/have_*

@guycipher

Copy link
Copy Markdown
Author

tidesdb_object_store.test - should check somehow that the host setup S3 (I do not have S3 setup on my computer but still want to run the test suite without S3, the same for buildbot builders (at least some).

It would be nice to detect absence of S3 by asking server/plugin, in worst case by environment variable. For inspiration you can check mysq-test/include/have_*

In TidesDB object store mode can be used with FS by default, so it's testing that path but yes variables for say minio, rust-fs, s3 could be valuable to configure for that specifically.

@sanja-byelkin

Copy link
Copy Markdown
Member

An update about versions. We just now are accepting DuckDB, it will make a precedent and we will just follow with TideDB. It should not take more than several days and we have what to fix during this time :)

@guycipher

guycipher commented Jun 8, 2026

Copy link
Copy Markdown
Author

Tide**s**DB, also understood. I saw the engine from the PLC, I understand. One thing, I do wanna state is on the repository side we are sticking to gamma as we have progressed through that hierarchy on our own side, though it may differ internally. I've brought up the version confusion with foundation as I went by what was in code, there was no stern documentation, I went with alpha, beta, preprod. After this, I'm sure we will have documentation on it!! :D

guycipher added 2 commits June 9, 2026 08:19
This pulls in the bundled SHA256 and HMAC SHA256 implementation (src/sha256.c,
src/hmac_sha256.c) used for AWS SigV4 request signing, so the S3 object
store connector no longer links OpenSSL and depends on libcurl alone. That
removes the OpenSSL versus bundled wolfSSL conflict that broke the Windows
buildbot runner, while leaving S3 fully functional on every platform.

storage/tidesdb/CMakeLists.txt now compiles the new crypto sources into the
static archive, links the S3 connector against libcurl only, and generates
libtidesdb's public tidesdb_version.h from its template (as the upstream
build does) carrying TIDESDB_VERSION and the TIDESDB_HAS_S3 and
TIDESDB_HAVE_{ZSTD,LZ4,SNAPPY} feature defines.

Exposed the vendored library version through the engine. ha_tidesdb.cc
includes the generated header and publishes a tidesdb_library_version status
variable, so SHOW GLOBAL STATUS reports which libtidesdb release the engine
was built against, independent of the plugin version. The status variable
test is updated accordingly.

Relocated the test suite from mysql-test/suite/tidesdb to
storage/tidesdb/mysql-test/tidesdb so the engine owns its tests (the layout
storage/rocksdb uses), and renamed the misnamed tidesdb_stress test to
tidesdb_concurrency since it is a deterministic transaction and concurrency
correctness test rather than a load test.

Made the suite preserve global state for mtr check-testcase. The tests run
the test database as utf8mb4 (set in have_tidesdb.inc); cleanup_tidesdb.inc
now restores it to the server default instead of forcing utf8mb4, the two
force restart fulltext tests source cleanup, and tidesdb_vector runs its
VECTOR skip check before the charset change so a skipped run leaves the
database unchanged. Without this every test reported a check-testcase
side effect.

Tested from 11.4 through 13.0, full tidesdb suite green,
check-testcase clean across repeated parallel runs
Include winsock2.h before curl pulls it in on MSVC so struct timeval is
defined exactly once. winsock2.h sets _WINSOCK2API_, so compat.h skips its
own timeval definition and curl's later include does not collide with it.
MinGW continues to resolve timeval through its POSIX sys/time.h.
@guycipher

Copy link
Copy Markdown
Author

@sanja-byelkin ok for review on your side. I've described changes quite extensively in each commit furthermore tied the @tidesdb patch to it. The windows packages buildbot is now failing on something unrelated to TidesDB, nor TideSQL.

@guycipher

guycipher commented Jun 9, 2026

Copy link
Copy Markdown
Author

There is:

MSBuild version 17.14.14+a129329f1 for .NET Framework
  Building Custom Rule C:/buildbot/workers/prod/amd64-windows-packages/build/win/packaging/ca/CMakeLists.txt
  CustomAction.cpp
  winservice.c
     Creating library C:/buildbot/workers/prod/amd64-windows-packages/build/win/packaging/ca/RelWithDebInfo/wixca.lib and object C:/buildbot/workers/prod/amd64-windows-packages/build/win/packaging/ca/RelWithDebInfo/wixca.exp
  wixca.vcxproj -> C:\buildbot\workers\prod\amd64-windows-packages\build\win\packaging\ca\RelWithDebInfo\wixca.dll
  -- Downloading https://github.com/HeidiSQL/HeidiSQL/releases/download/12.17/HeidiSQL_12.17_64_Portable.zip to C:/Users/buildbot/AppData/Local/Temp/HeidiSQL_12.17_64_Portable/HeidiSQL_12.17_64_Portable.zip
  -- CPACK_COMPONENTS_ALL=Backup;Client;ClientPlugins;Common;Debuginfo;Development;Readme;RuntimeDeps;Server;Server_Scripts;SharedLibraries;Test;VCCRT;connect-engine;connect-engine-jdbc;hashicorp-key-management;plugin-hashicorp-key-management;rocksdb-engine;tidesdb-engine
  -- add_component : ignoring aws-key-management, not in CPACK_COMPONENTS_ALL
  CMake Error at CPackWixConfig.cmake:75 (message):
    Component tidesdb-engine is not known.  Either install it using
    add_component() macro or add to COMPONENTS_IGNORE list
  Call Stack (most recent call first):
    create_msi.cmake:49 (INCLUDE)

This looks related to install executable for windows primarily. Core code change as opposed to plugin. I can make the adjustment but before touching MariaDB code, I'd obviously like confirmation on that aspect.

In the interim at TidesDB we will be merging v9.3.6 for release it's all good on our side. For what's next it will be contained to MariaDB PR, the TideSQL repo will also be updated shortly to reflect and all documentation. Thank you!!!

guycipher added 4 commits June 9, 2026 11:59
The lz4 provider service exposed LZ4_compressBound, LZ4_compress_default and
LZ4_decompress_safe. Add LZ4_compress_fast so storage engines that use
liblz4's acceleration parameter can route their lz4 compression through the
provider instead of linking liblz4 directly.

The new function pointer is appended to provider_service_lz4_st and wired up
in the provider plugin init, with a not-loaded warning stub in
sql_plugin_services.inl. VERSION_provider_lz4 is bumped to 0x0101 for the
additive service change.
The tidesdb suite only exercised the NONE and ZSTD per-table COMPRESSION
options. Add a dedicated test that round-trips a compressible payload through
every codec (NONE, SNAPPY, LZ4, LZ4_FAST, ZSTD), verifying the option
persists in SHOW CREATE TABLE and that data survives a write and read cycle.
LZ4_FAST additionally covers UPDATE and DELETE so the LZ4_compress_fast
acceleration path is rewritten and read back.
Add provider_zstd, mirroring the existing lz4 and snappy compression
providers, so storage engines can route Zstandard compression through the
loadable provider service instead of linking libzstd directly. The provider
exposes ZSTD_compressBound, ZSTD_compress, ZSTD_decompress and ZSTD_isError,
the surface TidesDB uses.

This adds include/providers/zstd.h (the service shim), the
provider_service_zstd libservice, the provider_zstd daemon plugin and its
.cnf (plugin_load_add plus force_plus_permanent like the other providers),
the VERSION_provider_zstd service version, and the handler registration in
sql_plugin_services.inl with not-loaded warning stubs.

InnoDB is left unchanged; it has no zstd page-compression algorithm. The
provider is exercised by the TidesDB engine, whose compression test covers
the ZSTD codec and others.
Switch the engine from linking libzstd, liblz4 and libsnappy directly to
resolving them through MariaDB's compression provider services. Keep
include/providers on the engine include path so libtidesdb's compress.c
compiles against the provider shims, compile the vendored archive with
MYSQL_DYNAMIC_PLUGIN so the codec calls bind to the loaded provider, and link
mysqlservices so the provider_service_{zstd,lz4,snappy} symbols resolve. The
plugin no longer has a direct dependency on any compression library.

All three code paths are always compiled in; a codec is usable at run time
when its provider plugin is loaded and fails cleanly (engine stays up, other
codecs unaffected) when it is not. The tidesdb suite loads provider_lz4,
provider_snappy and provider_zstd in suite.opt because the default table
compression is LZ4.

Tested on the full suite with the providers loaded (all pass, check-testcase
clean) and verified graceful degradation with a provider absent.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

External Contribution All PRs from entities outside of MariaDB Foundation, Corporation, Codership agreements.

Development

Successfully merging this pull request may close these issues.

6 participants