Skip to content

Commit 41a34a4

Browse files
SanneDavideD
authored andcommitted
Introduce a NativeParametersRendering service to directly render PostgreSQL-compatible SELECT statements
This avoids some post-processing of the SQL generated by ORM core; it takes care of the PostgreSQL specific parameters format; not applicable yet for mutation operations.
1 parent 6afdd94 commit 41a34a4

File tree

3 files changed

+102
-4
lines changed

3 files changed

+102
-4
lines changed

hibernate-reactive-core/src/main/java/org/hibernate/reactive/provider/impl/ReactiveServiceInitiators.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.hibernate.reactive.id.factory.spi.ReactiveIdentifierGeneratorFactoryInitiator;
2828
import org.hibernate.reactive.pool.impl.ReactiveConnectionPoolInitiator;
2929
import org.hibernate.reactive.pool.impl.SqlClientPoolConfigurationInitiator;
30+
import org.hibernate.reactive.provider.service.NativeParametersRendering;
3031
import org.hibernate.reactive.provider.service.NoJdbcConnectionProviderInitiator;
3132
import org.hibernate.reactive.provider.service.NoJdbcEnvironmentInitiator;
3233
import org.hibernate.reactive.provider.service.NoJdbcMultiTenantConnectionProviderInitiator;
@@ -42,7 +43,6 @@
4243
import org.hibernate.resource.beans.spi.ManagedBeanRegistryInitiator;
4344
import org.hibernate.resource.transaction.internal.TransactionCoordinatorBuilderInitiator;
4445
import org.hibernate.service.internal.SessionFactoryServiceRegistryFactoryInitiator;
45-
import org.hibernate.sql.ast.internal.JdbcParameterRendererInitiator;
4646
import org.hibernate.tool.schema.internal.script.SqlScriptExtractorInitiator;
4747

4848
import static java.util.Collections.unmodifiableList;
@@ -149,11 +149,11 @@ private static List<StandardServiceInitiator<?>> buildInitialServiceInitiatorLis
149149
// Custom for Hibernate Reactive: JdbcValuesMappingProducerProvider
150150
serviceInitiators.add( ReactiveValuesMappingProducerProviderInitiator.INSTANCE );
151151

152-
//Custom for Hibernate Reactive: SqmMultiTableMutationStrategyProvider
152+
// Custom for Hibernate Reactive: SqmMultiTableMutationStrategyProvider
153153
serviceInitiators.add( ReactiveSqmMultiTableMutationStrategyProviderInitiator.INSTANCE );
154154

155-
// [standard] JdbcParameterRenderer FIXME this will need to be replaced
156-
serviceInitiators.add( JdbcParameterRendererInitiator.INSTANCE );
155+
// Custom for Hibernate Reactive: NativeParametersRendering [Could be used by ORM too? TBD]
156+
serviceInitiators.add( NativeParametersRendering.INSTANCE );
157157

158158
// --- end of services defined by Hibernate ORM
159159

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/* Hibernate, Relational Persistence for Idiomatic Java
2+
*
3+
* SPDX-License-Identifier: Apache-2.0
4+
* Copyright: Red Hat Inc. and Hibernate Authors
5+
*/
6+
package org.hibernate.reactive.provider.service;
7+
8+
import java.util.Map;
9+
10+
import org.hibernate.boot.registry.StandardServiceInitiator;
11+
import org.hibernate.dialect.Dialect;
12+
import org.hibernate.dialect.DialectDelegateWrapper;
13+
import org.hibernate.dialect.PostgreSQLDialect;
14+
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
15+
import org.hibernate.service.spi.ServiceRegistryImplementor;
16+
import org.hibernate.sql.ast.internal.JdbcParameterRendererStandard;
17+
import org.hibernate.sql.ast.spi.JdbcParameterRenderer;
18+
19+
public class NativeParametersRendering implements StandardServiceInitiator<JdbcParameterRenderer> {
20+
/**
21+
* Singleton access
22+
*/
23+
public static final NativeParametersRendering INSTANCE = new NativeParametersRendering();
24+
25+
@Override
26+
public JdbcParameterRenderer initiateService(Map<String, Object> configurationValues, ServiceRegistryImplementor registry) {
27+
final Dialect dialect = registry.getService( JdbcEnvironment.class ).getDialect();
28+
final Dialect realDialect = DialectDelegateWrapper.extractRealDialect( dialect );
29+
if ( realDialect instanceof PostgreSQLDialect ) {
30+
return PostgreSQLParameterRenderer.INSTANCE;
31+
}
32+
//TODO: Create optimised implementations for the other most relevant dialects
33+
return JdbcParameterRendererStandard.INSTANCE;
34+
}
35+
36+
@Override
37+
public Class<JdbcParameterRenderer> getServiceInitiated() {
38+
return JdbcParameterRenderer.class;
39+
}
40+
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/* Hibernate, Relational Persistence for Idiomatic Java
2+
*
3+
* SPDX-License-Identifier: Apache-2.0
4+
* Copyright: Red Hat Inc. and Hibernate Authors
5+
*/
6+
package org.hibernate.reactive.provider.service;
7+
8+
import org.hibernate.dialect.Dialect;
9+
import org.hibernate.sql.ast.spi.JdbcParameterRenderer;
10+
import org.hibernate.sql.ast.spi.SqlAppender;
11+
import org.hibernate.type.descriptor.jdbc.JdbcType;
12+
13+
/**
14+
* Ensures the rendered SQL matches the syntax of parameters expected by
15+
* the Vert.x PgClient: parameters are rendered with "$1", "$2", etc..
16+
* rather than with "?" syntax.
17+
* We also post-process rendered SQL in PostgresParameters as the current
18+
* approach needs to be refined; as we close the gap, rendering correctly
19+
* directly improves performance as the Parameters step can then be skipped.
20+
* At the time of writing, this service is only invoked for SELECT operations;
21+
* INSERT and DELETE seem to render SQL over an alternative path; UPDATE untested.
22+
*/
23+
public final class PostgreSQLParameterRenderer implements JdbcParameterRenderer {
24+
25+
/**
26+
* Singleton access
27+
*/
28+
public static final PostgreSQLParameterRenderer INSTANCE = new PostgreSQLParameterRenderer();
29+
30+
private static final int MAX_POSITION_PREPARED = 10;
31+
private static final String[] RENDERED_PARAM = initConstants( MAX_POSITION_PREPARED );
32+
33+
private static String[] initConstants(int max) {
34+
String[] arr = new String[max];
35+
//index zero unused!
36+
for ( int i = 1; i < max; i++ ) {
37+
arr[i] = "$" + i;
38+
}
39+
return arr;
40+
}
41+
42+
private static String render(final int position) {
43+
assert position != 0;
44+
if ( position < MAX_POSITION_PREPARED ) {
45+
return RENDERED_PARAM[position];
46+
}
47+
else {
48+
return "$" + position;
49+
}
50+
}
51+
52+
@Override
53+
public void renderJdbcParameter(int position, JdbcType jdbcType, SqlAppender appender, Dialect dialect) {
54+
jdbcType.appendWriteExpression( render( position ), appender, dialect );
55+
}
56+
57+
}

0 commit comments

Comments
 (0)