Skip to content

[Feature] Improvements to QueryBuilder #4141

@Diggsey

Description

@Diggsey

Description

The QueryBuilder is adequate for building a query in order, but it has several drawbacks:

  1. It's not possible to refer to the same "bind" parameter multiple times (this might be a Postgres-only feature).
  2. It's not possible to build queries "out of order". This happens if eg. I want to build a query, then wrap the entire thing as a subquery within some outer query. The code building the subquery has to be refactored to work with a mutable borrow of the same parent query.
  3. All static analysis of the queries are lost.

Prefered solution

  1. There should be two Postgres-specific extension methods. One that pushes a new bind and returns an opaque "ID" for that bind. A second that pushes a reference to a previous bind by "ID".

  2. The QueryBuilder should store everything internally as a Vec<SqlOrBind>, and only convert to a string representation when the query is actually built. This way queries can be concatenated, one query can be used inside another, etc. without messing up the bind parameters. (When they are concatenated, all of the binds in the second query are automatically adjusted to not conflict with any binds from the first query)

  3. The QueryBuilder should support a format! style macro, where the user can annotate format arguments with the type of SQL AST node they correspond to. For example: format_sql!("SELECT * FROM foo WHERE {:expression} LIMIT 2"). This would produce a statically checked query like the query! macros, where during checking, the format argument is replaced by a suitable placeholder (eg. NULL for an expression). These format arguments should themselves be QueryBuilders, so that complex parts of the SQL can be built dynamically while still retaining some static checking.

Is this a breaking change? Why or why not?

The sql method on QueryBuilder cannot easily be supported with these changes (although into_sql is fine).

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