From ae9aa2d9d99a08ffd389c09e877b92fcd25b32c2 Mon Sep 17 00:00:00 2001 From: wafflejuice Date: Sat, 1 Mar 2025 16:33:26 +0900 Subject: [PATCH] HHH-19215 handle queries with straight_join or just order by --- .../java/org/hibernate/dialect/Dialect.java | 12 +++------- .../org/hibernate/dialect/DialectTest.java | 23 ++++++++++++++----- .../test/jpa/query/NamedQueryCommentTest.java | 2 +- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java index 7601ab4ce695..e5b3f1b05564 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java @@ -338,7 +338,7 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun private static final Pattern ESCAPE_CLOSING_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(?:natural )?(?:left |right |full )?(?:inner |outer |cross )?join.+?\\b)?(\\bwhere\\b.+?)$", + "^\\s*(select\\s.+?\\sfrom\\s.+?)(\\s(?:(?:natural)?\\s*(?:left|right|full)?\\s*(?:inner|outer|cross)?\\s*join|straight_join)\\s.+?)?(\\swhere\\s.+?)?(\\sorder\\s+by\\s.+?)?$", Pattern.CASE_INSENSITIVE); //needed for converting precision from decimal to binary digits @@ -5242,14 +5242,8 @@ public String addSqlHintOrComment(String sql, QueryOptions queryOptions, boolean public static String addUseIndexQueryHint(String query, String hints) { final Matcher matcher = QUERY_PATTERN.matcher( query ); if ( matcher.matches() && matcher.groupCount() > 1 ) { - final String startToken = matcher.group(1); - // Null if there is no join in the query - final String joinToken = matcher.group(2); - final String endToken = matcher.group(3); - return startToken - + " use index (" + hints + ") " - + ( joinToken == null ? "" : joinToken ) - + endToken; + final String startToken = matcher.group( 1 ); + return startToken + " use index (" + hints + ")" + query.substring( startToken.length() ); } else { return query; diff --git a/hibernate-core/src/test/java/org/hibernate/dialect/DialectTest.java b/hibernate-core/src/test/java/org/hibernate/dialect/DialectTest.java index e2493286e83b..d45ec967a3c7 100644 --- a/hibernate-core/src/test/java/org/hibernate/dialect/DialectTest.java +++ b/hibernate-core/src/test/java/org/hibernate/dialect/DialectTest.java @@ -24,21 +24,32 @@ static Stream _addQueryHints() { 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)); + builder.add(Arguments.of("Simple query : hint", + "select COUNT(*) from TEST t1_0 use index (MY_INDEX) where column1 = 'value'", simpleQuery, hints)); + final String limitQuery = "select COUNT(*) from TEST t1_0 order by column1 limit 1"; + builder.add(Arguments.of("Limit query : hint", + "select COUNT(*) from TEST t1_0 use index (MY_INDEX) order by column1 limit 1", + limitQuery, 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'", + "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'", + "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'", + "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)); + final String straightJoinQueryUsing = "select COUNT(*) from TEST t1_0 straight_join TEST2 t2_0 using(column2) where field = 'value'"; + builder.add(Arguments.of("Straight join query with using : hint", + "select COUNT(*) from TEST t1_0 use index (MY_INDEX) straight_join TEST2 t2_0 using(column2) where field = 'value'", + straightJoinQueryUsing, hints)); + final String straightJoinQueryOn = "select COUNT(*) from TEST t1_0 straight_join TEST2 t2_0 on t1_0.column2 = t2_0.column2 where field = 'value'"; + builder.add(Arguments.of("Straight join query with on : hint", + "select COUNT(*) from TEST t1_0 use index (MY_INDEX) straight_join TEST2 t2_0 on t1_0.column2 = t2_0.column2 where field = 'value'", + straightJoinQueryOn, hints)); return builder.build(); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/query/NamedQueryCommentTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/query/NamedQueryCommentTest.java index 5066d43ec9fd..e5e882f45bd2 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/query/NamedQueryCommentTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/query/NamedQueryCommentTest.java @@ -219,7 +219,7 @@ public void testSelectNamedNativeQueryWithQueryHintUsingIndex(EntityManagerFacto statementInspector.assertExecutedCount(1); statementInspector.assertExecuted( - "/* COMMENT_SELECT_INDEX_game_title */ select g1_0.id,g1_0.title from game g1_0 use index (idx_game_id) where g1_0.title=?" + "/* COMMENT_SELECT_INDEX_game_title */ select g1_0.id,g1_0.title from game g1_0 use index (idx_game_id) where g1_0.title=?" ); } );