Match your server's string settings
Run in production
AskDB’s SQL checks read a backslash inside a ’…’ string the way each engine does by default. If your server reads it differently, AskDB and the server disagree about where a string ends, and SQL the checks accept can run code they never saw. Set backslashEscapes to match your server.
Before you start
Section titled “Before you start”- A MySQL, MariaDB or Postgres server. SQL Server and SQLite never read a backslash in
'…'as an escape, so they need nothing here. - Code that passes a dialect to
ask(), or to@askdb/client’saskdb.ask().askdb.config.tstakes a built-in dialect id only: see Limits.
1. Check your server’s setting
Section titled “1. Check your server’s setting”| Engine | Run | Set backslashEscapes when |
|---|---|---|
| MySQL, MariaDB | SELECT @@sql_mode; | The result includes NO_BACKSLASH_ESCAPES: set false. The default reads a backslash as an escape, and so does a MySQL-family DialectSpec with backslashEscapes unset. |
| Postgres | SHOW standard_conforming_strings; | The result is off: set true. The default, on, reads a backslash as plain text. |
Check the setting your application’s connections get. A role, a database or the connection string can change it.
2. Make a dialect that matches
Section titled “2. Make a dialect that matches”Spread the built-in spec for your engine, and set backslashEscapes:
import { MYSQL_DIALECT, POSTGRES_DIALECT, type DialectSpec } from "@askdb/core";
// MySQL or MariaDB with NO_BACKSLASH_ESCAPES in sql_mode (spread MARIADB_DIALECT for MariaDB).export const mysqlNoBackslashEscapes: DialectSpec = { ...MYSQL_DIALECT, backslashEscapes: false };
// Postgres with standard_conforming_strings = off.export const postgresLegacyStrings: DialectSpec = { ...POSTGRES_DIALECT, backslashEscapes: true };Spreading keeps the built-in spec’s keywords, blocked functions and id. @askdb/mysql re-exports MYSQL_DIALECT and MARIADB_DIALECT from @askdb/core, so you can import them from either package.
3. Pass it everywhere you pass a dialect
Section titled “3. Pass it everywhere you pass a dialect”const result = await ask({ question, schema, model, dialect: mysqlNoBackslashEscapes });ask(): asdialect.@askdb/client: per call, asaskdb.ask(question, { dialect: mysqlNoBackslashEscapes }).validateSelectSql(): as its first argument, for SQL you check yourself.- A rebind: as
dialectinbindPreparedQuery(prepared, values, { schema, dialect: mysqlNoBackslashEscapes }), or toaskdb.bind(). A rebind refuses a templateask()made under your spec unless you pass the spec again, so your setting can’t drop out at rebind.
4. Run user-typed values as parameters
Section titled “4. Run user-typed values as parameters”The same setting decides how bindPreparedQuery() escapes the business values it inlines into its sql: with a mismatched dialect, a value containing a backslash can escape its literal. For values your users type, run unboundSql with params instead.
Tenant IDs don’t depend on the setting. By default (tenantSqlMode: "sql-params") they’re driver parameters, in ask() and at rebind. Where AskDB inlines them (tenantSqlMode: "sql-only"), a tenant ID must be printable ASCII without a backslash, or it’s refused (UNESCAPABLE_TENANT_ID).
Limits
Section titled “Limits”askdb.config.tstakes a built-in dialect id only, so the CLI, the HTTP API and Studio always assume the default settings (#340). Run them against a server with its default string settings.- The connection charset matters for parameters too. Under a MySQL or MariaDB connection charset of
sjis,cp932orujis, the client sends¥as byte 0x5C, which the server reads as a backslash. A driver that interpolates parameters into the SQL text on the client, such as mysql2’squery()with params, is affected; server-side prepared statements (mysql2’sexecute()) aren’t. Use autf8mb4connection, orexecute(). - MySQL’s
ANSI_QUOTESmode isn’t supported (it’s also part of theANSImode). It makes"…"an identifier, which the MySQL dialect reads as a string with backslash escapes, and noDialectSpecsetting matches it. Run AskDB’s SQL on a connection withoutANSI_QUOTES.
Read next
Section titled “Read next”© 2026 Yahya Gilany

