diesel-rs / diesel

A safe, extensible ORM and Query Builder for Rust
https://diesel.rs
Apache License 2.0
12.63k stars 1.06k forks source link

Deprecation of `dsl::any` will prevent use of `TextExpressionMethods::like(any(<expr>))` #3360

Open hgzimmerman opened 2 years ago

hgzimmerman commented 2 years ago

Feature Flags

Problem Description

The deprecation of pg::expression::dsl::any will prevent the use of it in conjunction with any of expression_methods::TextExpressionMethods::like, expression_methods::TextExpressionMethods::like, diesel::expression_methods::PgTextExpressionMethods::ilike, or diesel::expression_methods::PgTextExpressionMethods::not_ilike.

This similarly applies for pg::expression::dsl::all.

Before total removal of these functions in a 3.0.0 release, some alternative should be in place to represent the same semantics.

mleonhard commented 7 months ago

I'm using diesel 2.1.4 with stable Rust 1.76. My code returns search results, performing substring search and full-text search. To do substring search, it queries Postgres with LIKE ANY ( "%term1%", "%term2%", ...). Diesel has no like_any function, so I'm using like and any. Since any was deprecated in https://github.com/diesel-rs/diesel/commit/fa3dc3ea04b099916c5a3fd6e421cf8393fcede8 , the Rust compiler shows a deprecation warning.

Is there a way to do LIKE ANY without using the deprecated any function or sql?

Thanks!


Code:

let query_string = query_text.for_search();
// https://www.postgresql.org/docs/current/textsearch-controls.html
let config = TsConfigurationByName("english");
let vector = to_tsvector_with_search_config(&config, tags::text_search);
let query = websearch_to_tsquery_with_search_config(&config, &query_string);
let like_tokens: Vec<String> = query_string
    .split(' ')
    .filter(|s| s.len() > 1)
    .map(|s| format!("%{s}%"))
    .collect();
tags::table
    .filter(tags::text_search.like(any(like_tokens))) // <-- Generates warning
    .limit(30)
    .union(
        tags::table
            .filter(vector.matches(query))
            .order_by(ts_rank_cd(vector, query).desc())
            .limit(20),
    )
    .get_results::<Tag>(conn)
    .map_err(|e| Error::server_error(e.to_string()))

Compiler warning:

warning: use of deprecated function `diesel::dsl::any`: Use `ExpressionMethods::eq_any` instead
weiznich commented 7 months ago

Is there a way to do LIKE ANY without using the deprecated any function or sql?

Not with the built-in DSL. You would build your own DSL extension for that. Otherwise we are open to receive contributions that provide a built-in not-deprecated DSL node for this functionality.