ADBC Driver for MariaDB

Driver Version v0.1.6 Release Date 2026-11-10 Tested With MariaDB 12.2

This driver provides access to MariaDB , the free and open-source relational database management system.

Installation

The MariaDB driver can be installed with dbc :

dbc install mariadb

Connecting

To connect, edit the uri option below to match your environment and run the following:

from adbc_driver_manager import dbapi

conn = dbapi.connect(
    driver="mariadb", db_kwargs={"uri": "mariadb://root@localhost:3306/demo"}
)

Note: The example above is for Python using the adbc-driver-manager package but the process will be similar for other driver managers. See adbc-quickstarts .

Connection String Format

Connection strings are passed with the uri option. The driver supports two formats:

Go MariaDB Driver DSN Format (Alternative)

The driver also accepts the Go MariaDB Driver DSN format :

[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...&paramN=valueN]

Examples:

  • user:pass@tcp(localhost:3306)/mydb

  • user@tcp(127.0.0.1:3306)/mydb

  • user:pass@unix(/tmp/mariadb.sock)/mydb

Feature & Type Support

Feature MariaDB
Bulk Ingestion Create ✅
Append ✅
Create/Append ✅
Replace ✅
Temporary Table ✅
Target Catalog ❌
Target Schema ❌
Non-nullable fields are marked NOT NULL ✅
Catalog (GetObjects) depth=catalogs ✅
depth=db_schemas ✅
depth=tables ✅
depth=columns (all) ✅
Get Parameter Schema ✅
Get Table Schema ✅
Prepared Statements ✅
Transactions ✅

Types

Database to Arrow

Database Type MariaDB

BIGINT

int64

BIGINT UNSIGNED

uint64

BIT

binary

BOOLEAN

int32, int8 ⚠️ [1]

DATE

date32[day]

DATETIME

timestamp[us]

DOUBLE PRECISION

double

FLOAT

float ⚠️ [2]

INT

int32

JSON

string

NUMERIC

decimal64

SMALLINT

int16

TIME

duration[us]

TIMESTAMP

timestamp[us], timestamp[us] (with time zone) ⚠️ [1]

VARBINARY

binary

VARCHAR

string

Arrow to Database

Arrow Type MariaDB Type
Bind Ingest

binary

VARBINARY

BLOB

binary_view

VARBINARY

BLOB

bool

BOOLEAN

date32[day]

DATE

decimal128

DECIMAL

DECIMAL ⚠️ [3]

double

DOUBLE PRECISION

fixed_size_binary

VARBINARY

BLOB

float

FLOAT

FLOAT ⚠️ [2]

halffloat

FLOAT

(NA/not tested)

int16

SMALLINT

int32

INT

int64

BIGINT

large_binary

VARBINARY

LONGBLOB

large_string

VARCHAR

TEXT

string

VARCHAR

TEXT

string_view

VARCHAR

TEXT

time32[ms]

TIME

time32[s]

TIME

time64[ns]

TIME

time64[us]

TIME

timestamp[ms]

DATETIME

timestamp[ms] (with time zone)

TIMESTAMP

timestamp[ns]

DATETIME

timestamp[ns] (with time zone)

TIMESTAMP

timestamp[s]

DATETIME

timestamp[s] (with time zone)

TIMESTAMP

timestamp[us]

DATETIME

timestamp[us] (with time zone)

TIMESTAMP

uint16

SMALLINT UNSIGNED

uint32

INT UNSIGNED

uint64

BIGINT UNSIGNED

uint8

TINYINT UNSIGNED

