HHH-15511 - fix version determination also for the CockroachDB legacy dialect

Signed-off-by: Jan Schatteman <jschatte@redhat.com>
This commit is contained in:
Jan Schatteman 2022-09-20 17:56:28 +02:00 committed by Christian Beikov
parent 8a886039ec
commit 4f9ff5cfd1
1 changed files with 55 additions and 3 deletions

View File

@ -7,6 +7,7 @@
package org.hibernate.community.dialect;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.time.temporal.TemporalAccessor;
@ -14,6 +15,8 @@ import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import jakarta.persistence.TemporalType;
@ -30,6 +33,7 @@ import org.hibernate.dialect.PostgreSQLJsonJdbcType;
import org.hibernate.dialect.PostgreSQLJsonbJdbcType;
import org.hibernate.dialect.PostgreSQLPGObjectJdbcType;
import org.hibernate.dialect.RowLockStrategy;
import org.hibernate.dialect.SimpleDatabaseVersion;
import org.hibernate.dialect.SpannerDialect;
import org.hibernate.dialect.TimeZoneSupport;
import org.hibernate.dialect.function.CommonFunctionFactory;
@ -46,6 +50,7 @@ import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
import org.hibernate.engine.jdbc.env.spi.NameQualifierSupport;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.query.spi.QueryEngine;
@ -75,6 +80,8 @@ import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
import org.hibernate.type.descriptor.sql.internal.Scale6IntervalSecondDdlType;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import org.jboss.logging.Logger;
import static org.hibernate.query.sqm.TemporalUnit.DAY;
import static org.hibernate.query.sqm.TemporalUnit.NATIVE;
import static org.hibernate.type.SqlTypes.*;
@ -89,19 +96,23 @@ import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithM
*/
public class CockroachLegacyDialect extends Dialect {
private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, CockroachLegacyDialect.class.getName() );
private static final CockroachDBIdentityColumnSupport IDENTITY_COLUMN_SUPPORT = new CockroachDBIdentityColumnSupport();
// KNOWN LIMITATIONS:
// * no support for java.sql.Clob
// Pre-compile and reuse pattern
private static final Pattern CRDB_VERSION_PATTERN = Pattern.compile( "v[\\d]+(\\.[\\d]+)?(\\.[\\d]+)?" );
private static final DatabaseVersion DEFAULT_VERSION = DatabaseVersion.make( 19, 2 );
private final PostgreSQLDriverKind driverKind;
public CockroachLegacyDialect() {
this( DatabaseVersion.make( 19, 2 ) );
this( DEFAULT_VERSION );
}
public CockroachLegacyDialect(DialectResolutionInfo info) {
super(info);
driverKind = PostgreSQLDriverKind.determineKind( info );
this( fetchDataBaseVersion( info ), PostgreSQLDriverKind.determineKind( info ) );
registerKeywords( info );
}
public CockroachLegacyDialect(DatabaseVersion version) {
@ -113,6 +124,47 @@ public class CockroachLegacyDialect extends Dialect {
super(version);
this.driverKind = driverKind;
}
protected static DatabaseVersion fetchDataBaseVersion( DialectResolutionInfo info ) {
String versionString = null;
if ( info.getDatabaseMetadata() != null ) {
try (java.sql.Statement s = info.getDatabaseMetadata().getConnection().createStatement() ) {
final ResultSet rs = s.executeQuery( "SELECT version()" );
if ( rs.next() ) {
versionString = rs.getString( 1 );
}
}
catch (SQLException ex) {
// Ignore
}
}
return parseVersion( versionString );
}
protected static DatabaseVersion parseVersion(String versionString ) {
DatabaseVersion databaseVersion = null;
// What the DB select returns is similar to "CockroachDB CCL v21.2.10 (x86_64-unknown-linux-gnu, built 2022/05/02 17:38:58, go1.16.6)"
Matcher m = CRDB_VERSION_PATTERN.matcher( versionString == null ? "" : versionString );
if ( m.find() ) {
String[] versionParts = m.group().substring( 1 ).split( "\\." );
// if we got to this point, there is at least a major version, so no need to check [].length > 0
int majorVersion = Integer.parseInt( versionParts[0] );
int minorVersion = versionParts.length > 1 ? Integer.parseInt( versionParts[1] ) : 0;
int microVersion = versionParts.length > 2 ? Integer.parseInt( versionParts[2] ) : 0;
databaseVersion= new SimpleDatabaseVersion( majorVersion, minorVersion, microVersion);
}
if ( databaseVersion == null ) {
// Recur to the default version of the no-args constructor
LOG.unableToDetermineCockroachDatabaseVersion(
DEFAULT_VERSION.getDatabaseMajorVersion() + "." +
DEFAULT_VERSION.getDatabaseMinorVersion() + "." +
DEFAULT_VERSION.getDatabaseMicroVersion()
);
databaseVersion = DEFAULT_VERSION;
}
return databaseVersion;
}
@Override
protected String columnType(int sqlTypeCode) {