Skip to main content

Module sql_literal

Module sql_literal 

Source
Expand description

Escape SQL text for safe splicing into a target-language string literal.

Every backend embeds the query’s SQL text directly into the generated source as a string literal (conn.prepare("SELECT ..."), sqlx::query!("SELECT ..."), and so on). Before this module existed, only the TypeScript backends escaped that text (escape_ts_template_literal and escape_ts_double_quoted_literal); every other backend spliced the cleaned SQL straight into a host literal with no escaping at all. Two distinct failure classes follow from that:

  • Injection. Kotlin’s non-raw "..." string, Ruby’s "...", and Elixir’s "..." are all interpolating literals: $name, #{name}, and #{name} respectively splice a same-scope variable’s runtime value into the string. When SQL text contains one of those sequences and it happens to name an in-scope parameter, the generated code compiles cleanly and substitutes caller-controlled data directly into the SQL text – bypassing the ?/$N parameter binding entirely. This is the root cause of the Kotlin injection tracked as issue #176.
  • Silent corruption or a hard compile break. The remaining host forms (Go, Java, C#, PHP, Python, Rust, and the raw-string variants) do not interpolate, but an unescaped backslash or embedded quote either changes what the database receives (a LIKE 'a\_b%' backslash silently becomes a real escape) or breaks the literal outright (a quoted SQL identifier like SELECT "type" terminates the host string early).

One function per host literal form lives here, not one per backend, because the literal form – not the driver – determines what needs escaping. Every function takes the already-cleaned SQL text (post clean_sql/clean_sql_oneline/placeholder rewriting) and returns text safe to splice verbatim between that host form’s delimiters. None of them touch delimiters themselves except rust_raw_string_literal, which must choose its own delimiter width.

Only literal forms actually emitted by a backend in this crate are implemented here – see each function’s doc comment for which backends call it.

Functions§

double_percent_for_percent_paramstyle
Double every literal % in SQL text destined for a Python %-paramstyle DB-API driver (psycopg3’s %(name)s, aiomysql’s/PyMySQL’s %s).
escape_csharp_verbatim_string
Escape SQL text for splicing into a C# verbatim @"..." string literal.
escape_elixir_double_quoted
Escape SQL text for splicing into an Elixir double-quoted "..." string literal.
escape_go_interpreted_string
Escape SQL text for splicing into a Go interpreted "..." string literal.
escape_java_string
Escape SQL text for splicing into a Java plain "..." string literal.
escape_kotlin_string
Escape SQL text for splicing into a Kotlin non-raw "..." string literal.
escape_php_single_quoted
Escape SQL text for splicing into a PHP single-quoted '...' string literal.
escape_python_triple_double
Escape SQL text for splicing into a Python triple-double-quoted """...""" string literal.
escape_ruby_double_quoted
Escape SQL text for splicing into a Ruby double-quoted "..." string literal.
escape_rust_string
Escape SQL text for splicing into a Rust plain "..." string literal.
rust_raw_string_literal
Build a complete Rust raw string literal (r#"..."#, widened as needed) containing sql verbatim.