Skip to content

Commit a03d221

Browse files
rguihardbeikov
authored andcommitted
HHH-18916 - extends addQueryHints behavior
QUERY_PATTERN regex handles queries with natural, left/right, inner/outer join Add unit test to check existing behavior
1 parent a893f15 commit a03d221

File tree

2 files changed

+60
-3
lines changed

2 files changed

+60
-3
lines changed

hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,8 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
278278

279279
private static final Pattern ESCAPE_CLOSING_COMMENT_PATTERN = Pattern.compile( "\\*/" );
280280
private static final Pattern ESCAPE_OPENING_COMMENT_PATTERN = Pattern.compile( "/\\*" );
281-
private static final Pattern QUERY_PATTERN = Pattern.compile( "^\\s*(select\\b.+?\\bfrom\\b.+?)(\\b(where|join)\\b.+?)$" );
281+
private static final Pattern QUERY_PATTERN = Pattern.compile(
282+
"^\\s*(select\\b.+?\\bfrom\\b.+?)(\\b(?:natural )?(?:left |right )?(?:inner |outer )?join.+?\\b)?(\\bwhere\\b.+?)$");
282283

283284
private static final CoreMessageLogger LOG = Logger.getMessageLogger( MethodHandles.lookup(), CoreMessageLogger.class, Dialect.class.getName() );
284285

@@ -4767,13 +4768,16 @@ public String addSqlHintOrComment(
47674768
public static String addQueryHints(String query, String hints) {
47684769
Matcher matcher = QUERY_PATTERN.matcher( query );
47694770
if ( matcher.matches() && matcher.groupCount() > 1 ) {
4770-
String startToken = matcher.group( 1 );
4771-
String endToken = matcher.group( 2 );
4771+
final String startToken = matcher.group(1);
4772+
// Null if there is no join in the query
4773+
final String joinToken = Objects.toString(matcher.group(2), "");
4774+
final String endToken = matcher.group(3);
47724775

47734776
return startToken +
47744777
" use index (" +
47754778
hints +
47764779
") " +
4780+
joinToken +
47774781
endToken;
47784782
}
47794783
else {
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* SPDX-License-Identifier: LGPL-2.1-or-later
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.dialect;
6+
7+
import static org.junit.jupiter.api.Assertions.assertEquals;
8+
9+
import java.util.stream.Stream;
10+
11+
import org.junit.jupiter.params.ParameterizedTest;
12+
import org.junit.jupiter.params.provider.Arguments;
13+
import org.junit.jupiter.params.provider.MethodSource;
14+
15+
/**
16+
* Check if IndexQueryHintHandler handles correctly simple query and query with JOIN
17+
*
18+
* @author Rguihard
19+
*/
20+
class DialectTest {
21+
22+
static Stream<Arguments> _addQueryHints() {
23+
final Stream.Builder<Arguments> builder = Stream.builder();
24+
25+
final String hints = "MY_INDEX";
26+
final String simpleQuery = "select COUNT(*) from TEST t1_0 where column1 = 'value'";
27+
builder.add(
28+
Arguments.of("Simple query : hint",
29+
"select COUNT(*) from TEST t1_0 use index (MY_INDEX) where column1 = 'value'", simpleQuery, hints));
30+
final String joinQueryUsing = "select COUNT(*) from TEST t1_0 join TEST2 t2_0 using(column2) where field = 'value'";
31+
builder.add(Arguments.of("Join query with using : hint",
32+
"select COUNT(*) from TEST t1_0 use index (MY_INDEX) join TEST2 t2_0 using(column2) where field = 'value'",
33+
joinQueryUsing, hints));
34+
final String joinQueryOn = "select COUNT(*) from TEST t1_0 join TEST2 t2_0 on t1_0.column2 = t2_0.column2 where field = 'value'";
35+
builder.add(Arguments.of("Join query with on : hint",
36+
"select COUNT(*) from TEST t1_0 use index (MY_INDEX) join TEST2 t2_0 on t1_0.column2 = t2_0.column2 where field = 'value'",
37+
joinQueryOn, hints));
38+
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'";
39+
builder.add(Arguments.of("Left join query with on : hint",
40+
"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'",
41+
leftJoinQuery, hints));
42+
43+
return builder.build();
44+
}
45+
46+
@MethodSource("_addQueryHints")
47+
@ParameterizedTest
48+
void addQueryHints(String description, String expected, String query, String hints) {
49+
final String queryWithHint = MySQLDialect.addQueryHints(query, hints);
50+
assertEquals(expected, queryWithHint, description);
51+
}
52+
53+
}

0 commit comments

Comments
 (0)