In addition to the shared SQL types, metadata-based schema discovery supports:

  • UUID as the standard Arrow arrow.uuid extension type.

  • VECTOR(n) as fixed_size_list<float32>[n]. If a query result omits the vector width, the driver conservatively returns packed binary data with mariadb.vector_encoding=float32_le metadata.

  • INET4 and INET6 as canonical strings carrying the intended logical type in mariadb.logical_arrow_type. The driver deliberately avoids unregistered ARROW:extension:name values, since some consumers reject the entire schema.

  • Spatial columns as WKB binary with mariadb.logical_arrow_type=geoarrow.wkb. The driver removes MariaDB’s internal four-byte SRID prefix while reading and uses ST_GeomFromWKB during bulk ingest.

  • JSON as the standard Arrow arrow.json extension type. Because MariaDB stores JSON as LONGTEXT, GetTableSchema recognizes its JSON_VALID constraint to recover the logical type.

  • ENUM and SET as strings. Their declared values are JSON arrays in the mariadb.enum_values and mariadb.set_values field metadata.

  • Unsigned integers as Arrow unsigned integers, including BIGINT UNSIGNED as uint64. DECIMAL values up to precision 38 use the narrowest Arrow decimal type. Wider decimals are lossless UTF-8 strings with precision, scale, mariadb.logical_arrow_type, and mariadb.arrow_fallback=string metadata, avoiding consumer failures on decimal256 schemas.

  • BIT(n) as binary with its bit width in sql.length, and YEAR as int16. Binary collations remain Arrow binary while textual collations remain UTF-8.

  • TIME as an Arrow duration, preserving MariaDB’s negative values and values up to 838 hours. DATE, DATETIME, and TIMESTAMP retain fractional-second precision; zero dates follow mariadb.query.zero_datetime_behavior.

MariaDB’s result-set protocol sometimes reports logical aliases using their storage types: notably UUID as CHAR and JSON as LONGTEXT. For arbitrary SQL query results the driver does not guess from values. Cast at the consumer or use GetTableSchema when native logical types are required.

FLOAT precision

MariaDB formats FLOAT values with only 6 significant digits when results are sent over the text protocol, which the driver uses for queries executed without parameters or a prior Prepare. Values are stored exactly, but such reads may be rounded (for example, 16777216 is returned as 16777200). This is a server behavior shared by all text-protocol clients.

To read FLOAT values exactly, prepare the statement before executing it, so results use the binary protocol:

with conn.cursor() as cursor:
    cursor.adbc_prepare("SELECT v FROM t")
    cursor.execute("SELECT v FROM t")

Alternatively, use DOUBLE columns or CAST(v AS DOUBLE).

Parameter schema discovery

Prepared statements support GetParameterSchema. The returned Arrow schema contains one field for each positional ? parameter, in binding order. The placeholder parser ignores question marks inside quoted strings, quoted identifiers, and SQL comments.

MariaDB’s prepared-statement protocol reports the number of parameters but does not expose their inferred definitions through database/sql. Parameter fields are therefore unnamed, nullable Arrow null fields. Applications can use the schema to discover parameter count and order, but must still obtain the intended parameter types from application or query context.

The statement must be prepared before requesting its parameter schema:

from adbc_driver_manager import dbapi

with dbapi.connect(driver="mariadb", uri="mariadb://root@localhost/demo") as conn:
    with conn.cursor() as cursor:
        sql = "SELECT CAST(? AS SIGNED), CAST(? AS CHAR)"
        parameter_schema = cursor.adbc_prepare(sql)
        print(parameter_schema)

        cursor.execute(sql, [42, "MariaDB"])
        print(cursor.fetch_arrow_table())

Transactions and isolation levels

Connections use autocommit by default at the ADBC API level. Set adbc.connection.autocommit to false to group subsequent statements into a transaction, then use Commit or Rollback to finish it. MariaDB implicitly starts the next transaction when another statement executes while autocommit remains disabled. Commit and rollback return an invalid-state error while autocommit is enabled.

The standard adbc.connection.transaction.isolation_level option supports:

  • adbc.connection.transaction.isolation.default

  • adbc.connection.transaction.isolation.read_uncommitted

  • adbc.connection.transaction.isolation.read_committed

  • adbc.connection.transaction.isolation.repeatable_read

  • adbc.connection.transaction.isolation.serializable

