Skip to content

Commit 1fa65b4

Browse files
liubao68beikov
authored andcommitted
HHH-19365 GaussDB Dialect Support-rebase
1 parent e5d927d commit 1fa65b4

File tree

60 files changed

+566
-231
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+566
-231
lines changed

docker_db.sh

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ gaussdb() {
216216

217217
# config param
218218
CONTAINER_NAME=opengauss
219-
IMAGE=opengauss/opengauss:7.0.0-RC1
219+
IMAGE=opengauss/opengauss:7.0.0-RC1.B023
220220
PORT=8000
221221
DB_USER=hibernate_orm_test
222222
DB_PASSWORD=Hibernate_orm_test@1234
@@ -225,24 +225,22 @@ gaussdb() {
225225

226226
echo "start OpenGauss container..."
227227
$CONTAINER_CLI run --name ${CONTAINER_NAME} \
228-
--privileged \
228+
--privileged=true \
229+
-e GS_USERNAME=${DB_USER} \
229230
-e GS_PASSWORD=${DB_PASSWORD} \
230-
-e GS_NODENAME=opengauss \
231231
-e GS_PORT=${PORT} \
232-
-e GS_CGROUP_DISABLE=YES \
233232
-p ${PORT}:8000 \
234233
-d ${IMAGE}
235234

236235
echo "wait OpenGauss starting..."
237-
sleep 20
236+
sleep 30
238237

239238
echo " Initialize the database using the PostgreSQL client container..."
240239

241240
$CONTAINER_CLI run --rm --network=host ${PSQL_IMAGE} \
242241
bash -c "
243-
PGPASSWORD='${DB_PASSWORD}' psql -h localhost -p ${PORT} -U gaussdb -d postgres -c \"CREATE USER ${DB_USER} WITH PASSWORD '${DB_PASSWORD}';\" &&
244-
PGPASSWORD='${DB_PASSWORD}' psql -h localhost -p ${PORT} -U gaussdb -d postgres -c \"CREATE DATABASE ${DB_NAME} OWNER ${DB_USER};\" &&
245-
PGPASSWORD='${DB_PASSWORD}' psql -h localhost -p ${PORT} -U gaussdb -d ${DB_NAME} -c \"CREATE SCHEMA test AUTHORIZATION ${DB_USER};\"
242+
PGPASSWORD='${DB_PASSWORD}' psql -h localhost -p ${PORT} -U ${DB_USER} -d postgres -c \"CREATE DATABASE ${DB_NAME} OWNER ${DB_USER};\" &&
243+
PGPASSWORD='${DB_PASSWORD}' psql -h localhost -p ${PORT} -U ${DB_USER} -d ${DB_NAME} -c \"CREATE SCHEMA test AUTHORIZATION ${DB_USER};\"
246244
"
247245

248246
echo "Initialization completed"

hibernate-agroal/src/test/java/org/hibernate/test/agroal/AgroalTransactionIsolationConfigTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import org.hibernate.community.dialect.AltibaseDialect;
88
import org.hibernate.community.dialect.TiDBDialect;
9-
import org.hibernate.dialect.GaussDBDialect;
9+
import org.hibernate.community.dialect.GaussDBDialect;
1010
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
1111
import org.hibernate.agroal.internal.AgroalConnectionProvider;
1212

hibernate-c3p0/src/test/java/org/hibernate/test/c3p0/C3p0TransactionIsolationConfigTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
99
import org.hibernate.c3p0.internal.C3P0ConnectionProvider;
1010
import org.hibernate.community.dialect.AltibaseDialect;
11-
import org.hibernate.dialect.GaussDBDialect;
11+
import org.hibernate.community.dialect.GaussDBDialect;
1212
import org.hibernate.dialect.SybaseASEDialect;
1313
import org.hibernate.community.dialect.TiDBDialect;
1414
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CommunityDatabase.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,21 @@ public String getDriverClassName(String jdbcUrl) {
228228
? "org.apache.derby.jdbc.ClientDriver"
229229
: "org.apache.derby.jdbc.EmbeddedDriver";
230230
}
231+
},
232+
233+
GAUSSDB {
234+
@Override
235+
public Dialect createDialect(DialectResolutionInfo info) {
236+
return new GaussDBDialect(info);
237+
}
238+
@Override
239+
public boolean productNameMatches(String databaseName) {
240+
return "GaussDB".equals( databaseName );
241+
}
242+
@Override
243+
public String getDriverClassName(String jdbcUrl) {
244+
return "com.huawei.gaussdb.jdbc.Driver";
245+
}
231246
};
232247

233248
/**
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* SPDX-License-Identifier: Apache-2.0
33
* Copyright Red Hat Inc. and Hibernate Authors
44
*/
5-
package org.hibernate.dialect;
5+
package org.hibernate.community.dialect;
66
import java.lang.reflect.Array;
77
import java.sql.CallableStatement;
88
import java.sql.ResultSet;
@@ -59,7 +59,7 @@
5959
*
6060
* Notes: Original code of this class is based on AbstractPostgreSQLStructJdbcType.
6161
*/
62-
public abstract class AbstractGaussDBStructJdbcType implements StructuredJdbcType {
62+
public abstract class GaussDBAbstractStructuredJdbcType implements StructuredJdbcType {
6363

6464
private static final DateTimeFormatter LOCAL_DATE_TIME;
6565
static {
@@ -91,7 +91,7 @@ public abstract class AbstractGaussDBStructJdbcType implements StructuredJdbcTyp
9191
private final int[] inverseOrderMapping;
9292
private final EmbeddableMappingType embeddableMappingType;
9393

94-
protected AbstractGaussDBStructJdbcType(
94+
protected GaussDBAbstractStructuredJdbcType(
9595
EmbeddableMappingType embeddableMappingType,
9696
String typeName,
9797
int[] orderMapping) {
@@ -162,7 +162,7 @@ private X getObject(Object object, WrapperOptions options) throws SQLException {
162162
if ( object == null ) {
163163
return null;
164164
}
165-
return ( (AbstractGaussDBStructJdbcType) getJdbcType() ).fromString(
165+
return ( (GaussDBAbstractStructuredJdbcType) getJdbcType() ).fromString(
166166
object.toString(),
167167
getJavaType(),
168168
options
@@ -452,7 +452,7 @@ private int deserializeStruct(
452452
if ( string.charAt( i + 1 ) == '(' ) {
453453
// This could be a nested struct
454454
final JdbcMapping jdbcMapping = getJdbcValueSelectable( column ).getJdbcMapping();
455-
if ( jdbcMapping.getJdbcType() instanceof AbstractGaussDBStructJdbcType structJdbcType ) {
455+
if ( jdbcMapping.getJdbcType() instanceof GaussDBAbstractStructuredJdbcType structJdbcType ) {
456456
final Object[] subValues = new Object[structJdbcType.embeddableMappingType.getJdbcValueCount()];
457457
final int subEnd = structJdbcType.deserializeStruct(
458458
string,
@@ -848,7 +848,7 @@ private int deserializeArray(
848848
i += expectedQuotes - 1;
849849
if ( string.charAt( i + 1 ) == '(' ) {
850850
// This could be a nested struct
851-
if ( elementType.getJdbcType() instanceof AbstractGaussDBStructJdbcType structJdbcType ) {
851+
if ( elementType.getJdbcType() instanceof GaussDBAbstractStructuredJdbcType structJdbcType ) {
852852
final Object[] subValues = new Object[structJdbcType.embeddableMappingType.getJdbcValueCount()];
853853
final int subEnd = structJdbcType.deserializeStruct(
854854
string,
@@ -1211,7 +1211,7 @@ private void serializeJdbcValuesTo(
12111211
embeddableMappingType.getJdbcValueSelectable( i ) :
12121212
embeddableMappingType.getJdbcValueSelectable( orderMapping[i] );
12131213
final JdbcMapping jdbcMapping = selectableMapping.getJdbcMapping();
1214-
if ( jdbcMapping.getJdbcType() instanceof AbstractGaussDBStructJdbcType structJdbcType ) {
1214+
if ( jdbcMapping.getJdbcType() instanceof GaussDBAbstractStructuredJdbcType structJdbcType ) {
12151215
appender.quoteStart();
12161216
structJdbcType.serializeJdbcValuesTo(
12171217
appender,
@@ -1344,7 +1344,7 @@ private void serializeConvertedBasicTo(
13441344
break;
13451345
case SqlTypes.STRUCT:
13461346
if ( subValue != null ) {
1347-
final AbstractGaussDBStructJdbcType structJdbcType = (AbstractGaussDBStructJdbcType) jdbcMapping.getJdbcType();
1347+
final GaussDBAbstractStructuredJdbcType structJdbcType = (GaussDBAbstractStructuredJdbcType) jdbcMapping.getJdbcType();
13481348
appender.quoteStart();
13491349
structJdbcType.serializeJdbcValuesTo( appender, options, (Object[]) subValue, '(' );
13501350
appender.append( ')' );

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/GaussDBArrayJdbcType.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* SPDX-License-Identifier: Apache-2.0
33
* Copyright Red Hat Inc. and Hibernate Authors
44
*/
5-
package org.hibernate.dialect;
5+
package org.hibernate.community.dialect;
66

77
import java.sql.CallableStatement;
88
import java.sql.PreparedStatement;

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/GaussDBArrayJdbcTypeConstructor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
* SPDX-License-Identifier: Apache-2.0
33
* Copyright Red Hat Inc. and Hibernate Authors
44
*/
5-
package org.hibernate.dialect;
5+
package org.hibernate.community.dialect;
66

77
import java.sql.Types;
88

9+
import org.hibernate.dialect.Dialect;
910
import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation;
1011
import org.hibernate.type.BasicType;
1112
import org.hibernate.type.descriptor.jdbc.JdbcType;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.community.dialect;
6+
7+
import java.util.List;
8+
9+
import org.hibernate.HibernateException;
10+
import org.hibernate.procedure.internal.AbstractStandardCallableStatementSupport;
11+
import org.hibernate.procedure.spi.FunctionReturnImplementor;
12+
import org.hibernate.procedure.spi.ProcedureCallImplementor;
13+
import org.hibernate.procedure.spi.ProcedureParameterImplementor;
14+
import org.hibernate.type.OutputableType;
15+
import org.hibernate.query.spi.ProcedureParameterMetadataImplementor;
16+
import org.hibernate.sql.exec.internal.JdbcCallImpl;
17+
import org.hibernate.sql.exec.spi.JdbcCallParameterRegistration;
18+
import org.hibernate.sql.exec.spi.JdbcOperationQueryCall;
19+
import org.hibernate.type.SqlTypes;
20+
21+
import jakarta.persistence.ParameterMode;
22+
23+
/**
24+
* GaussDB implementation of CallableStatementSupport.
25+
*
26+
* @author liubao
27+
*
28+
* Notes: Original code of this class is based on PostgreSQLTruncFunction.
29+
*/
30+
public class GaussDBCallableStatementSupport extends AbstractStandardCallableStatementSupport {
31+
/**
32+
* Singleton access
33+
*/
34+
public static final GaussDBCallableStatementSupport INSTANCE = new GaussDBCallableStatementSupport( true );
35+
public static final GaussDBCallableStatementSupport V10_INSTANCE = new GaussDBCallableStatementSupport( false );
36+
37+
private final boolean supportsProcedures;
38+
39+
private GaussDBCallableStatementSupport(boolean supportsProcedures) {
40+
this.supportsProcedures = supportsProcedures;
41+
}
42+
43+
@Override
44+
public JdbcOperationQueryCall interpretCall(ProcedureCallImplementor<?> procedureCall) {
45+
final String procedureName = procedureCall.getProcedureName();
46+
final FunctionReturnImplementor<?> functionReturn = procedureCall.getFunctionReturn();
47+
final ProcedureParameterMetadataImplementor parameterMetadata = procedureCall.getParameterMetadata();
48+
final boolean firstParamIsRefCursor = parameterMetadata.getParameterCount() != 0
49+
&& isFirstParameterModeRefCursor( parameterMetadata );
50+
51+
final List<? extends ProcedureParameterImplementor<?>> registrations = parameterMetadata.getRegistrationsAsList();
52+
final int paramStringSizeEstimate;
53+
if ( functionReturn == null && parameterMetadata.hasNamedParameters() ) {
54+
// That's just a rough estimate. I guess most params will have fewer than 8 chars on average
55+
paramStringSizeEstimate = registrations.size() * 10;
56+
}
57+
else {
58+
// For every param rendered as '?' we have a comma, hence the estimate
59+
paramStringSizeEstimate = registrations.size() * 2;
60+
}
61+
final JdbcCallImpl.Builder builder = new JdbcCallImpl.Builder();
62+
63+
final int jdbcParameterOffset;
64+
final int startIndex;
65+
final CallMode callMode;
66+
if ( functionReturn != null ) {
67+
if ( functionReturn.getJdbcTypeCode() == SqlTypes.REF_CURSOR ) {
68+
if ( firstParamIsRefCursor ) {
69+
// validate that the parameter strategy is positional (cannot mix, and REF_CURSOR is inherently positional)
70+
if ( parameterMetadata.hasNamedParameters() ) {
71+
throw new HibernateException( "Cannot mix named parameters and REF_CURSOR parameter on GaussDB" );
72+
}
73+
callMode = CallMode.CALL_RETURN;
74+
startIndex = 1;
75+
jdbcParameterOffset = 1;
76+
builder.addParameterRegistration( registrations.get( 0 ).toJdbcParameterRegistration( 1, procedureCall ) );
77+
}
78+
else {
79+
callMode = CallMode.TABLE_FUNCTION;
80+
startIndex = 0;
81+
jdbcParameterOffset = 1;
82+
// Old style
83+
// callMode = CallMode.CALL_RETURN;
84+
// startIndex = 0;
85+
// jdbcParameterOffset = 2;
86+
// builder.setFunctionReturn( functionReturn.toJdbcFunctionReturn( procedureCall.getSession() ) );
87+
}
88+
}
89+
else {
90+
callMode = CallMode.FUNCTION;
91+
startIndex = 0;
92+
jdbcParameterOffset = 1;
93+
}
94+
}
95+
else if ( supportsProcedures ) {
96+
jdbcParameterOffset = 1;
97+
startIndex = 0;
98+
callMode = CallMode.NATIVE_CALL;
99+
}
100+
else if ( firstParamIsRefCursor ) {
101+
// validate that the parameter strategy is positional (cannot mix, and REF_CURSOR is inherently positional)
102+
if ( parameterMetadata.hasNamedParameters() ) {
103+
throw new HibernateException( "Cannot mix named parameters and REF_CURSOR parameter on GaussDB" );
104+
}
105+
jdbcParameterOffset = 1;
106+
startIndex = 1;
107+
callMode = CallMode.CALL_RETURN;
108+
builder.addParameterRegistration( registrations.get( 0 ).toJdbcParameterRegistration( 1, procedureCall ) );
109+
}
110+
else {
111+
jdbcParameterOffset = 1;
112+
startIndex = 0;
113+
callMode = CallMode.CALL;
114+
}
115+
116+
final StringBuilder buffer = new StringBuilder( callMode.start.length() + callMode.end.length() + procedureName.length() + paramStringSizeEstimate )
117+
.append( callMode.start );
118+
buffer.append( procedureName );
119+
120+
if ( startIndex == registrations.size() ) {
121+
buffer.append( '(' );
122+
}
123+
else {
124+
char sep = '(';
125+
for ( int i = startIndex; i < registrations.size(); i++ ) {
126+
final ProcedureParameterImplementor<?> parameter = registrations.get( i );
127+
if ( !supportsProcedures && parameter.getMode() == ParameterMode.REF_CURSOR ) {
128+
throw new HibernateException(
129+
"GaussDB supports only one REF_CURSOR parameter, but multiple were registered" );
130+
}
131+
buffer.append( sep );
132+
final JdbcCallParameterRegistration registration = parameter.toJdbcParameterRegistration(
133+
i + jdbcParameterOffset,
134+
procedureCall
135+
);
136+
final OutputableType<?> type = registration.getParameterType();
137+
final String castType;
138+
if ( parameter.getName() != null ) {
139+
buffer.append( parameter.getName() ).append( " => " );
140+
}
141+
if ( type != null && type.getJdbcType() instanceof GaussDBAbstractStructuredJdbcType ) {
142+
// We have to cast struct type parameters so that GaussDB understands nulls
143+
castType = ( (GaussDBAbstractStructuredJdbcType) type.getJdbcType() ).getStructTypeName();
144+
buffer.append( "cast(" );
145+
}
146+
else {
147+
castType = null;
148+
}
149+
buffer.append( "?" );
150+
if ( castType != null ) {
151+
buffer.append( " as " ).append( castType ).append( ')' );
152+
}
153+
sep = ',';
154+
builder.addParameterRegistration( registration );
155+
}
156+
}
157+
158+
buffer.append( callMode.end );
159+
builder.setCallableName( buffer.toString() );
160+
return builder.buildJdbcCall();
161+
}
162+
163+
private static boolean isFirstParameterModeRefCursor(ProcedureParameterMetadataImplementor parameterMetadata) {
164+
return parameterMetadata.getRegistrationsAsList().get( 0 ).getMode() == ParameterMode.REF_CURSOR;
165+
}
166+
167+
enum CallMode {
168+
TABLE_FUNCTION("select * from ", ")"),
169+
FUNCTION("select ", ")"),
170+
NATIVE_CALL("call ", ")"),
171+
CALL_RETURN("{?=call ", ")}"),
172+
CALL("{call ", ")}");
173+
174+
private final String start;
175+
private final String end;
176+
177+
CallMode(String start, String end) {
178+
this.start = start;
179+
this.end = end;
180+
}
181+
182+
}
183+
184+
}

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/GaussDBCastingInetJdbcType.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
* SPDX-License-Identifier: Apache-2.0
33
* Copyright Red Hat Inc. and Hibernate Authors
44
*/
5-
package org.hibernate.dialect;
5+
package org.hibernate.community.dialect;
66

77
import java.net.InetAddress;
88
import java.sql.CallableStatement;
99
import java.sql.PreparedStatement;
1010
import java.sql.ResultSet;
1111
import java.sql.SQLException;
1212

13+
import org.hibernate.dialect.Dialect;
1314
import org.hibernate.sql.ast.spi.SqlAppender;
1415
import org.hibernate.type.SqlTypes;
1516
import org.hibernate.type.descriptor.ValueBinder;

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/GaussDBCastingIntervalSecondJdbcType.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
* SPDX-License-Identifier: Apache-2.0
33
* Copyright Red Hat Inc. and Hibernate Authors
44
*/
5-
package org.hibernate.dialect;
5+
package org.hibernate.community.dialect;
66

77
import java.math.BigDecimal;
88
import java.sql.CallableStatement;
99
import java.sql.PreparedStatement;
1010
import java.sql.ResultSet;
1111
import java.sql.SQLException;
1212

13+
import org.hibernate.dialect.Dialect;
1314
import org.hibernate.engine.spi.SessionFactoryImplementor;
1415
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
1516
import org.hibernate.sql.ast.SqlAstTranslator;

0 commit comments

Comments
 (0)