Skip to content

Commit 826e8da

Browse files
author
nathan.xu
committed
HHH-16283 - Integrate ParameterMarkerStrategy into NativeQuery
1 parent afca931 commit 826e8da

File tree

4 files changed

+39
-38
lines changed

4 files changed

+39
-38
lines changed

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@
5555
import org.hibernate.query.internal.DelegatingDomainQueryExecutionContext;
5656
import org.hibernate.query.internal.ParameterMetadataImpl;
5757
import org.hibernate.query.internal.QueryOptionsImpl;
58-
import org.hibernate.query.internal.QueryParameterBindingsImpl;
5958
import org.hibernate.query.internal.ResultSetMappingResolutionContext;
6059
import org.hibernate.query.named.NamedResultSetMappingMemento;
6160
import org.hibernate.query.results.Builders;
@@ -90,6 +89,7 @@
9089
import org.hibernate.query.sql.spi.ParameterInterpretation;
9190
import org.hibernate.query.sql.spi.ParameterOccurrence;
9291
import org.hibernate.query.sql.spi.SelectInterpretationsKey;
92+
import org.hibernate.sql.ast.spi.ParameterMarkerStrategy;
9393
import org.hibernate.sql.exec.internal.CallbackImpl;
9494
import org.hibernate.sql.exec.spi.Callback;
9595
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducer;
@@ -370,7 +370,8 @@ private ParameterInterpretation resolveParameterInterpretation(
370370
return interpretationCache.resolveNativeQueryParameters(
371371
sqlString,
372372
s -> {
373-
final ParameterRecognizerImpl parameterRecognizer = new ParameterRecognizerImpl();
373+
final ParameterMarkerStrategy parameterMarkerStrategy = sessionFactory.getJdbcServices().getDialect().getNativeParameterMarkerStrategy();
374+
final ParameterRecognizerImpl parameterRecognizer = new ParameterRecognizerImpl(parameterMarkerStrategy);
374375

375376
session.getFactory().getServiceRegistry()
376377
.requireService( NativeQueryInterpreter.class )
@@ -781,7 +782,7 @@ protected String expandParameterLists() {
781782
}
782783
}
783784
if ( isEnclosedInParens ) {
784-
for ( int i = sourcePosition + 1; i < sqlString.length(); i++ ) {
785+
for ( int i = sourcePosition + occurrence.getLength(); i < sqlString.length(); i++ ) {
785786
final char ch = sqlString.charAt( i );
786787
if ( !Character.isWhitespace( ch ) ) {
787788
isEnclosedInParens = ch == ')';

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

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import org.hibernate.query.spi.QueryParameterImplementor;
2121
import org.hibernate.query.sql.spi.ParameterOccurrence;
2222
import org.hibernate.query.sql.spi.ParameterRecognizer;
23+
import org.hibernate.sql.ast.internal.ParameterMarkerStrategyStandard;
24+
import org.hibernate.sql.ast.spi.ParameterMarkerStrategy;
2325

2426
/**
2527
* @author Steve Ebersole
@@ -36,13 +38,15 @@ private enum ParameterStyle {
3638
private Map<String, QueryParameterImplementor<?>> namedQueryParameters;
3739
private Map<Integer, QueryParameterImplementor<?>> positionalQueryParameters;
3840

39-
private int ordinalParameterImplicitPosition;
41+
private int parameterImplicitPosition;
42+
private final ParameterMarkerStrategy parameterMarkerStrategy;
4043

4144
private List<ParameterOccurrence> parameterList;
4245
private final StringBuilder sqlStringBuffer = new StringBuilder();
4346

44-
public ParameterRecognizerImpl() {
45-
ordinalParameterImplicitPosition = 1;
47+
public ParameterRecognizerImpl(ParameterMarkerStrategy parameterMarkerStrategy) {
48+
this.parameterMarkerStrategy = parameterMarkerStrategy == null ? ParameterMarkerStrategyStandard.INSTANCE : parameterMarkerStrategy;
49+
parameterImplicitPosition = 1;
4650
}
4751

4852
@Override
@@ -103,7 +107,7 @@ else if ( parameterStyle != ParameterStyle.JDBC ) {
103107
throw new ParameterRecognitionException( "Cannot mix parameter styles between JDBC-style, ordinal and named in the same query" );
104108
}
105109

106-
int implicitPosition = ordinalParameterImplicitPosition++;
110+
int implicitPosition = parameterImplicitPosition++;
107111

108112
QueryParameterImplementor<?> parameter = null;
109113

@@ -119,12 +123,7 @@ else if ( parameterStyle != ParameterStyle.JDBC ) {
119123
positionalQueryParameters.put( implicitPosition, parameter );
120124
}
121125

122-
if ( parameterList == null ) {
123-
parameterList = new ArrayList<>();
124-
}
125-
126-
parameterList.add( new ParameterOccurrence( parameter, sqlStringBuffer.length() ) );
127-
sqlStringBuffer.append( "?" );
126+
recognizeParameter( parameter, implicitPosition );
128127
}
129128

130129
@Override
@@ -150,12 +149,7 @@ else if ( parameterStyle != ParameterStyle.NAMED ) {
150149
namedQueryParameters.put( name, parameter );
151150
}
152151

153-
if ( parameterList == null ) {
154-
parameterList = new ArrayList<>();
155-
}
156-
157-
parameterList.add( new ParameterOccurrence( parameter, sqlStringBuffer.length() ) );
158-
sqlStringBuffer.append( "?" );
152+
recognizeParameter( parameter, parameterImplicitPosition++ );
159153
}
160154

161155
@Override
@@ -185,16 +179,21 @@ else if ( parameterStyle != ParameterStyle.NAMED ) {
185179
positionalQueryParameters.put( position, parameter );
186180
}
187181

188-
if ( parameterList == null ) {
189-
parameterList = new ArrayList<>();
190-
}
191-
192-
parameterList.add( new ParameterOccurrence( parameter, sqlStringBuffer.length() ) );
193-
sqlStringBuffer.append( "?" );
182+
recognizeParameter(parameter, position);
194183
}
195184

196185
@Override
197186
public void other(char character) {
198187
sqlStringBuffer.append( character );
199188
}
189+
190+
private void recognizeParameter(QueryParameterImplementor parameter, int position) {
191+
final String marker = parameterMarkerStrategy.createMarker( position, null );
192+
final int markerLength = marker.length();
193+
if ( parameterList == null ) {
194+
parameterList = new ArrayList<>();
195+
}
196+
sqlStringBuffer.append( marker );
197+
parameterList.add( new ParameterOccurrence( parameter, sqlStringBuffer.length() - markerLength, markerLength ) );
198+
}
200199
}

hibernate-core/src/main/java/org/hibernate/query/sql/spi/ParameterOccurrence.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ public final class ParameterOccurrence {
1515

1616
private final QueryParameterImplementor<?> parameter;
1717
private final int sourcePosition;
18+
private final int length;
1819

19-
public ParameterOccurrence(QueryParameterImplementor<?> parameter, int sourcePosition) {
20+
public ParameterOccurrence(QueryParameterImplementor<?> parameter, int sourcePosition, int length) {
2021
this.parameter = parameter;
2122
this.sourcePosition = sourcePosition;
23+
this.length = length;
2224
}
2325

2426
public QueryParameterImplementor<?> getParameter() {
@@ -28,4 +30,8 @@ public QueryParameterImplementor<?> getParameter() {
2830
public int getSourcePosition() {
2931
return sourcePosition;
3032
}
33+
34+
public int getLength() {
35+
return length;
36+
}
3137
}

hibernate-core/src/test/java/org/hibernate/orm/test/sql/ast/ParameterMarkerStrategyTests.java

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,31 @@
88

99
import java.util.List;
1010

11+
import jakarta.persistence.Basic;
12+
import jakarta.persistence.Entity;
13+
import jakarta.persistence.Id;
14+
import jakarta.persistence.Table;
15+
import jakarta.persistence.Version;
1116
import org.hibernate.LockMode;
1217
import org.hibernate.annotations.Filter;
1318
import org.hibernate.annotations.FilterDef;
1419
import org.hibernate.annotations.ParamDef;
1520
import org.hibernate.dialect.H2Dialect;
16-
import org.hibernate.internal.util.StringHelper;
1721
import org.hibernate.sql.ast.spi.ParameterMarkerStrategy;
18-
import org.hibernate.type.descriptor.jdbc.JdbcType;
19-
2022
import org.hibernate.testing.jdbc.SQLStatementInspector;
2123
import org.hibernate.testing.orm.domain.gambit.EntityOfBasics;
2224
import org.hibernate.testing.orm.junit.DomainModel;
23-
import org.hibernate.testing.orm.junit.FailureExpected;
2425
import org.hibernate.testing.orm.junit.Jira;
2526
import org.hibernate.testing.orm.junit.RequiresDialect;
2627
import org.hibernate.testing.orm.junit.ServiceRegistry;
2728
import org.hibernate.testing.orm.junit.SessionFactory;
2829
import org.hibernate.testing.orm.junit.SessionFactoryScope;
30+
import org.hibernate.type.descriptor.jdbc.JdbcType;
2931
import org.junit.jupiter.api.AfterEach;
3032
import org.junit.jupiter.api.Test;
3133

32-
import jakarta.persistence.Basic;
33-
import jakarta.persistence.Entity;
34-
import jakarta.persistence.Id;
35-
import jakarta.persistence.Table;
36-
import jakarta.persistence.Version;
37-
3834
import static org.assertj.core.api.Assertions.assertThat;
39-
import static org.hibernate.internal.util.StringHelper.*;
35+
import static org.hibernate.internal.util.StringHelper.count;
4036

4137
/**
4238
* @implNote Restricted to H2 as there is nothing intrinsically Dialect specific here,
@@ -151,7 +147,6 @@ public void testLocking(SessionFactoryScope scope) {
151147
}
152148

153149
@Test
154-
@FailureExpected
155150
@Jira( "https://hibernate.atlassian.net/browse/HHH-16283" )
156151
public void testNativeQuery(SessionFactoryScope scope) {
157152
final SQLStatementInspector statementInspector = scope.getCollectingStatementInspector();

0 commit comments

Comments
 (0)