Skip to content

Commit a6504de

Browse files
committed
HHH-19695 test by @michaelfranz
1 parent e99feb8 commit a6504de

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

hibernate-core/src/test/java/org/hibernate/orm/test/sql/TemplateTest.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,61 @@ public void templateLiterals(SessionFactoryScope scope) {
8080
"CAST({@}.foo AS signed)", factory );
8181
}
8282

83+
@Test
84+
@JiraKey("HHH-19695")
85+
public void testFetchGrammarVsColumnNames(SessionFactoryScope scope) {
86+
SessionFactoryImplementor factory = scope.getSessionFactory();
87+
88+
// Test that "first" and "next" are treated as keywords when part of FETCH grammar
89+
assertWhereStringTemplate( "fetch first 10 rows only", "fetch first 10 rows only", factory );
90+
assertWhereStringTemplate( "fetch next 5 rows only", "fetch next 5 rows only", factory );
91+
assertWhereStringTemplate( "select * from table fetch first 1 row only",
92+
"select * from table fetch first 1 row only", factory );
93+
94+
// Mixed scenarios: ensure identifiers around FETCH grammar are still qualified
95+
assertWhereStringTemplate( "select first_name from users fetch first 10 rows only",
96+
"select {@}.first_name from users fetch first 10 rows only", factory );
97+
assertWhereStringTemplate( "where fetch_count > 5 and fetch next 1 row only",
98+
"where {@}.fetch_count > 5 and fetch next 1 row only", factory );
99+
assertWhereStringTemplate( "select first from users fetch first 10 rows only",
100+
"select {@}.first from users fetch first 10 rows only", factory );
101+
assertWhereStringTemplate( "select next from users fetch next 10 rows only",
102+
"select {@}.next from users fetch next 10 rows only", factory );
103+
}
104+
105+
@Test
106+
@JiraKey("HHH-19695")
107+
public void testFetchGrammarVariants(SessionFactoryScope scope) {
108+
SessionFactoryImplementor factory = scope.getSessionFactory();
109+
Dialect dialect = factory.getJdbcServices().getDialect();
110+
111+
// Variants of FETCH FIRST/NEXT
112+
assertWhereStringTemplate( "fetch first 1 row only", "fetch first 1 row only", factory );
113+
assertWhereStringTemplate( "fetch next 10 rows only", "fetch next 10 rows only", factory );
114+
115+
// Parameterized row count
116+
assertWhereStringTemplate( "fetch next ? rows only", "fetch next ? rows only", factory );
117+
118+
// Casing variants
119+
assertWhereStringTemplate( "FETCH First 10 ROWS ONLY", "FETCH First 10 ROWS ONLY", factory );
120+
121+
// Extra whitespace and newlines
122+
assertWhereStringTemplate( "fetch first 10 rows only", "fetch first 10 rows only", factory );
123+
assertWhereStringTemplate( "fetch\nfirst 3 rows only", "fetch\nfirst 3 rows only", factory );
124+
125+
// State reset after ONLY: trailing 'next' should be qualified
126+
assertWhereStringTemplate( "fetch next 1 rows only and next > 5",
127+
"fetch next 1 rows only and {@}.next > 5", factory );
128+
129+
// Qualified identifier should remain as-is
130+
assertWhereStringTemplate( "select u.first from users u fetch first 1 row only",
131+
"select u.first from users u fetch first 1 row only", factory );
132+
133+
// Quoted identifier should be qualified, while FETCH clause remains unqualified
134+
assertWhereStringTemplate( "select `first` from users fetch first 1 row only",
135+
"select {@}." + dialect.quote("`first`") + " from users fetch first 1 row only", factory );
136+
}
137+
83138
private static void assertWhereStringTemplate(String sql, SessionFactoryImplementor sf) {
84139
assertEquals( sql,
85140
Template.renderWhereStringTemplate(

0 commit comments

Comments
 (0)