HHH-18916 - extends addQueryHints behavior
QUERY_PATTERN regex handles queries with natural, left/right, inner/outer join Add unit test to check existing behavior
This commit is contained in:
parent
a893f15884
commit
a03d22190d
|
@ -278,7 +278,8 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
||||||
|
|
||||||
private static final Pattern ESCAPE_CLOSING_COMMENT_PATTERN = Pattern.compile( "\\*/" );
|
private static final Pattern ESCAPE_CLOSING_COMMENT_PATTERN = Pattern.compile( "\\*/" );
|
||||||
private static final Pattern ESCAPE_OPENING_COMMENT_PATTERN = Pattern.compile( "/\\*" );
|
private static final Pattern ESCAPE_OPENING_COMMENT_PATTERN = Pattern.compile( "/\\*" );
|
||||||
private static final Pattern QUERY_PATTERN = Pattern.compile( "^\\s*(select\\b.+?\\bfrom\\b.+?)(\\b(where|join)\\b.+?)$" );
|
private static final Pattern QUERY_PATTERN = Pattern.compile(
|
||||||
|
"^\\s*(select\\b.+?\\bfrom\\b.+?)(\\b(?:natural )?(?:left |right )?(?:inner |outer )?join.+?\\b)?(\\bwhere\\b.+?)$");
|
||||||
|
|
||||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger( MethodHandles.lookup(), CoreMessageLogger.class, Dialect.class.getName() );
|
private static final CoreMessageLogger LOG = Logger.getMessageLogger( MethodHandles.lookup(), CoreMessageLogger.class, Dialect.class.getName() );
|
||||||
|
|
||||||
|
@ -4767,13 +4768,16 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
||||||
public static String addQueryHints(String query, String hints) {
|
public static String addQueryHints(String query, String hints) {
|
||||||
Matcher matcher = QUERY_PATTERN.matcher( query );
|
Matcher matcher = QUERY_PATTERN.matcher( query );
|
||||||
if ( matcher.matches() && matcher.groupCount() > 1 ) {
|
if ( matcher.matches() && matcher.groupCount() > 1 ) {
|
||||||
String startToken = matcher.group( 1 );
|
final String startToken = matcher.group(1);
|
||||||
String endToken = matcher.group( 2 );
|
// Null if there is no join in the query
|
||||||
|
final String joinToken = Objects.toString(matcher.group(2), "");
|
||||||
|
final String endToken = matcher.group(3);
|
||||||
|
|
||||||
return startToken +
|
return startToken +
|
||||||
" use index (" +
|
" use index (" +
|
||||||
hints +
|
hints +
|
||||||
") " +
|
") " +
|
||||||
|
joinToken +
|
||||||
endToken;
|
endToken;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
* Copyright Red Hat Inc. and Hibernate Authors
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if IndexQueryHintHandler handles correctly simple query and query with JOIN
|
||||||
|
*
|
||||||
|
* @author Rguihard
|
||||||
|
*/
|
||||||
|
class DialectTest {
|
||||||
|
|
||||||
|
static Stream<Arguments> _addQueryHints() {
|
||||||
|
final Stream.Builder<Arguments> builder = Stream.builder();
|
||||||
|
|
||||||
|
final String hints = "MY_INDEX";
|
||||||
|
final String simpleQuery = "select COUNT(*) from TEST t1_0 where column1 = 'value'";
|
||||||
|
builder.add(
|
||||||
|
Arguments.of("Simple query : hint",
|
||||||
|
"select COUNT(*) from TEST t1_0 use index (MY_INDEX) where column1 = 'value'", simpleQuery, hints));
|
||||||
|
final String joinQueryUsing = "select COUNT(*) from TEST t1_0 join TEST2 t2_0 using(column2) where field = 'value'";
|
||||||
|
builder.add(Arguments.of("Join query with using : hint",
|
||||||
|
"select COUNT(*) from TEST t1_0 use index (MY_INDEX) join TEST2 t2_0 using(column2) where field = 'value'",
|
||||||
|
joinQueryUsing, hints));
|
||||||
|
final String joinQueryOn = "select COUNT(*) from TEST t1_0 join TEST2 t2_0 on t1_0.column2 = t2_0.column2 where field = 'value'";
|
||||||
|
builder.add(Arguments.of("Join query with on : hint",
|
||||||
|
"select COUNT(*) from TEST t1_0 use index (MY_INDEX) join TEST2 t2_0 on t1_0.column2 = t2_0.column2 where field = 'value'",
|
||||||
|
joinQueryOn, hints));
|
||||||
|
final String leftJoinQuery = "select COUNT(*) from TEST t1_0 left join TEST2 t2_0 on t1_0.column2 = t2_0.column2 and t1_0.column3 = t2_0.column3 where field = 'value'";
|
||||||
|
builder.add(Arguments.of("Left join query with on : hint",
|
||||||
|
"select COUNT(*) from TEST t1_0 use index (MY_INDEX) left join TEST2 t2_0 on t1_0.column2 = t2_0.column2 and t1_0.column3 = t2_0.column3 where field = 'value'",
|
||||||
|
leftJoinQuery, hints));
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@MethodSource("_addQueryHints")
|
||||||
|
@ParameterizedTest
|
||||||
|
void addQueryHints(String description, String expected, String query, String hints) {
|
||||||
|
final String queryWithHint = MySQLDialect.addQueryHints(query, hints);
|
||||||
|
assertEquals(expected, queryWithHint, description);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue