Blazebit / blaze-persistence

Rich Criteria API for JPA providers
https://persistence.blazebit.com
Apache License 2.0
697 stars 85 forks source link

By default, when using a "LIKE" query, the "ESCAPE" string is automatically concatenated. #1880

Closed CraKeyBoy closed 2 months ago

CraKeyBoy commented 2 months ago

Description

I use ClickHouse as a database and employ Blaze-Persistence for dynamic querying. Starting from version 1.6.9, Blaze-Persistence automatically concatenates the statement "ESCAPE ''" when performing a "LIKE" query by default. However, this causes an error in ClickHouse because ClickHouse does not support appending "ESCAPE" after a "LIKE" query. Could you please help me with resolving this error? Additionally, I would like to know why it is necessary to concatenate the statement "ESCAPE ''".

I have already located the source code for the following class: "ResolvingQueryGenerator ". Line 753 ~ 762

        if (predicate.getEscapeCharacter() != null) {
            sb.append(" ESCAPE ");
            if (predicate.getEscapeCharacter() instanceof StringLiteral) {
                TypeUtils.STRING_CONVERTER.appendTo(escapeCharacter(((StringLiteral) predicate.getEscapeCharacter()).getValue().charAt(0)), sb);
            } else {
                predicate.getEscapeCharacter().accept(this);
            }
        } else if (!externalRepresentation && !jpaProvider.supportsLikePatternEscape() && predicate.getEscapeCharacter() == null && (dbmsDialect.getDefaultEscapeCharacter()) != null) {
            sb.append(" ESCAPE ''");
        }

Expected behavior

cb.where("s.name").like().value("%" + request.getUserName() + "%").noEscape();

 like '%xxx%' 

Actual behavior

cb.where("s.name").like().value("%" + request.getUserName() + "%").noEscape();

 like '%xxx%'   ESCAPE ''

Steps to reproduce

Just use a like query and look the query sql.

Environment

Version: 1.6.11 Spring Boot: 2.3.12 JPA-Provider: Hibernate 5.4.32.Final DBMS: clickhouse use mysql8 DbmsDialect Application Server: N/A

beikov commented 2 months ago

Hi there. The code that you reference is for rendering the HQL fragment that is passed to Hibernate ORM. You can of course create a custom DbmsDialect that extends MySQLDbmsDialect and override the getDefaultEscapeCharacter() method to return null instead. This should allow you to workaround this problem. Note that Clickhouse is not "supported" i.e. we don't regularly test with it or have a DbmsDialect implementation. Hibernate ORM also has no "support" for that database, so you might run into other issues. If you care about that database, please consider contributing support for it.

beikov commented 2 months ago

Also see the documentation that explains a bit about DbmsDialect.

CraKeyBoy commented 2 months ago

OK,I use this method。thx。