[jOOQ/jOOQ#17785] Field::contains should be emulated using DSL::position instead of Field::like, if available

This commit is contained in:
Lukas Eder 2024-12-18 13:38:01 +01:00
parent aec78ab32b
commit f26669a60d
8 changed files with 194 additions and 35 deletions

View File

@ -100,11 +100,42 @@ implements
case YUGABYTEDB:
return false;
case DUCKDB:
return true;
case CLICKHOUSE:
case CUBRID:
case DERBY:
case FIREBIRD:
case H2:
case HSQLDB:
case IGNITE:
case MARIADB:
case MYSQL:
case SQLITE:
case TRINO:
return false;
default:
return false;
return true;
}
}
@ -132,12 +163,45 @@ implements
break;
}
case DUCKDB:
ctx.visit(function(N_CONTAINS, BOOLEAN, value, content));
case CLICKHOUSE:
case CUBRID:
case DERBY:
case FIREBIRD:
case H2:
case HSQLDB:
case IGNITE:
case MARIADB:
case MYSQL:
case SQLITE:
case TRINO: {
acceptDefault(ctx);
break;
}
default:
acceptDefault(ctx);
ctx.visit(function(N_CONTAINS, BOOLEAN, value, content));
break;
}
}
@ -152,7 +216,7 @@ implements
private final void acceptDefault(Context<?> ctx) {
ctx.visit(value.like(DSL.concat(inline("%"), Tools.escapeForLike(content, ctx.configuration()), inline("%")), Tools.ESCAPE));
ctx.visit(DSL.position(Like.requiresStringCast(value), Like.requiresStringCast(content)).gt(inline(0)));
}
// -------------------------------------------------------------------------

View File

@ -100,12 +100,14 @@ implements
case DUCKDB:
ctx.visit(value.lower().contains(content.lower()));
break;
default:
ctx.visit(value.likeIgnoreCase(DSL.concat(inline("%"), Tools.escapeForLike(content, ctx.configuration()), inline("%")), Tools.ESCAPE));
ctx.visit(value.lower().contains(content.lower()));
break;
}
}

View File

@ -94,6 +94,43 @@ implements
@Override
final boolean parenthesised(Context<?> ctx) {
switch (ctx.family()) {
case CUBRID:
case DERBY:
case FIREBIRD:
case H2:
case HSQLDB:
case IGNITE:
case MARIADB:
case MYSQL:
case POSTGRES:
case SQLITE:
case TRINO:
case YUGABYTEDB:
return false;
case DUCKDB:
return true;
@ -101,7 +138,7 @@ implements
return true;
default:
return false;
return true;
}
}
@ -114,6 +151,45 @@ implements
case CUBRID:
case DERBY:
case FIREBIRD:
case H2:
case HSQLDB:
case IGNITE:
case MARIADB:
case MYSQL:
case POSTGRES:
case SQLITE:
case TRINO:
case YUGABYTEDB:
ctx.visit(DSL.position(Like.requiresStringCast(string), Like.requiresStringCast(suffix)).eq(iadd(isub(Like.requiresStringCast(string).length(), Like.requiresStringCast(suffix).length()), inline(1))));
break;
case DUCKDB:
ctx.visit(function(N_SUFFIX, BOOLEAN, string, suffix));
break;
@ -123,7 +199,7 @@ implements
break;
default:
ctx.visit(string.like(DSL.concat(inline("%"), Tools.escapeForLike(suffix, ctx.configuration())), Tools.ESCAPE));
ctx.visit(function(N_ENDS_WITH, BOOLEAN, string, suffix));
break;
}
}

View File

@ -100,13 +100,14 @@ implements
case CLICKHOUSE:
case DUCKDB:
ctx.visit(string.lower().endsWith(suffix.lower()));
break;
default:
ctx.visit(string.likeIgnoreCase(DSL.concat(inline("%"), Tools.escapeForLike(suffix, ctx.configuration())), Tools.ESCAPE));
ctx.visit(string.lower().endsWith(suffix.lower()));
break;
}
}

View File

@ -178,20 +178,14 @@ implements
case SIMILAR_TO:
case NOT_LIKE:
case NOT_SIMILAR_TO:
if (!arg1.getDataType().isString() && REQUIRES_CAST_ON_LIKE.contains(ctx.dialect()))
arg1 = castIfNeeded(arg1, String.class);
if (!arg2.getDataType().isString() && REQUIRES_CAST_ON_LIKE.contains(ctx.dialect()))
arg2 = castIfNeeded(arg2, String.class);
arg1 = requiresStringCastOnLike(ctx, arg1);
arg2 = requiresStringCastOnLike(ctx, arg2);
break;
case LIKE_IGNORE_CASE:
case NOT_LIKE_IGNORE_CASE:
if (!arg1.getDataType().isString())
arg1 = castIfNeeded(arg1, String.class);
if (!arg2.getDataType().isString())
arg2 = castIfNeeded(arg2, String.class);
arg1 = requiresStringCast(arg1);
arg2 = requiresStringCast(arg2);
break;
}
@ -226,6 +220,20 @@ implements
}
}
static final Field<String> requiresStringCastOnLike(Context<?> ctx, Field<?> arg1) {
if (!arg1.getDataType().isString() && REQUIRES_CAST_ON_LIKE.contains(ctx.dialect()))
arg1 = castIfNeeded(arg1, String.class);
return (Field<String>) arg1;
}
static final Field<String> requiresStringCast(Field<?> arg1) {
if (!arg1.getDataType().isString())
arg1 = castIfNeeded(arg1, String.class);
return (Field<String>) arg1;
}

View File

@ -458,6 +458,7 @@ final class Names {
static final Name N_DENSE_RANK = systemName("dense_rank");
static final Name N_DIGITS = systemName("digits");
static final Name N_E = systemName("e");
static final Name N_ENDS_WITH = systemName("ends_with");
static final Name N_EXCLUDED = systemName("excluded");
static final Name N_EXECUTE = systemName("execute");
static final Name N_EXISTS = systemName("exists");

View File

@ -111,6 +111,9 @@ implements
@ -163,6 +166,10 @@ implements
@ -179,7 +186,7 @@ implements
case POSTGRES:
case SQLITE:
case YUGABYTEDB:
ctx.visit(string.like(DSL.concat(Tools.escapeForLike(prefix, ctx.configuration()), inline("%")), Tools.ESCAPE));
ctx.visit(DSL.position(Like.requiresStringCast(string), Like.requiresStringCast(prefix)).eq(inline(1)));
break;
case DUCKDB:

View File

@ -100,14 +100,14 @@ implements
case CLICKHOUSE:
case DUCKDB:
case TRINO:
ctx.visit(string.lower().startsWith(prefix.lower()));
break;
default:
ctx.visit(string.likeIgnoreCase(DSL.concat(Tools.escapeForLike(prefix, ctx.configuration()), inline("%")), Tools.ESCAPE));
ctx.visit(string.lower().startsWith(prefix.lower()));
break;
}
}