The option applies to the dedicated MariaDB session used by the ADBC connection and can also be read to obtain the active level. Snapshot and linearizable isolation are not supported by MariaDB and return ADBC NOT_IMPLEMENTED. Change the isolation level before starting a transaction; MariaDB does not allow transaction characteristics to change while a transaction is active.

from adbc_driver_manager import ConnectionOptions, dbapi

option = ConnectionOptions.ISOLATION_LEVEL.value
level = "adbc.connection.transaction.isolation.serializable"

with dbapi.connect(
    driver="mariadb",
    uri="mariadb://root@localhost/demo",
    autocommit=False,
) as conn:
    conn.adbc_connection.set_options(**{option: level})
    print(conn.adbc_connection.get_option(option))

    with conn.cursor() as cursor:
        cursor.execute("UPDATE accounts SET balance = balance - 10 WHERE id = 1")
    conn.commit()

Object metadata

GetObjects exposes MariaDB table metadata through the standard ADBC nested object schema. Column metadata includes type name, size, decimal digits, numeric radix, character octet length, nullability, default value, comment, auto-increment status, and generated-column status. Primary-key, unique, foreign-key, and check constraints are returned in table_constraints; foreign keys include the referenced catalog, table, and column for every key column in ordinal order.

ADBC has no standard field for invisible columns. The driver preserves that MariaDB attribute in the column remarks using the marker [MariaDB: INVISIBLE], appended after any user-defined column comment. Check-constraint expressions likewise have no field in the standard ADBC constraint structure; the driver exposes their name and CHECK type and uses JSON_VALID(column) internally to recover MariaDB’s logical JSON alias.

Statistics

GetStatistics reports the standard ADBC row-count statistic from information_schema.TABLES and distinct-count estimates for indexed columns from information_schema.STATISTICS. It also exposes the MariaDB-specific statistics mariadb.statistic.data_length, mariadb.statistic.index_length, and mariadb.statistic.avg_row_length; their keys are available through GetStatisticNames.

MariaDB metadata values, including InnoDB row counts and index cardinalities, are estimates. The driver therefore marks these statistics approximate even when exact statistics are requested. It does not implicitly execute ANALYZE TABLE or ANALYZE FORMAT=JSON, since those operations can scan data, update persistent optimizer statistics, or execute the analyzed statement.

Options

adbc.connection.autocommit

Values: true, false. Default: true.

Enable or disable MariaDB session autocommit. Enabling autocommit commits any active transaction, following MariaDB semantics.

adbc.connection.transaction.isolation_level

Values: default, read_uncommitted, read_committed, repeatable_read, and serializable, using their full standardized ADBC option values listed above.

Get or set the transaction isolation level for the MariaDB session.

mariadb.query.zero_datetime_behavior

Values: error, convert_to_null. Default: error.

Control what to do with DATE and TIMESTAMP values that contain zero components in the date (e.g. 0000-00-00), which MariaDB allows for backwards compatibility. By default, this will error; convert_to_null will instead treat these values as equivalent to null.

Compatibility

MariaDB databases are exposed as ADBC catalogs with an empty schema because MariaDB has no namespace below a database. Schema-oriented clients may assign an external name to that namespace; DuckDB exposes it as main, making tables addressable as <attachment>.main.<table> while sending unqualified table names to MariaDB.

When attaching through DuckDB’s ADBC extension, specify MariaDB’s backtick identifier delimiters. Without this option DuckDB uses double quotes, causing MariaDB table lookup to fail unless ANSI_QUOTES SQL mode is enabled.

ATTACH 'profile://mydb' AS mariadb (TYPE adbc, DELIMITER '``');
SELECT * FROM mariadb.main.my_table;

This driver was tested on:

  • MariaDB 12.2.2-MariaDB-ubu2404 (mariadb.org binary distribution)