HHH-15736 Add escape logic to cockroach and fix mysql 5.7

This commit is contained in:
Marco Belladelli 2022-12-15 11:33:49 +01:00 committed by Christian Beikov
parent ae54ca8ae7
commit fc7bdce2c8
4 changed files with 148 additions and 10 deletions

View File

@ -15,6 +15,7 @@ import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.expression.Literal;
import org.hibernate.sql.ast.tree.expression.Summarization;
import org.hibernate.sql.ast.tree.predicate.BooleanExpressionPredicate;
import org.hibernate.sql.ast.tree.predicate.LikePredicate;
import org.hibernate.sql.ast.tree.select.QueryGroup;
import org.hibernate.sql.ast.tree.select.QueryPart;
import org.hibernate.sql.ast.tree.select.QuerySpec;
@ -153,6 +154,31 @@ public class CockroachLegacySqlAstTranslator<T extends JdbcOperation> extends Ab
}
}
@Override
public void visitLikePredicate(LikePredicate likePredicate) {
// Custom implementation because CockroachDB uses backslash as default escape character
likePredicate.getMatchExpression().accept( this );
if ( likePredicate.isNegated() ) {
appendSql( " not" );
}
if ( likePredicate.isCaseSensitive() ) {
appendSql( " like " );
}
else {
appendSql( WHITESPACE );
appendSql( getDialect().getCaseInsensitiveLike() );
appendSql( WHITESPACE );
}
likePredicate.getPattern().accept( this );
if ( likePredicate.getEscapeCharacter() != null ) {
appendSql( " escape " );
likePredicate.getEscapeCharacter().accept( this );
}
else {
appendSql( " escape ''" );
}
}
@Override
protected boolean supportsRowValueConstructorSyntaxInQuantifiedPredicates() {
return false;

View File

@ -143,12 +143,50 @@ public class MySQLLegacySqlAstTranslator<T extends JdbcOperation> extends Abstra
@Override
public void visitLikePredicate(LikePredicate likePredicate) {
super.visitLikePredicate( likePredicate );
// Custom implementation because MySQL uses backslash as the default escape character
// We can override this by specifying an empty escape character
// See https://dev.mysql.com/doc/refman/8.0/en/string-comparison-functions.html#operator_like
if ( !( (MySQLLegacyDialect) getDialect() ).isNoBackslashEscapesEnabled() && likePredicate.getEscapeCharacter() == null ) {
appendSql( " escape ''" );
if ( getDialect().getVersion().isSameOrAfter( 8 ) ) {
// From version 8 we can override this by specifying an empty escape character
// See https://dev.mysql.com/doc/refman/8.0/en/string-comparison-functions.html#operator_like
super.visitLikePredicate( likePredicate );
if ( !getDialect().isNoBackslashEscapesEnabled() && likePredicate.getEscapeCharacter() == null ) {
appendSql( " escape ''" );
}
}
else {
if ( likePredicate.isCaseSensitive() ) {
likePredicate.getMatchExpression().accept( this );
if ( likePredicate.isNegated() ) {
appendSql( " not" );
}
appendSql( " like " );
renderBackslashEscapedLikePattern(
likePredicate.getPattern(),
likePredicate.getEscapeCharacter(),
getDialect().isNoBackslashEscapesEnabled()
);
}
else {
appendSql( getDialect().getLowercaseFunction() );
appendSql( OPEN_PARENTHESIS );
likePredicate.getMatchExpression().accept( this );
appendSql( CLOSE_PARENTHESIS );
if ( likePredicate.isNegated() ) {
appendSql( " not" );
}
appendSql( " like " );
appendSql( getDialect().getLowercaseFunction() );
appendSql( OPEN_PARENTHESIS );
renderBackslashEscapedLikePattern(
likePredicate.getPattern(),
likePredicate.getEscapeCharacter(),
getDialect().isNoBackslashEscapesEnabled()
);
appendSql( CLOSE_PARENTHESIS );
}
if ( likePredicate.getEscapeCharacter() != null ) {
appendSql( " escape " );
likePredicate.getEscapeCharacter().accept( this );
}
}
}
@ -197,4 +235,9 @@ public class MySQLLegacySqlAstTranslator<T extends JdbcOperation> extends Abstra
protected String getFromDual() {
return " from dual";
}
@Override
public MySQLDialect getDialect() {
return (MySQLDialect) super.getDialect();
}
}

View File

@ -15,6 +15,7 @@ import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.expression.Literal;
import org.hibernate.sql.ast.tree.expression.Summarization;
import org.hibernate.sql.ast.tree.predicate.BooleanExpressionPredicate;
import org.hibernate.sql.ast.tree.predicate.LikePredicate;
import org.hibernate.sql.ast.tree.select.QueryGroup;
import org.hibernate.sql.ast.tree.select.QueryPart;
import org.hibernate.sql.ast.tree.select.QuerySpec;
@ -125,6 +126,31 @@ public class CockroachSqlAstTranslator<T extends JdbcOperation> extends Abstract
}
}
@Override
public void visitLikePredicate(LikePredicate likePredicate) {
// Custom implementation because CockroachDB uses backslash as default escape character
likePredicate.getMatchExpression().accept( this );
if ( likePredicate.isNegated() ) {
appendSql( " not" );
}
if ( likePredicate.isCaseSensitive() ) {
appendSql( " like " );
}
else {
appendSql( WHITESPACE );
appendSql( getDialect().getCaseInsensitiveLike() );
appendSql( WHITESPACE );
}
likePredicate.getPattern().accept( this );
if ( likePredicate.getEscapeCharacter() != null ) {
appendSql( " escape " );
likePredicate.getEscapeCharacter().accept( this );
}
else {
appendSql( " escape ''" );
}
}
@Override
protected boolean supportsRowValueConstructorSyntaxInQuantifiedPredicates() {
return false;

View File

@ -142,12 +142,50 @@ public class MySQLSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlA
@Override
public void visitLikePredicate(LikePredicate likePredicate) {
super.visitLikePredicate( likePredicate );
// Custom implementation because MySQL uses backslash as the default escape character
// We can override this by specifying an empty escape character
// See https://dev.mysql.com/doc/refman/8.0/en/string-comparison-functions.html#operator_like
if ( !( (MySQLDialect) getDialect() ).isNoBackslashEscapesEnabled() && likePredicate.getEscapeCharacter() == null ) {
appendSql( " escape ''" );
if ( getDialect().getVersion().isSameOrAfter( 8 ) ) {
// From version 8 we can override this by specifying an empty escape character
// See https://dev.mysql.com/doc/refman/8.0/en/string-comparison-functions.html#operator_like
super.visitLikePredicate( likePredicate );
if ( !getDialect().isNoBackslashEscapesEnabled() && likePredicate.getEscapeCharacter() == null ) {
appendSql( " escape ''" );
}
}
else {
if ( likePredicate.isCaseSensitive() ) {
likePredicate.getMatchExpression().accept( this );
if ( likePredicate.isNegated() ) {
appendSql( " not" );
}
appendSql( " like " );
renderBackslashEscapedLikePattern(
likePredicate.getPattern(),
likePredicate.getEscapeCharacter(),
getDialect().isNoBackslashEscapesEnabled()
);
}
else {
appendSql( getDialect().getLowercaseFunction() );
appendSql( OPEN_PARENTHESIS );
likePredicate.getMatchExpression().accept( this );
appendSql( CLOSE_PARENTHESIS );
if ( likePredicate.isNegated() ) {
appendSql( " not" );
}
appendSql( " like " );
appendSql( getDialect().getLowercaseFunction() );
appendSql( OPEN_PARENTHESIS );
renderBackslashEscapedLikePattern(
likePredicate.getPattern(),
likePredicate.getEscapeCharacter(),
getDialect().isNoBackslashEscapesEnabled()
);
appendSql( CLOSE_PARENTHESIS );
}
if ( likePredicate.getEscapeCharacter() != null ) {
appendSql( " escape " );
likePredicate.getEscapeCharacter().accept( this );
}
}
}
@ -196,4 +234,9 @@ public class MySQLSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlA
protected String getFromDual() {
return " from dual";
}
@Override
public MySQLDialect getDialect() {
return (MySQLDialect) super.getDialect();
}
}