Skip to content

Commit 5801c25

Browse files
committed
HHH-19632 Give access to optional parameter info in SqlAstTranslator
1 parent 0930fb3 commit 5801c25

File tree

10 files changed

+137
-7
lines changed

10 files changed

+137
-7
lines changed

hibernate-core/src/main/java/org/hibernate/query/sqm/internal/ConcreteSqmSelectQueryPlan.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ private static CacheableSqmInterpretation buildCacheableSqmInterpretation(
493493

494494
final SqlAstTranslator<JdbcOperationQuerySelect> selectTranslator =
495495
sessionFactory.getJdbcServices().getJdbcEnvironment().getSqlAstTranslatorFactory()
496-
.buildSelectTranslator( sessionFactory, sqmInterpretation.getSqlAst() );
496+
.buildSelectTranslator( sessionFactory, sqmInterpretation.getSqlAst(), sqmInterpretation.getParameterInfo() );
497497

498498
final var jdbcParamsXref =
499499
generateJdbcParamsXref( domainParameterXref, sqmInterpretation::getJdbcParamsBySqmParam );

hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/MatchingIdSelectionHelper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ public static List<Object> selectMatchingIds(
274274
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
275275
final SqlAstTranslator<JdbcOperationQuerySelect> sqlAstSelectTranslator = jdbcEnvironment
276276
.getSqlAstTranslatorFactory()
277-
.buildSelectTranslator( factory, translation.getSqlAst() );
277+
.buildSelectTranslator( factory, translation.getSqlAst(), translation.getParameterInfo() );
278278

279279
final JdbcParameterBindings jdbcParameterBindings = SqmUtil.createJdbcParameterBindings(
280280
executionContext.getQueryParameterBindings(),

hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqmTranslation.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import org.hibernate.metamodel.mapping.MappingModelExpressible;
1111
import org.hibernate.query.sqm.tree.expression.SqmParameter;
12+
import org.hibernate.sql.ast.SqlParameterInfo;
1213
import org.hibernate.sql.ast.spi.FromClauseAccess;
1314
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
1415
import org.hibernate.sql.ast.tree.Statement;
@@ -25,4 +26,11 @@ public interface SqmTranslation<T extends Statement> {
2526
FromClauseAccess getFromClauseAccess();
2627
Map<SqmParameter<?>, List<List<JdbcParameter>>> getJdbcParamsBySqmParam();
2728
Map<SqmParameter<?>, MappingModelExpressible<?>> getSqmParameterMappingModelTypeResolutions();
29+
30+
/**
31+
* The parameter information for the SQL AST.
32+
*
33+
* @since 7.1
34+
*/
35+
SqlParameterInfo getParameterInfo();
2836
}

hibernate-core/src/main/java/org/hibernate/query/sqm/sql/StandardSqmTranslation.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@
44
*/
55
package org.hibernate.query.sqm.sql;
66

7+
import java.util.Collections;
8+
import java.util.IdentityHashMap;
79
import java.util.List;
810
import java.util.Map;
911

1012
import org.hibernate.metamodel.mapping.MappingModelExpressible;
1113
import org.hibernate.query.sqm.tree.expression.SqmParameter;
14+
import org.hibernate.sql.ast.SqlParameterInfo;
15+
import org.hibernate.sql.ast.internal.SqlParameterInfoImpl;
1216
import org.hibernate.sql.ast.spi.FromClauseAccess;
1317
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
1418
import org.hibernate.sql.ast.tree.Statement;
@@ -24,6 +28,7 @@ public class StandardSqmTranslation<T extends Statement> implements SqmTranslati
2428
private final Map<SqmParameter<?>, MappingModelExpressible<?>> parameterMappingModelTypeMap;
2529
private final SqlExpressionResolver sqlExpressionResolver;
2630
private final FromClauseAccess fromClauseAccess;
31+
private final SqlParameterInfo parameterInfo;
2732

2833
public StandardSqmTranslation(
2934
T sqlAst,
@@ -36,6 +41,19 @@ public StandardSqmTranslation(
3641
this.parameterMappingModelTypeMap = parameterMappingModelTypeMap;
3742
this.sqlExpressionResolver = sqlExpressionResolver;
3843
this.fromClauseAccess = fromClauseAccess;
44+
final IdentityHashMap<JdbcParameter, Integer> parameterIdMap = new IdentityHashMap<>();
45+
int parameterId = 0;
46+
for ( Map.Entry<SqmParameter<?>, List<List<JdbcParameter>>> entry : jdbcParamMap.entrySet() ) {
47+
final List<List<JdbcParameter>> parameterUses = entry.getValue();
48+
final int baseId = parameterId;
49+
for ( List<JdbcParameter> jdbcParameters : parameterUses ) {
50+
for ( int i = 0; i < jdbcParameters.size(); i++ ) {
51+
parameterIdMap.put( jdbcParameters.get( i ), baseId + i );
52+
}
53+
}
54+
parameterId += parameterUses.get( 0 ).size();
55+
}
56+
this.parameterInfo = new SqlParameterInfoImpl( Collections.unmodifiableMap( parameterIdMap ) );
3957
}
4058

4159
@Override
@@ -62,4 +80,9 @@ public SqlExpressionResolver getSqlExpressionResolver() {
6280
public FromClauseAccess getFromClauseAccess() {
6381
return fromClauseAccess;
6482
}
83+
84+
@Override
85+
public SqlParameterInfo getParameterInfo() {
86+
return parameterInfo;
87+
}
6588
}

hibernate-core/src/main/java/org/hibernate/sql/ast/SqlAstTranslatorFactory.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ public interface SqlAstTranslatorFactory {
2323
*/
2424
SqlAstTranslator<JdbcOperationQuerySelect> buildSelectTranslator(SessionFactoryImplementor sessionFactory, SelectStatement statement);
2525

26+
/**
27+
* Builds a single-use select translator
28+
*
29+
* @since 7.1
30+
*/
31+
SqlAstTranslator<JdbcOperationQuerySelect> buildSelectTranslator(SessionFactoryImplementor sessionFactory, SelectStatement statement, SqlParameterInfo parameterInfo);
32+
2633
/**
2734
* Builds a single-use mutation translator
2835
*/
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.sql.ast;
6+
7+
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
8+
9+
/**
10+
* Parameter information for {@link JdbcParameter} within a SQL query.
11+
*
12+
* @since 7.1
13+
*/
14+
public interface SqlParameterInfo {
15+
/**
16+
* Returns the parameter id or bind position for the given {@link JdbcParameter}.
17+
*/
18+
int getParameterId(JdbcParameter jdbcParameter);
19+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.sql.ast.internal;
6+
7+
import org.hibernate.sql.ast.SqlParameterInfo;
8+
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
9+
10+
import java.util.IdentityHashMap;
11+
import java.util.Map;
12+
13+
/**
14+
* @since 7.0
15+
*/
16+
public class SqlParameterInfoImpl implements SqlParameterInfo {
17+
18+
private final Map<JdbcParameter, Integer> parameterIdMap;
19+
20+
public SqlParameterInfoImpl() {
21+
this(new IdentityHashMap<>());
22+
}
23+
24+
public SqlParameterInfoImpl(Map<JdbcParameter, Integer> parameterIdMap) {
25+
this.parameterIdMap = parameterIdMap;
26+
}
27+
28+
@Override
29+
public int getParameterId(JdbcParameter jdbcParameter) {
30+
final Integer id = parameterIdMap.get( jdbcParameter );
31+
if ( id == null ) {
32+
final int newId = parameterIdMap.size();
33+
parameterIdMap.put( jdbcParameter, newId );
34+
return newId;
35+
}
36+
return id;
37+
}
38+
}

hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55
package org.hibernate.sql.ast.spi;
66

7+
import org.checkerframework.checker.nullness.qual.Nullable;
78
import jakarta.persistence.criteria.Nulls;
89
import org.hibernate.AssertionFailure;
910
import org.hibernate.Internal;
@@ -69,9 +70,11 @@
6970
import org.hibernate.sql.ast.SqlAstJoinType;
7071
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
7172
import org.hibernate.sql.ast.SqlAstTranslator;
73+
import org.hibernate.sql.ast.SqlParameterInfo;
7274
import org.hibernate.sql.ast.SqlTreeCreationException;
73-
import org.hibernate.sql.ast.internal.ParameterMarkerStrategyStandard;
75+
import org.hibernate.sql.ast.internal.SqlParameterInfoImpl;
7476
import org.hibernate.sql.ast.internal.TableGroupHelper;
77+
import org.hibernate.sql.ast.internal.ParameterMarkerStrategyStandard;
7578
import org.hibernate.sql.ast.tree.AbstractUpdateOrDeleteStatement;
7679
import org.hibernate.sql.ast.tree.MutationStatement;
7780
import org.hibernate.sql.ast.tree.SqlAstNode;
@@ -269,6 +272,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
269272
private final Stack<Clause> clauseStack = new StandardStack<>();
270273
private final Stack<QueryPart> queryPartStack = new StandardStack<>();
271274
private final Stack<Statement> statementStack = new StandardStack<>();
275+
private @Nullable SqlParameterInfo parameterInfo;
272276

273277
/**
274278
* Used to identify the QuerySpec to which locking (for update, e.g.) should
@@ -308,11 +312,16 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
308312
private JdbcParameter limitParameter;
309313

310314
protected AbstractSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
315+
this( sessionFactory, statement, null );
316+
}
317+
318+
protected AbstractSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable SqlParameterInfo parameterInfo) {
311319
this.sessionFactory = sessionFactory;
312320
final JdbcServices jdbcServices = sessionFactory.getJdbcServices();
313321
this.dialect = jdbcServices.getDialect();
314322
this.statementStack.push( statement );
315323
this.parameterMarkerStrategy = jdbcServices.getParameterMarkerStrategy();
324+
this.parameterInfo = parameterInfo;
316325

317326
if ( statement instanceof SelectStatement selectStatement ) {
318327
// ideally we'd only do this if there are LockOptions,
@@ -346,6 +355,13 @@ public SessionFactoryImplementor getSessionFactory() {
346355
return sessionFactory;
347356
}
348357

358+
protected SqlParameterInfo getParameterInfo() {
359+
if ( parameterInfo == null ) {
360+
parameterInfo = new SqlParameterInfoImpl();
361+
}
362+
return parameterInfo;
363+
}
364+
349365
protected FunctionRenderer castFunction() {
350366
if ( castFunction == null ) {
351367
castFunction = findSelfRenderingFunction( "cast", 2 );

hibernate-core/src/main/java/org/hibernate/sql/ast/spi/StandardSqlAstTranslator.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
*/
55
package org.hibernate.sql.ast.spi;
66

7+
import org.checkerframework.checker.nullness.qual.Nullable;
78
import org.hibernate.engine.spi.SessionFactoryImplementor;
9+
import org.hibernate.sql.ast.SqlParameterInfo;
810
import org.hibernate.sql.ast.tree.Statement;
911
import org.hibernate.sql.exec.spi.JdbcOperation;
1012
import org.hibernate.sql.exec.spi.JdbcOperationQuerySelect;
@@ -21,4 +23,8 @@ public class StandardSqlAstTranslator<T extends JdbcOperation> extends AbstractS
2123
public StandardSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
2224
super( sessionFactory, statement );
2325
}
26+
27+
public StandardSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable SqlParameterInfo parameterInfo) {
28+
super( sessionFactory, statement, parameterInfo );
29+
}
2430
}

hibernate-core/src/main/java/org/hibernate/sql/ast/spi/StandardSqlAstTranslatorFactory.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
*/
55
package org.hibernate.sql.ast.spi;
66

7+
import org.checkerframework.checker.nullness.qual.Nullable;
78
import org.hibernate.engine.spi.SessionFactoryImplementor;
89
import org.hibernate.sql.ast.SqlAstTranslator;
910
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
11+
import org.hibernate.sql.ast.SqlParameterInfo;
1012
import org.hibernate.sql.ast.tree.MutationStatement;
1113
import org.hibernate.sql.ast.tree.Statement;
1214
import org.hibernate.sql.ast.tree.select.SelectStatement;
@@ -22,20 +24,24 @@
2224
* @author Steve Ebersole
2325
*/
2426
public class StandardSqlAstTranslatorFactory implements SqlAstTranslatorFactory {
25-
2627
@Override
2728
public SqlAstTranslator<JdbcOperationQuerySelect> buildSelectTranslator(SessionFactoryImplementor sessionFactory, SelectStatement statement) {
28-
return buildTranslator( sessionFactory, statement );
29+
return buildTranslator( sessionFactory, statement, null );
30+
}
31+
32+
@Override
33+
public SqlAstTranslator<JdbcOperationQuerySelect> buildSelectTranslator(SessionFactoryImplementor sessionFactory, SelectStatement statement, SqlParameterInfo parameterInfo) {
34+
return buildTranslator( sessionFactory, statement, parameterInfo );
2935
}
3036

3137
@Override
3238
public SqlAstTranslator<? extends JdbcOperationQueryMutation> buildMutationTranslator(SessionFactoryImplementor sessionFactory, MutationStatement statement) {
33-
return buildTranslator( sessionFactory, statement );
39+
return buildTranslator( sessionFactory, statement, null );
3440
}
3541

3642
@Override
3743
public <O extends JdbcMutationOperation> SqlAstTranslator<O> buildModelMutationTranslator(TableMutation<O> mutation, SessionFactoryImplementor sessionFactory) {
38-
return buildTranslator( sessionFactory, mutation );
44+
return buildTranslator( sessionFactory, mutation, null );
3945
}
4046

4147
/**
@@ -45,4 +51,11 @@ protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(SessionF
4551
return new StandardSqlAstTranslator<>( sessionFactory, statement );
4652
}
4753

54+
/**
55+
* Consolidated building of a translator for all Query cases
56+
*/
57+
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable SqlParameterInfo parameterInfo) {
58+
return buildTranslator( sessionFactory, statement );
59+
}
60+
4861
}

0 commit comments

Comments
 (0)