Skip to content

Support String Concatenation in Query #610

Description

@ElijahAhianyo

Postgres, MySQL, and SQLite all support string concatenation via CONCAT/CONCAT_WS functions, and Postgres and SQLite additionally support it via the || operator. We currently don't handle either form, and both + and || silently produce broken SQL statements.

Example:

#[model]
#[derive(Debug, Clone)]
pub struct Product {
    #[model(primary_key)]
    id: Auto<i64>,
    #[model(unique)]
    title: LimitedString<64>,
    name: LimitedString<255>,
}

...
query!(Product, ($name + $title) == "mortal kombat").all(&db)

Currently produces

SELECT "id", "title", "name",  FROM "foo__product" WHERE "name" + "title" = "mortal kombat"

which is meaningless for text columns.
Trying || instead:

query!(Product, ($name || $title) == "mortal kombat").all(&db)

Also produces:

SELECT "id", "title", "name" FROM "foo__product" WHERE "name" OR "title" = "mortal kombat"

because || is being parsed as logical OR, not SQL string concatenation.

Ideally, we want this to yield a cot::db::query::Expr::Concat expression:

Usage in the query! macro, and for the + operator specifically, we'd like it to dispatch to Expr::Concat when operating on string-typed fields(whenever possible), while continuing to produce Expr::Add for numeric fields

One caveat: this can get tricky for concat chains like below:

query!(Product, ($name + "-" + $title) == "mortal - kombat" )

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-libCrate: cot (main library crate)C-macrosCrate: cot-macrosenhancementNew feature or requesthelp wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions