diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000000000..5a23a1addcc55
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,629 @@
+*-t
+*.ctest
+*.reject
+*.spec
+*.bak
+*.dgcov
+*.rpm
+.*.swp
+*.ninja
+.ninja_*
+*.mri
+*.mri.tpl
+/.cproject
+/.project
+.gdb_history
+.vs/
+/.settings/
+errmsg.sys
+typescript
+_CPack_Packages
+CMakeCache.txt
+CMakeFiles/
+MakeFile
+install_manifest*.txt
+CPackConfig.cmake
+CPackSourceConfig.cmake
+CTestTestfile.cmake
+Docs/INFO_BIN
+Docs/INFO_SRC
+Makefile
+TAGS
+Testing/
+tmp/
+VERSION.dep
+configure
+client/async_example
+client/mysql
+client/mysql_plugin
+client/mysql_upgrade
+client/mysqladmin
+client/mysqlbinlog
+client/mysqlcheck
+client/mysqldump
+client/mysqlimport
+client/mysqlshow
+client/mysqlslap
+client/mysqltest
+client/mariadb-conv
+cmake_install.cmake
+dbug/*.r
+dbug/factorial
+dbug/tests
+dbug/user.ps
+dbug/user.t
+extra/comp_err
+extra/innochecksum
+extra/jemalloc/build/
+extra/jemalloc/tmp/
+extra/mariabackup/mariabackup
+extra/mariabackup/mbstream
+extra/my_print_defaults
+extra/mysql_waitpid
+extra/mysqld_safe_helper
+extra/perror
+extra/replace
+extra/resolve_stack_dump
+extra/resolveip
+extra/wolfssl/user_settings.h
+import_executables.cmake
+include/*.h.tmp
+include/config.h
+include/my_config.h
+include/mysql_version.h
+include/mysqld_ername.h
+include/mysqld_error.h
+include/sql_state.h
+include/probes_mysql.d
+include/probes_mysql_dtrace.h
+include/probes_mysql_nodtrace.h
+include/source_revision.h
+info_macros.cmake
+libmysql*/libmysql*_exports_file.cc
+libmysql*/merge_archives_mysql*.cmake
+libmysql*/mysql*_depends.c
+libmysql/libmysql_versions.ld
+libmysqld/examples/mysql_client_test_embedded
+libmysqld/examples/mysql_embedded
+libmysqld/examples/mysqltest_embedded
+make_dist.cmake
+mariadb-*.*.*.tar.gz
+mariadb-*.*.*/
+mysql-test/lib/My/SafeProcess/my_safe_process
+mysql-test/lib/My/SafeProcess/wsrep_check_version
+mysql-test/mtr
+mysql-test/mysql-test-run
+mysql-test/mariadb-test-run
+mysql-test/mysql-stress-test.pl
+mysql-test/mysql-test-run.pl
+mysql-test/var*
+mysql-test-gcov.err
+mysql-test-gcov.msg
+mysys/test_hash
+mysys/thr_lock
+mysys/thr_timer
+packaging/rpm-oel/mysql.spec
+packaging/rpm-uln/mysql.10.0.11.spec
+packaging/solaris/postinstall-solaris
+extra/pcre2
+extra/libfmt
+plugin/auth_pam/auth_pam_tool
+plugin/auth_pam/config_auth_pam.h
+plugin/aws_key_management/aws-sdk-cpp
+plugin/aws_key_management/aws_sdk_cpp
+plugin/aws_key_management/aws_sdk_cpp-prefix
+scripts/comp_sql
+scripts/make_binary_distribution
+scripts/msql2mysql
+scripts/mysql_config
+scripts/mysql_config.pl
+scripts/mysql_convert_table_format
+scripts/mysql_find_rows
+scripts/mysql_fix_extensions
+scripts/mysql_fix_privilege_tables.sql
+scripts/mysql_fix_privilege_tables_sql.c
+scripts/mysql_install_db
+scripts/mysql_secure_installation
+scripts/mysql_setpermission
+scripts/mysql_zap
+scripts/mysqlaccess
+scripts/mysqlbug
+scripts/mysqld_multi
+scripts/mysqld_safe
+scripts/mysqldumpslow
+scripts/mysqlhotcopy
+scripts/mytop
+scripts/wsrep_sst_backup
+scripts/wsrep_sst_common
+scripts/wsrep_sst_mysqldump
+scripts/wsrep_sst_rsync
+scripts/wsrep_sst_rsync_wan
+scripts/wsrep_sst_mariabackup
+scripts/wsrep_sst_xtrabackup
+scripts/wsrep_sst_xtrabackup-v2
+scripts/maria_add_gis_sp.sql
+scripts/maria_add_gis_sp_bootstrap.sql
+scripts/galera_new_cluster
+scripts/galera_recovery
+scripts/mysql_convert_table_format.pl
+scripts/mysql_sys_schema.sql
+scripts/mysqld_multi.pl
+scripts/mysqldumpslow.pl
+scripts/mysqlhotcopy.pl
+sql-bench/bench-count-distinct
+sql-bench/bench-init.pl
+sql-bench/compare-results
+sql-bench/copy-db
+sql-bench/crash-me
+sql-bench/graph-compare-results
+sql-bench/innotest1
+sql-bench/innotest1a
+sql-bench/innotest1b
+sql-bench/innotest2
+sql-bench/innotest2a
+sql-bench/innotest2b
+sql-bench/run-all-tests
+sql-bench/server-cfg
+sql-bench/test-ATIS
+sql-bench/test-alter-table
+sql-bench/test-big-tables
+sql-bench/test-connect
+sql-bench/test-create
+sql-bench/test-insert
+sql-bench/test-select
+sql-bench/test-table-elimination
+sql-bench/test-transactions
+sql-bench/test-wisconsin
+sql-bench/bench-count-distinct.pl
+sql-bench/compare-results.pl
+sql-bench/copy-db.pl
+sql-bench/crash-me.pl
+sql-bench/graph-compare-results.pl
+sql-bench/innotest1.pl
+sql-bench/innotest1a.pl
+sql-bench/innotest1b.pl
+sql-bench/innotest2.pl
+sql-bench/innotest2a.pl
+sql-bench/innotest2b.pl
+sql-bench/run-all-tests.pl
+sql-bench/server-cfg.pl
+sql-bench/test-ATIS.pl
+sql-bench/test-alter-table.pl
+sql-bench/test-big-tables.pl
+sql-bench/test-connect.pl
+sql-bench/test-create.pl
+sql-bench/test-insert.pl
+sql-bench/test-select.pl
+sql-bench/test-table-elimination.pl
+sql-bench/test-transactions.pl
+sql-bench/test-wisconsin.pl
+sql/make_mysqld_lib.cmake
+sql/lex_token.h
+sql/gen_lex_token
+sql/gen_lex_hash
+sql/lex_hash.h
+sql/myskel.m4
+sql/mysql_tzinfo_to_sql
+sql/mysqld
+sql/sql_builtin.cc
+sql/yy_mariadb.cc
+sql/yy_mariadb.hh
+sql/yy_mariadb.yy
+sql/yy_oracle.cc
+sql/yy_oracle.hh
+sql/yy_oracle.yy
+storage/heap/hp_test1
+storage/heap/hp_test2
+storage/maria/aria_chk
+storage/maria/aria_dump_log
+storage/maria/aria_ftdump
+storage/maria/aria_pack
+storage/maria/aria_read_log
+storage/maria/aria_s3_copy
+storage/maria/ma_rt_test
+storage/maria/ma_sp_test
+storage/maria/ma_test1
+storage/maria/ma_test2
+storage/maria/ma_test3
+storage/maria/test_ma_backup
+storage/myisam/mi_test1
+storage/myisam/mi_test2
+storage/myisam/mi_test3
+storage/myisam/myisam_ftdump
+storage/myisam/myisamchk
+storage/myisam/myisamlog
+storage/myisam/myisampack
+storage/myisam/rt_test
+storage/myisam/sp_test
+storage/perfschema/pfs_config.h
+storage/rocksdb/ldb
+storage/rocksdb/myrocks_hotbackup
+storage/rocksdb/mysql_ldb
+storage/rocksdb/rdb_source_revision.h
+storage/rocksdb/sst_dump
+strings/conf_to_src
+support-files/MySQL-shared-compat.spec
+support-files/binary-configure
+support-files/config.huge.ini
+support-files/config.medium.ini
+support-files/config.small.ini
+support-files/mariadb.pc
+support-files/mariadb.pp
+support-files/mariadb.service
+support-files/mariadb.socket
+support-files/mariadb-extra.socket
+support-files/mariadb@.service
+support-files/mariadb@.socket
+support-files/mariadb-extra@.socket
+support-files/mini-benchmark
+support-files/my-huge.cnf
+support-files/my-innodb-heavy-4G.cnf
+support-files/my-large.cnf
+support-files/my-medium.cnf
+support-files/my-small.cnf
+support-files/mariadb.logrotate
+support-files/mysql.10.0.11.spec
+support-files/mysql.server
+support-files/mysql.service
+support-files/mysql.spec
+support-files/mysqld.service
+support-files/mysqld_multi.server
+support-files/policy/selinux/mysqld-safe.pp
+support-files/sysusers.conf
+support-files/tmpfiles.conf
+support-files/wsrep.cnf
+support-files/wsrep_notify
+tags
+tests/async_queries
+tests/bug25714
+tests/mysql_client_test
+storage/mroonga/config.sh
+storage/mroonga/mrn_version.h
+storage/mroonga/data/install.sql
+storage/mroonga/vendor/groonga/config.h
+storage/mroonga/vendor/groonga/config.sh
+storage/mroonga/vendor/groonga/groonga.pc
+storage/mroonga/vendor/groonga/src/grnslap
+storage/mroonga/vendor/groonga/src/groonga
+storage/mroonga/vendor/groonga/src/groonga-benchmark
+storage/mroonga/vendor/groonga/src/suggest/groonga-suggest-create-dataset
+storage/mroonga/mysql-test/mroonga/storage/r/information_schema_plugins.result
+storage/mroonga/mysql-test/mroonga/storage/r/variable_version.result
+zlib/zconf.h
+xxx/*
+yyy/*
+zzz/*
+
+# C and C++
+
+# Compiled Object files
+*.slo
+*.o
+*.ko
+*.obj
+*.elf
+*.exp
+*.dep
+*.idb
+*.res
+*.tlog
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Compiled Static libraries
+*.lib
+*.a
+*.la
+*.lai
+*.lo
+
+# Compiled Dynamic libraries
+*.so
+*.so.*
+*.dylib
+*.dll
+
+# Executables
+*.exe
+*.out
+*.app
+*.i*86
+*.x86_64
+*.hex
+
+
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+*.sln
+
+*.vcproj
+*.vcproj.*
+*.vcproj.*.*
+*.vcproj.*.*.*
+*.vcxproj
+*.vcxproj.*
+*.vcxproj.*.*
+*.vcxproj.*.*.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+build/
+bld/
+[Bb]in/
+/cmake-build-debug/
+[Oo]bj/
+
+# Roslyn cache directories
+*.ide/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+#NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+*.cachefile
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding addin-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# If using the old MSBuild-Integrated Package Restore, uncomment this:
+#!**/packages/repositories.config
+
+# Windows Azure Build Output
+csx/
+*.build.csdef
+
+# Windows Store app package directory
+AppPackages/
+
+# Others
+# sql/
+*.Cache
+ClientBin/
+[Ss]tyle[Cc]op.*
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.pfx
+*.publishsettings
+node_modules/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+*.stackdump
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# macOS garbage
+.DS_Store
+
+# QtCreator && CodeBlocks
+*.cbp
+
+compile_commands.json
+.clang-format
+.kscope/
+.vimrc
+.editorconfig
+.kateconfig
+*.kdev4
+
+# Visual Studio Code workspace
+.vscode/
+
+# Clion && other JetBrains ides
+/.idea/
+
+.cache/clangd
+
+
+client/mariadb
+client/mariadb-admin
+client/mariadb-binlog
+client/mariadb-check
+client/mariadb-dump
+client/mariadb-import
+client/mariadb-plugin
+client/mariadb-show
+client/mariadb-slap
+client/mariadb-test
+client/mariadb-upgrade
+extra/mariabackup/mariadb-backup
+extra/mariadbd-safe-helper
+extra/mariadb-waitpid
+libmysqld/examples/mariadb-client-test-embedded
+libmysqld/examples/mariadb-embedded
+libmysqld/examples/mariadb-test-embedded
+man/mariadb.1
+man/mariadb-access.1
+man/mariadb-admin.1
+man/mariadb-backup.1
+man/mariadb-binlog.1
+man/mariadb-check.1
+man/mariadb-client-test.1
+man/mariadb-client-test-embedded.1
+man/mariadb_config.1
+man/mariadb-convert-table-format.1
+man/mariadbd.8
+man/mariadbd-multi.1
+man/mariadbd-safe.1
+man/mariadbd-safe-helper.1
+man/mariadb-dump.1
+man/mariadb-dumpslow.1
+man/mariadb-embedded.1
+man/mariadb-find-rows.1
+man/mariadb-fix-extensions.1
+man/mariadb-hotcopy.1
+man/mariadb-import.1
+man/mariadb-install-db.1
+man/mariadb-ldb.1
+man/mariadb-plugin.1
+man/mariadb-secure-installation.1
+man/mariadb-setpermission.1
+man/mariadb-show.1
+man/mariadb-slap.1
+man/mariadb-test.1
+man/mariadb-test-embedded.1
+man/mariadb-tzinfo-to-sql.1
+man/mariadb-upgrade.1
+man/mariadb-waitpid.1
+scripts/mariadb-access
+scripts/mariadb-convert-table-format
+scripts/mariadbd-multi
+scripts/mariadbd-safe
+scripts/mariadb-dumpslow
+scripts/mariadb-find-rows
+scripts/mariadb-fix-extensions
+scripts/mariadb-hotcopy
+scripts/mariadb-install-db
+scripts/mariadb-secure-installation
+scripts/mariadb-setpermission
+sql/mariadbd
+sql/mariadb-tzinfo-to-sql
+storage/rocksdb/mariadb-ldb
+strings/ctype-uca1400data.h
+strings/uca-dump
+tests/mariadb-client-test
+versioninfo_dll.rc
+versioninfo_exe.rc
+win/packaging/ca/symlinks.cc
+
+# rust output
+**/target/
+**/.git
+
diff --git a/.github/workflows/validation-rust.yaml b/.github/workflows/validation-rust.yaml
new file mode 100644
index 0000000000000..57f0cc7bce684
--- /dev/null
+++ b/.github/workflows/validation-rust.yaml
@@ -0,0 +1,178 @@
+---
+
+# Main "useful" actions config file
+# Cache config comes from https://github.com/actions/cache/blob/main/examples.md#rust---cargo
+# actions-rs/toolchain configures rustup
+# actions-rs/cargo actually runs cargo
+
+on:
+ push:
+ branches:
+ - rust
+ # pull_request:
+
+name: Rust Validation
+
+jobs:
+ check:
+ name: "Check (cargo check)"
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/cache@v3
+ with:
+ path: |
+ ~/.cargo/bin/
+ ~/.cargo/registry/index/
+ ~/.cargo/registry/cache/
+ ~/.cargo/git/db/
+ target/
+ rust/target/
+ CMakeFiles/
+ CMakeCache.txt
+ CPackConfig.cmake
+ CPackSourceConfig.cmake
+ CTestTestfile.cmake
+ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
+ - run: sudo apt-get update && sudo apt-get install cmake
+ - uses: dtolnay/rust-toolchain@stable
+ - run: cargo check --manifest-path rust/Cargo.toml
+
+ test:
+ strategy:
+ fail-fast: true
+ matrix:
+ os: [ubuntu-latest] #, windows-latest, macos-latest]
+ include:
+ - os: ubuntu-latest
+ name: linux
+ # - os: windows-latest
+ # name: windows
+ # - os: macos-latest
+ # name: mac
+
+ name: "Test on ${{ matrix.name }} (cargo test)"
+ runs-on: ${{ matrix.os }}
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/cache@v3
+ with:
+ path: |
+ ~/.cargo/bin/
+ ~/.cargo/registry/index/
+ ~/.cargo/registry/cache/
+ ~/.cargo/git/db/
+ target/
+ rust/target/
+ CMakeFiles/
+ CMakeCache.txt
+ CPackConfig.cmake
+ CPackSourceConfig.cmake
+ CTestTestfile.cmake
+ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
+ - run: sudo apt-get update && sudo apt-get install cmake
+ - uses: dtolnay/rust-toolchain@stable
+ - run: cargo test --manifest-path rust/Cargo.toml
+ env:
+ RUST_BACKTRACE: "1"
+
+
+ fmt:
+ name: "Format (cargo fmt)"
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/cache@v3
+ with:
+ path: |
+ ~/.cargo/bin/
+ ~/.cargo/registry/index/
+ ~/.cargo/registry/cache/
+ ~/.cargo/git/db/
+ target/
+ rust/target/
+ CMakeFiles/
+ CMakeCache.txt
+ CPackConfig.cmake
+ CPackSourceConfig.cmake
+ CTestTestfile.cmake
+ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
+ - uses: dtolnay/rust-toolchain@stable
+ with:
+ components: rustfmt
+ - run: cargo fmt --manifest-path rust/Cargo.toml --all -- --check
+
+ clippy:
+ name: "Clippy (cargo clippy)"
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/cache@v3
+ with:
+ path: |
+ ~/.cargo/bin/
+ ~/.cargo/registry/index/
+ ~/.cargo/registry/cache/
+ ~/.cargo/git/db/
+ target/
+ rust/target/
+ CMakeFiles/
+ CMakeCache.txt
+ CPackConfig.cmake
+ CPackSourceConfig.cmake
+ CTestTestfile.cmake
+ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
+ - run: sudo apt-get update && sudo apt-get install cmake
+ - uses: dtolnay/rust-toolchain@nightly
+ with:
+ components: clippy
+ - run: cargo clippy --manifest-path rust/Cargo.toml -- -D warnings
+
+ doc:
+ name: "Docs (cargo doc) & Pub"
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/cache@v3
+ with:
+ path: |
+ ~/.cargo/bin/
+ ~/.cargo/registry/index/
+ ~/.cargo/registry/cache/
+ ~/.cargo/git/db/
+ target/
+ rust/target/
+ CMakeFiles/
+ CMakeCache.txt
+ CPackConfig.cmake
+ CPackSourceConfig.cmake
+ CTestTestfile.cmake
+ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
+ - run: sudo apt-get update && sudo apt-get install cmake
+ - uses: dtolnay/rust-toolchain@stable
+ # test docs for everything
+ - name: Test build all docs
+ run: cargo doc --manifest-path rust/Cargo.toml --no-deps
+ # create docs for the crate we care about
+ - name: Build docs for publish
+ run: |
+ rm -rf target/doc/ rust/target/doc/
+ cargo doc --manifest-path rust/mariadb/Cargo.toml --no-deps
+ cargo doc --manifest-path rust/bindings/Cargo.toml --no-deps
+ - run: |
+ echo `pwd`/rust/target/doc >> $GITHUB_PATH
+ # fake index.html so github likes us
+ echo "" > rust/target/doc/index.html
+ - name: Deploy GitHub Pages
+ run: |
+ git worktree add gh-pages
+ git config user.name "Deploy from CI"
+ git config user.email ""
+ cd gh-pages
+ # Delete the ref to avoid keeping history.
+ git update-ref -d refs/heads/gh-pages
+ rm -rf *
+ mv ../rust/target/doc/* .
+ git add .
+ git commit -m "Deploy $GITHUB_SHA to gh-pages"
+ git push --force --set-upstream origin gh-pages
diff --git a/.gitignore b/.gitignore
index 2fb3857120c1f..d427014224d7c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -622,3 +622,7 @@ tests/mariadb-client-test
versioninfo_dll.rc
versioninfo_exe.rc
win/packaging/ca/symlinks.cc
+
+# rust output
+rust/target
+Cargo.lock
diff --git a/README.md b/README.md
index 58dbf105fb90a..e09f97ad69769 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,13 @@
+# MariaDB: Rust Support Fork
+
+This is a fork of [MariaDB server](https://github.com/MariaDB/server) with the
+goal of experimenting with a Rust plugin API. It is a work in progress,
+everything here should be considered unstable.
+
+View docs for the Rust API here:
+.
+
+
Code status:
------------
diff --git a/docker_build.sh b/docker_build.sh
new file mode 100644
index 0000000000000..b9d7da7362e97
--- /dev/null
+++ b/docker_build.sh
@@ -0,0 +1,11 @@
+# docker run -it -v $(pwd):/build/server ubuntu
+apt-get update
+apt-get build-dep mariadb-server
+apt-get install -y build-essential libncurses5-dev gnutls-dev bison zlib1g-dev ccache g++ cmake ninja-build vim wget
+
+cd build
+mkdir build-mariadb-server-debug
+cd build-mariadb-server-debug
+cmake ../server -DCONC_WITH_{UNITTEST,SSL}=OFF -DWITH_UNIT_TESTS=OFF -DCMAKE_BUILD_TYPE=Debug -DWITH_SAFEMALLOC=OFF -DWITH_SSL=bundled -DMYSQL_MAINTAINER_MODE=OFF -G Ninja
+
+# cmake --build . --parallel 4
diff --git a/include/mysql/plugin_auth_common.h b/include/mysql/plugin_auth_common.h
index 8edd712875461..7bbdca5aae214 100644
--- a/include/mysql/plugin_auth_common.h
+++ b/include/mysql/plugin_auth_common.h
@@ -128,4 +128,3 @@ typedef struct st_plugin_vio
} MYSQL_PLUGIN_VIO;
#endif
-
diff --git a/rust/.clippy.toml b/rust/.clippy.toml
new file mode 100644
index 0000000000000..96995253d74c2
--- /dev/null
+++ b/rust/.clippy.toml
@@ -0,0 +1 @@
+doc-valid-idents = ["MySQL", "MariaDB"]
diff --git a/rust/.rustfmt.toml b/rust/.rustfmt.toml
new file mode 100644
index 0000000000000..4dc35d3684f6d
--- /dev/null
+++ b/rust/.rustfmt.toml
@@ -0,0 +1,6 @@
+imports_granularity = "Module"
+newline_style = "Unix"
+group_imports = "StdExternalCrate"
+format_code_in_doc_comments = true
+format_macro_bodies = true
+format_macro_matchers = true
diff --git a/rust/Cargo.toml b/rust/Cargo.toml
new file mode 100644
index 0000000000000..cd5c15254140e
--- /dev/null
+++ b/rust/Cargo.toml
@@ -0,0 +1,13 @@
+# Define our crates within a workspace
+
+[workspace]
+
+members = [
+ "bindings",
+ "mariadb",
+ "macros",
+ "examples/keymgt-basic",
+ "examples/keymgt-debug",
+ "examples/encryption",
+ "plugins/keymgt-clevis",
+]
diff --git a/rust/Dockerfile b/rust/Dockerfile
new file mode 100644
index 0000000000000..206d657aa251a
--- /dev/null
+++ b/rust/Dockerfile
@@ -0,0 +1,65 @@
+# Quick test for our example plugins, build against the current repo but runs
+# with the published 10.11 image
+#
+# ```
+# # Build the image. Change the directory (../) if not building in `rust/`
+# docker build -f Dockerfile ../ --tag mdb-plugin-ex
+#
+# # Run the container, select default plugins as desired
+# docker run --rm -e MARIADB_ROOT_PASSWORD=example --name mdb-plugin-ex-c \
+# mdb-plugin-ex \
+# --plugin-maturity=experimental \
+# --plugin-load=libbasic \
+# --plugin-load=libencryption
+# --plugin-load=libkeymgt_debug
+#
+# # Enter a SQL console
+# docker exec -it mdb-plugin-ex-c mysql -pexample
+#
+# # Install desired plugins
+# INSTALL PLUGIN basic_key_management SONAME 'libbasic.so';
+# INSTALL PLUGIN encryption_example SONAME 'libencryption.so';
+# INSTALL PLUGIN debug_key_management SONAME 'libkeymgt_debug.so';
+#
+# # Stop server
+# docker stop mdb-plugin-ex-c
+# ```
+
+# use nighlty image for faster builds
+FROM rustlang/rust:nightly AS build
+
+ENV CARGO_UNSTABLE_SPARSE_REGISTRY=true
+WORKDIR /build
+
+RUN apt-get update \
+ # build requirements
+ && apt-get install -y cmake clang bison \
+ && mkdir /output
+
+COPY . .
+
+WORKDIR /build/rust
+
+RUN --mount=type=cache,target=/usr/local/cargo/registry \
+ --mount=type=cache,target=target \
+ cargo build \
+ # -p basic
+ # -p encryption
+ # --release \
+ # && cp target/release/*.so /output
+ && cp target/debug/*.so /output
+
+# RUN cp target/debug/*.so /output
+
+RUN export RUST_BACKTRACE=1
+
+FROM mariadb:10.11-rc
+
+# Deb utils
+RUN apt-get update \
+ && apt-get install -y xxd less vim-tiny binutils
+
+COPY --from=build /output/* /usr/lib/mysql/plugin/
+
+# create database db; use db; create table t1 (id int) encrypted=yes;
+# flush tables t1 for export;
diff --git a/rust/README.md b/rust/README.md
new file mode 100644
index 0000000000000..80850afbdd38c
--- /dev/null
+++ b/rust/README.md
@@ -0,0 +1,33 @@
+# Rust support for MariaDB
+
+The purpose of this module is to be able to write plugins for MariaDB in Rust.
+
+## Building
+
+The Rust portion of this repository does not yet integrate with the main MariaDB
+CMake build system to statically link plugins (adding this is a goal).
+
+To build dynamically, simply run `cargo build` within this `/rust` directory.
+
+## Testing with Docker
+
+
+```sh
+# Build the image. Change the directory (../) if not building in `rust/`
+docker build -f Dockerfile ../ --tag mdb-plugin-ex
+
+# Run the container
+docker run --rm -e MARIADB_ROOT_PASSWORD=example --name mdb-plugin-ex-c \
+ mdb-plugin-ex \
+ --plugin-maturity=experimental
+# --plugin-load=libbasic \
+# --plugin-load=libencryption
+# --plugin-load=libdebug_key_management
+
+# Enter a SQL console
+docker exec -it mdb-plugin-ex-c mysql -pexample
+
+# Install desired plugins
+INSTALL PLUGIN basic_key_management SONAME 'libbasic.so';
+INSTALL PLUGIN encryption_example SONAME 'libencryption_example.so';
+```
diff --git a/rust/bindings/Cargo.toml b/rust/bindings/Cargo.toml
new file mode 100644
index 0000000000000..4417de0938517
--- /dev/null
+++ b/rust/bindings/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "mariadb-sys"
+version = "0.1.0"
+edition = '2021'
+
+
+[build-dependencies]
+bindgen = "0.63.0"
+cmake = "0.1"
+doxygen-rs = "0.2"
diff --git a/rust/bindings/build.rs b/rust/bindings/build.rs
new file mode 100644
index 0000000000000..026486b89da48
--- /dev/null
+++ b/rust/bindings/build.rs
@@ -0,0 +1,126 @@
+//! This file runs `cmake` as needed, then `bindgen` to produce the rust bindings
+
+use std::collections::HashSet;
+use std::env;
+use std::path::PathBuf;
+use std::process::Command;
+
+use bindgen::callbacks::{DeriveInfo, MacroParsingBehavior, ParseCallbacks};
+use bindgen::EnumVariation;
+
+// `math.h` seems to double define some things, To avoid this, we ignore them.
+const IGNORE_MACROS: [&str; 20] = [
+ "FE_DIVBYZERO",
+ "FE_DOWNWARD",
+ "FE_INEXACT",
+ "FE_INVALID",
+ "FE_OVERFLOW",
+ "FE_TONEAREST",
+ "FE_TOWARDZERO",
+ "FE_UNDERFLOW",
+ "FE_UPWARD",
+ "FP_INFINITE",
+ "FP_INT_DOWNWARD",
+ "FP_INT_TONEAREST",
+ "FP_INT_TONEARESTFROMZERO",
+ "FP_INT_TOWARDZERO",
+ "FP_INT_UPWARD",
+ "FP_NAN",
+ "FP_NORMAL",
+ "FP_SUBNORMAL",
+ "FP_ZERO",
+ "IPPORT_RESERVED",
+];
+
+const DERIVE_COPY_NAMES: [&str; 1] = ["enum_field_types"];
+
+#[derive(Debug)]
+struct BuildCallbacks(HashSet);
+
+impl ParseCallbacks for BuildCallbacks {
+ /// Ignore macros that are in the ignored list
+ fn will_parse_macro(&self, name: &str) -> MacroParsingBehavior {
+ if self.0.contains(name) {
+ MacroParsingBehavior::Ignore
+ } else {
+ MacroParsingBehavior::Default
+ }
+ }
+
+ /// Use a converter to turn doxygen comments into rustdoc
+ fn process_comment(&self, comment: &str) -> Option {
+ Some(doxygen_rs::transform(comment))
+ }
+
+ fn add_derives(&self, _info: &DeriveInfo<'_>) -> Vec {
+ if DERIVE_COPY_NAMES.contains(&_info.name) {
+ vec!["Copy".to_owned()]
+ } else {
+ vec![]
+ }
+ }
+}
+
+impl BuildCallbacks {
+ fn new() -> Self {
+ Self(IGNORE_MACROS.into_iter().map(|s| s.to_owned()).collect())
+ }
+}
+
+fn main() {
+ // Tell cargo to invalidate the built crate whenever the wrapper changes
+ println!("cargo:rerun-if-changed=src/wrapper.h");
+
+ // Run cmake to configure only
+ Command::new("cmake")
+ .args(["../../", "-B../../"])
+ .output()
+ .expect("failed to invoke cmake");
+
+ // The bindgen::Builder is the main entry point
+ // to bindgen, and lets you build up options for
+ // the resulting bindings.
+ let bindings = bindgen::Builder::default()
+ // The input header we would like to generate
+ // bindings for.
+ .header("src/wrapper.h")
+ // Fix math.h double defines
+ .parse_callbacks(Box::new(BuildCallbacks::new()))
+ .clang_arg("-I../../include")
+ .clang_arg("-I../../sql")
+ .clang_arg("-xc++")
+ .clang_arg("-std=c++17")
+ // Don't derive copy for structs
+ .derive_copy(false)
+ // Use rust-style enums labeled with non_exhaustive to represent C enums
+ .default_enum_style(EnumVariation::Rust {
+ non_exhaustive: true,
+ })
+ // LLVM has some issues with long dobule and ABI compatibility
+ // disabling the only relevant function here to suppress errors
+ .blocklist_function("strfroml")
+ .blocklist_function("strfromf64x")
+ .blocklist_function("strtof64x_l")
+ .blocklist_function("strtof64x")
+ .blocklist_function("strtold")
+ .blocklist_function("strtold_l")
+ // qvct, evct, qfcvt_r, ...
+ .blocklist_function("[a-z]{1,2}cvt(?:_r)?")
+ // c++ things that aren't supported
+ .blocklist_item("List_iterator")
+ .blocklist_type("std::char_traits")
+ .opaque_type("std_.*")
+ .blocklist_item("std_basic_string")
+ .blocklist_item("std_collate.*")
+ .blocklist_item("__gnu_cxx.*")
+ // Finish the builder and generate the bindings.
+ .generate()
+ // Unwrap the Result and panic on failure.
+ .expect("Unable to generate bindings");
+
+ // Write the bindings to the $OUT_DIR/bindings.rs file.
+ let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
+ bindings
+ .write_to_file(out_path.join("bindings.rs"))
+ .expect("couldn't write bindings");
+}
diff --git a/rust/bindings/src/hand_impls.rs b/rust/bindings/src/hand_impls.rs
new file mode 100644
index 0000000000000..c70f6734d6f53
--- /dev/null
+++ b/rust/bindings/src/hand_impls.rs
@@ -0,0 +1,122 @@
+use std::ffi::{c_char, c_double, c_int, c_long, c_longlong, c_uint, c_ulong, c_ulonglong};
+
+use super::{mysql_var_check_func, mysql_var_update_func, TYPELIB};
+
+// Defined in service_encryption.h but not imported because of tilde syntax
+pub const ENCRYPTION_KEY_VERSION_INVALID: c_uint = !0;
+
+#[allow(dead_code)] // not sure why this lint hits
+pub const PLUGIN_VAR_MASK: u32 = super::PLUGIN_VAR_READONLY
+ | super::PLUGIN_VAR_NOSYSVAR
+ | super::PLUGIN_VAR_NOCMDOPT
+ | super::PLUGIN_VAR_NOCMDARG
+ | super::PLUGIN_VAR_OPCMDARG
+ | super::PLUGIN_VAR_RQCMDARG
+ | super::PLUGIN_VAR_DEPRECATED
+ | super::PLUGIN_VAR_MEMALLOC;
+
+// We hand write these stucts because the definition is tricky, not all fields are
+// always present
+
+// no support for THD yet
+macro_rules! declare_sysvar_type {
+ (@common $name:ident: $(#[$doc:meta] $fname:ident: $fty:ty),* $(,)*) => {
+ // Common implementation
+ #[repr(C)]
+ #[derive(Debug)]
+ pub struct $name {
+ /// Variable flags
+ pub flags: c_int,
+ /// Name of the variable
+ pub name: *const c_char,
+ /// Variable description
+ pub comment: *const c_char,
+ /// Function for getting the variable
+ pub check: mysql_var_check_func,
+ /// Function for setting the variable
+ pub update: mysql_var_update_func,
+
+ // Repeated fields
+ $(
+ #[$doc]
+ pub $fname: $fty
+ ),*
+ }
+ };
+ (basic: $name:ident, $ty:ty) => {
+ // A "basic" sysvar
+ declare_sysvar_type!{
+ @common $name:
+ #[doc = "Pointer to the value"]
+ value: *mut $ty,
+ #[doc = "Default value"]
+ def_val: $ty,
+ }
+ };
+ (const basic: $name:ident, $ty:ty) => {
+ // A "basic" sysvar
+ declare_sysvar_type!{
+ @common $name:
+ #[doc = "Pointer to the value"]
+ value: *const $ty,
+ #[doc = "Default value"]
+ def_val: $ty,
+ }
+ };
+ (simple: $name:ident, $ty:ty) => {
+ // A "simple" sysvar, with minimum maximum and block size
+ declare_sysvar_type!{
+ @common $name:
+ #[doc = "Pointer to the value"]
+ value: *mut $ty,
+ #[doc = "Default value"]
+ def_val: $ty,
+ #[doc = "Min value"]
+ min_val: $ty,
+ #[doc = "Max value"]
+ max_val: $ty,
+ #[doc = "Block size"]
+ blk_sz: $ty,
+ }
+ };
+ (typelib: $name:ident, $ty:ty) => {
+ // A "typelib" sysvar
+ declare_sysvar_type!{
+ @common $name:
+ #[doc = "Pointer to the value"]
+ value: *mut $ty,
+ #[doc = "Default value"]
+ def_val: $ty,
+ #[doc = "Typelib"]
+ typelib: *const TYPELIB
+ }
+ };
+
+
+ // (typelib: $name:ident, $ty:ty) => {
+
+ // };
+ // (thd: $name:ident, $ty:ty) => {
+
+ // };
+}
+
+declare_sysvar_type!(@common sysvar_common_t:);
+declare_sysvar_type!(basic: sysvar_bool_t, bool);
+declare_sysvar_type!(basic: sysvar_str_t, *mut c_char);
+declare_sysvar_type!(typelib: sysvar_enum_t, c_ulong);
+declare_sysvar_type!(typelib: sysvar_set_t, c_ulonglong);
+declare_sysvar_type!(simple: sysvar_int_t, c_int);
+declare_sysvar_type!(simple: sysvar_long_t, c_long);
+declare_sysvar_type!(simple: sysvar_longlong_t, c_longlong);
+declare_sysvar_type!(simple: sysvar_uint_t, c_uint);
+declare_sysvar_type!(simple: sysvar_ulong_t, c_ulong);
+declare_sysvar_type!(simple: sysvar_ulonglong_t, c_ulonglong);
+declare_sysvar_type!(simple: sysvar_double_t, c_double);
+
+// declare_sysvar_type!(thdbasic: thdvar_bool_t, bool);
+// declare_sysvar_type!(thdbasic: thdvar_str_t, *mut c_char);
+// declare_sysvar_type!(typelib: sysvar_enum_t, c_ulong);
+// declare_sysvar_type!(typelib: sysvar_set_t, c_ulonglong);
+
+// type THDVAR_FUNC = Option *mut T>;
diff --git a/rust/bindings/src/lib.rs b/rust/bindings/src/lib.rs
new file mode 100644
index 0000000000000..402b4d3501ea8
--- /dev/null
+++ b/rust/bindings/src/lib.rs
@@ -0,0 +1,15 @@
+//! Bindings module
+//!
+//! Autogenerated bindings to C interfaces for Rust
+#![allow(non_upper_case_globals)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+#![allow(clippy::useless_transmute)]
+#![allow(clippy::too_many_arguments)]
+#![allow(clippy::missing_safety_doc)]
+
+// Bindings are autogenerated at build time using build.rs
+include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
+
+mod hand_impls;
+pub use hand_impls::*;
diff --git a/rust/bindings/src/wrapper.h b/rust/bindings/src/wrapper.h
new file mode 100644
index 0000000000000..cdc2c07e514f3
--- /dev/null
+++ b/rust/bindings/src/wrapper.h
@@ -0,0 +1,6 @@
+// Directives here indicate what to include in bindings
+
+// #include
+#include
+#include
+#include
diff --git a/rust/examples/encryption/Cargo.toml b/rust/examples/encryption/Cargo.toml
new file mode 100644
index 0000000000000..71e17a51ce84b
--- /dev/null
+++ b/rust/examples/encryption/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "encryption-example"
+version = "0.1.0"
+edition = '2021'
+
+[lib]
+crate-type = ["cdylib"]
+
+[dependencies]
+mariadb = { path = "../../mariadb" }
+aes-gcm = "0.10"
+sha2 = "0.10"
+rand = "0.8"
diff --git a/rust/examples/encryption/src/lib.rs b/rust/examples/encryption/src/lib.rs
new file mode 100644
index 0000000000000..763f0278d22c3
--- /dev/null
+++ b/rust/examples/encryption/src/lib.rs
@@ -0,0 +1,168 @@
+//! Basic encryption plugin using:
+//!
+//! - SHA256 as the hasher
+
+#![allow(unused)]
+
+use std::sync::Mutex;
+use std::time::{Duration, Instant};
+
+use aes_gcm::{
+ aead::{Aead, KeyInit, OsRng},
+ Aes256Gcm,
+ Nonce, // Or `Aes128Gcm`
+};
+use mariadb::plugin::encryption::{Encryption, EncryptionError, Flags, KeyError, KeyManager};
+use mariadb::plugin::*;
+use rand::Rng;
+use sha2::{Digest, Sha256 as Hasher};
+
+/// Range of key rotations, as seconds
+const KEY_ROTATION_MIN: f32 = 45.0;
+const KEY_ROTATION_MAX: f32 = 90.0;
+const KEY_ROTATION_INTERVAL: f32 = KEY_ROTATION_MAX - KEY_ROTATION_MIN;
+const SHA256_SIZE: usize = 32;
+// const KEY_ROTATION_INTERVAL: Duration =
+// KEY_ROTATION_MAX - KEY_ROTATION_MIN;
+
+/// Our global key version state
+static KEY_VERSIONS: Mutex