Skip to content

Commit 3326eed

Browse files
Stefan-Tribeikov
authored andcommitted
HHH-19558: Fixed support of JDBC escape syntax
1 parent be489a1 commit 3326eed

File tree

2 files changed

+65
-2
lines changed

2 files changed

+65
-2
lines changed

hibernate-core/src/main/java/org/hibernate/query/sql/internal/SQLQueryParser.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,21 @@ protected String substituteBrackets(String sqlQuery) throws QueryException {
8484
if (!doubleQuoted && !escaped) {
8585
singleQuoted = !singleQuoted;
8686
}
87-
result.append(ch);
87+
if (escaped) {
88+
token.append(ch);
89+
} else {
90+
result.append(ch);
91+
}
8892
break;
8993
case '"':
9094
if (!singleQuoted && !escaped) {
9195
doubleQuoted = !doubleQuoted;
9296
}
93-
result.append(ch);
97+
if (escaped) {
98+
token.append(ch);
99+
} else {
100+
result.append(ch);
101+
}
94102
break;
95103
case '{':
96104
if (!singleQuoted && !doubleQuoted) {
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.sql;
6+
7+
import org.hibernate.dialect.H2Dialect;
8+
import org.hibernate.engine.spi.SessionFactoryImplementor;
9+
import org.hibernate.query.sql.internal.SQLQueryParser;
10+
11+
import org.hibernate.testing.orm.junit.DomainModel;
12+
import org.hibernate.testing.orm.junit.RequiresDialect;
13+
import org.hibernate.testing.orm.junit.SessionFactory;
14+
import org.hibernate.testing.orm.junit.SessionFactoryScope;
15+
import org.junit.jupiter.api.Test;
16+
17+
import static org.assertj.core.api.Assertions.assertThat;
18+
19+
/**
20+
* Tests for {@link SQLQueryParser}
21+
*
22+
* @author Steve Ebersole
23+
*/
24+
@SuppressWarnings("JUnitMalformedDeclaration")
25+
public class SQLQueryParserUnitTests {
26+
27+
@Test
28+
@DomainModel
29+
@SessionFactory
30+
@RequiresDialect(H2Dialect.class)
31+
void testJDBCEscapeSyntaxParsing(SessionFactoryScope scope) {
32+
final SessionFactoryImplementor sessionFactory = scope.getSessionFactory();
33+
final String sqlQuery = "select id, name from {h-domain}the_table where date = {d '2025-06-18'}";
34+
35+
final String full = processSqlString( sqlQuery, "my_catalog", "my_schema", sessionFactory );
36+
assertThat( full ).contains( "{d '2025-06-18'}" );
37+
38+
final String catalogOnly = processSqlString( sqlQuery, "my_catalog", null, sessionFactory );
39+
assertThat( catalogOnly ).contains( "{d '2025-06-18'}" );
40+
41+
final String schemaOnly = processSqlString( sqlQuery, null, "my_schema", sessionFactory );
42+
assertThat( schemaOnly ).contains( "{d '2025-06-18'}" );
43+
44+
final String none = processSqlString( sqlQuery, null, null, sessionFactory );
45+
assertThat( none ).contains( "{d '2025-06-18'}" );
46+
}
47+
48+
private static String processSqlString(
49+
String sqlQuery,
50+
String catalogName,
51+
String schemaName,
52+
SessionFactoryImplementor sessionFactory) {
53+
return new SQLQueryParser( sqlQuery, null, sessionFactory ).process();
54+
}
55+
}

0 commit comments

Comments
 (0)