Skip to content

Expose DBMS-specific quoting/escaping APIs #2487

@ojacobson

Description

@ojacobson

Is your feature request related to a problem? Please describe.

I am working on a program that, as part of its normal operation, creates new Postgres databases. The Postgres syntax for creating databases reads:

create database some_name; -- options elided

The database name can be any Postgres identifier. Identifiers which contain reserved words, spaces, or for which case is important must be "quoted like this". Note that these identifiers are not values; Postgres cannot bind them from query parameters.

Describe the solution you'd like

I could safely quote database names to construct queries if the connection or executor type exposed a quote_identifier method, possibly via a trait only implemented for databases for which this operation is available:

let ident = "some string";
let mut conn = pool.acquire().await?;
let ident = conn.quote_identifier(ident).await?;

let query = format!("create database {ident}");
let result = sqlx::query(query).execute(&mut conn).await?;
conn.close().await?;

Describe alternatives you've considered

For my specific use case I'm able to control the generation of database names, and I have ensured that they do not require quoting in practice. This is a limited approach but works well within those limits.

For Postgres, I can also use quote_ident:

let ident = "some string";
let ident = sqlx::query_scalar!("select quote_ident($1)", ident).fetch_one(&mut conn).await?;

However, this requires a roundtrip; libpq's quoting function does not.

Additional context

Note that, at least for Postgres, quoting requires a connection to the DB, at least as far as libpq is concerned (source), because of concerns regarding multibyte encodings for the current client encoding. This isn't true for all databases, but does suggest that the operation should be exposed by a connection and not just by a free function or a method on the DB driver type.

MySQL implements this via a query function, rather than a library function, which would also require a connection.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions