Bring your SQL client to DuckDB inside ProxySQL
You’ve connected to the DuckDB endpoint with mysql, run a total, and opened the same table with psql. The next step might be a reporting script or a desktop SQL tool. Being able to use a familiar client is part of the appeal: you can explore an embedded analytical database through tools that already speak MySQL or PostgreSQL.
Choosing the right client means looking at what it does after it connects. An interactive query, a parameterized application call and a tool’s automatic server inspection can take different paths, even when they start with the same connection details.
The DuckDB plugin in ProxySQL 4.0.12 supports simple text queries over both protocols. With that execution path, a client can create tables, write data and ask analytical questions against the shared DuckDB database. Understanding the path helps you decide which existing tools to bring along.
The connection gets you there; DuckDB answers the question
Consider a query that groups sales by region and adds up the amounts. A MySQL client can carry that query to ProxySQL’s DuckDB port, but DuckDB evaluates the grouping and addition. Connecting through PostgreSQL’s port reaches the same engine.
The protocol is how the client and server exchange messages. The SQL language is what the database understands inside those messages. Here, MySQL and PostgreSQL supply the connection protocols; DuckDB 1.4.5 supplies the SQL engine.
That distinction is useful when deciding what to reuse. A client that sends ordinary DuckDB-compatible SQL may fit well. An application that generates MySQL-specific or PostgreSQL-specific SQL needs its statements reviewed. The plugin doesn’t translate those dialects into DuckDB SQL.
Some familiar discovery commands are supported, including version and current-database queries, SHOW TABLES, SHOW DATABASES and SHOW SCHEMAS. Those help a client get oriented. They don’t mean every command the client normally issues will work. For example, the MariaDB client’s status command can issue a combined DATABASE()/USER() query that DuckDB rejects. A successful connection and version check are a useful beginning; the queries your workflow actually needs are the next thing to check.
Start with the query path you can see
Interactive mysql and psql use provides a straightforward starting point. On the MySQL endpoint, the supported request is COM_QUERY. On the PostgreSQL endpoint, it’s the simple Query message.
Client prepared-statement execution is outside this initial plugin surface. PostgreSQL’s extended flow—Parse, Bind, Describe and Execute—is also unsupported. A driver may choose that flow automatically for parameterized calls, so check its execution mode before adapting a script. A plain-looking SQL string in application code doesn’t tell you which protocol messages the driver sends.
If your application depends on an unsupported parameter-binding path, preserve that requirement when assessing the fit. Concatenating untrusted values into SQL would lose the protection binding was meant to provide. The protocol compatibility guide describes the supported surface in detail.
Both endpoints also use ProxySQL’s core frontend TLS handshake before DuckDB handles queries. An encrypted connection is supported; verifying the server’s identity additionally requires trusted certificates and the appropriate client verification settings.
Keep control of each request
Send one SQL statement in each request. For example, to add a row to an existing article_sales demonstration table inside an explicit transaction, send these as three separate requests:
BEGIN;
INSERT INTO article_sales VALUES ('west', 50.00);
COMMIT;
An interactive client may split a script into separate requests for you. A driver that sends the entire script as one request will encounter the plugin’s multiple-statement rejection.
Explicit transaction commands also make the intended behavior clear. The compatibility commands SET autocommit=0 and SET autocommit=1 are accepted as no-ops; they don’t provide MySQL’s general autocommit behavior. If an error invalidates an explicit transaction, issue ROLLBACK before continuing.
Session settings can still be useful. These two requests select and inspect the schema search path for the current connection:
SET search_path='main';
SELECT current_setting('search_path');
Engine-wide controls such as thread count belong to the ProxySQL administrator. A client session cannot change them for everyone through SET.
Decide what the application needs from an answer
A human reading a sales total generally needs the value and its column name. An application may also use the column’s declared type to choose a numeric object or format a chart.
Clients see result columns described as text, even when the displayed value is a decimal total. A reporting library may therefore receive the right value without recognizing it automatically as a number. SQL NULL remains a real protocol null, separate from the string NULL.
Review that behavior before relying on automatic type inference. For nested or specialized DuckDB values, the plugin attempts to produce printable text by casting result columns where a wrapper is valid. Some DML RETURNING results cannot use that wrapper, and an unsupported result column can be returned as NULL. Workflows that need those values should choose a supported representation explicitly.
These choices make the best starting use case clear: familiar clients, DuckDB SQL, simple requests and results whose representation you understand. You can share working tables across the two endpoints without building a new client protocol into your tools. Just remember that the users share database access too; authentication doesn’t create separate table permissions.
The plugin is available through source installation in the published 4.0.12 prerelease, rather than the downloadable packages. For a compatible reporting or exploration workflow, it brings DuckDB within reach of SQL tools you already know.