HHH-15294 cockroachdb fixes
* HHH-15294 Fix setting of untyped null values in CockroachDB dialect Solution exactly same as in PostgresqlDialect * HHH-15294 Change CockroachDB multitable mutation strategies to CTE Align with the Postgresql strategy * HHH-15294 Fix missing IdentityColumnSupport in CockroachDB Dialect * HHH-15294 Skip test for CockRoachDB due to unsupported automatic type conversion * HHH-15294 CockroachDB doesn't support value propagation
This commit is contained in:
parent
6728afadb7
commit
e0615b13a8
|
@ -8,12 +8,14 @@ package org.hibernate.dialect;
|
||||||
|
|
||||||
import java.sql.DatabaseMetaData;
|
import java.sql.DatabaseMetaData;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Types;
|
||||||
import java.time.temporal.TemporalAccessor;
|
import java.time.temporal.TemporalAccessor;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import jakarta.persistence.TemporalType;
|
import jakarta.persistence.TemporalType;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
|
@ -21,6 +23,8 @@ import org.hibernate.LockOptions;
|
||||||
import org.hibernate.boot.model.TypeContributions;
|
import org.hibernate.boot.model.TypeContributions;
|
||||||
import org.hibernate.dialect.function.CommonFunctionFactory;
|
import org.hibernate.dialect.function.CommonFunctionFactory;
|
||||||
import org.hibernate.dialect.function.FormatFunction;
|
import org.hibernate.dialect.function.FormatFunction;
|
||||||
|
import org.hibernate.dialect.identity.CockroachDBIdentityColumnSupport;
|
||||||
|
import org.hibernate.dialect.identity.IdentityColumnSupport;
|
||||||
import org.hibernate.dialect.pagination.LimitHandler;
|
import org.hibernate.dialect.pagination.LimitHandler;
|
||||||
import org.hibernate.dialect.pagination.OffsetFetchLimitHandler;
|
import org.hibernate.dialect.pagination.OffsetFetchLimitHandler;
|
||||||
import org.hibernate.dialect.sequence.PostgreSQLSequenceSupport;
|
import org.hibernate.dialect.sequence.PostgreSQLSequenceSupport;
|
||||||
|
@ -31,10 +35,16 @@ import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
|
||||||
import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
|
import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
|
||||||
import org.hibernate.engine.jdbc.env.spi.NameQualifierSupport;
|
import org.hibernate.engine.jdbc.env.spi.NameQualifierSupport;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
|
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||||
import org.hibernate.query.spi.QueryEngine;
|
import org.hibernate.query.spi.QueryEngine;
|
||||||
import org.hibernate.query.sqm.IntervalType;
|
import org.hibernate.query.sqm.IntervalType;
|
||||||
import org.hibernate.query.sqm.NullOrdering;
|
import org.hibernate.query.sqm.NullOrdering;
|
||||||
import org.hibernate.query.sqm.TemporalUnit;
|
import org.hibernate.query.sqm.TemporalUnit;
|
||||||
|
import org.hibernate.query.sqm.mutation.internal.cte.CteInsertStrategy;
|
||||||
|
import org.hibernate.query.sqm.mutation.internal.cte.CteMutationStrategy;
|
||||||
|
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy;
|
||||||
|
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
||||||
import org.hibernate.service.ServiceRegistry;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
|
@ -42,9 +52,15 @@ import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||||
import org.hibernate.sql.ast.tree.Statement;
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
import org.hibernate.sql.exec.spi.JdbcOperation;
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
import org.hibernate.type.JavaObjectType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.BlobJdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.ClobJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.InstantAsTimestampWithTimeZoneJdbcType;
|
import org.hibernate.type.descriptor.jdbc.InstantAsTimestampWithTimeZoneJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.ObjectNullAsBinaryTypeJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.UUIDJdbcType;
|
import org.hibernate.type.descriptor.jdbc.UUIDJdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.VarbinaryJdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.VarcharJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
||||||
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
|
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
|
||||||
import org.hibernate.type.descriptor.sql.internal.Scale6IntervalSecondDdlType;
|
import org.hibernate.type.descriptor.sql.internal.Scale6IntervalSecondDdlType;
|
||||||
|
@ -84,8 +100,8 @@ import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithM
|
||||||
*/
|
*/
|
||||||
public class CockroachDialect extends Dialect {
|
public class CockroachDialect extends Dialect {
|
||||||
|
|
||||||
|
private static final CockroachDBIdentityColumnSupport IDENTITY_COLUMN_SUPPORT = new CockroachDBIdentityColumnSupport();
|
||||||
// KNOWN LIMITATIONS:
|
// KNOWN LIMITATIONS:
|
||||||
|
|
||||||
// * no support for java.sql.Clob
|
// * no support for java.sql.Clob
|
||||||
|
|
||||||
private final PostgreSQLDriverKind driverKind;
|
private final PostgreSQLDriverKind driverKind;
|
||||||
|
@ -223,6 +239,23 @@ public class CockroachDialect extends Dialect {
|
||||||
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLJsonJdbcType.INSTANCE );
|
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLJsonJdbcType.INSTANCE );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Force Blob binding to byte[] for CockroachDB
|
||||||
|
jdbcTypeRegistry.addDescriptor( Types.BLOB, VarbinaryJdbcType.INSTANCE );
|
||||||
|
jdbcTypeRegistry.addDescriptor( Types.CLOB, VarcharJdbcType.INSTANCE );
|
||||||
|
|
||||||
|
// The next two contributions are the same as for Postgresql
|
||||||
|
typeContributions.contributeJdbcType( ObjectNullAsBinaryTypeJdbcType.INSTANCE );
|
||||||
|
|
||||||
|
// Until we remove StandardBasicTypes, we have to keep this
|
||||||
|
typeContributions.contributeType(
|
||||||
|
new JavaObjectType(
|
||||||
|
ObjectNullAsBinaryTypeJdbcType.INSTANCE,
|
||||||
|
typeContributions.getTypeConfiguration()
|
||||||
|
.getJavaTypeRegistry()
|
||||||
|
.getDescriptor( Object.class )
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -296,6 +329,11 @@ public class CockroachDialect extends Dialect {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IdentityColumnSupport getIdentityColumnSupport() {
|
||||||
|
return IDENTITY_COLUMN_SUPPORT;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsValuesList() {
|
public boolean supportsValuesList() {
|
||||||
return true;
|
return true;
|
||||||
|
@ -362,6 +400,11 @@ public class CockroachDialect extends Dialect {
|
||||||
return "select sequence_name,sequence_schema,sequence_catalog,start_value,minimum_value,maximum_value,increment from information_schema.sequences";
|
return "select sequence_name,sequence_schema,sequence_catalog,start_value,minimum_value,maximum_value,increment from information_schema.sequences";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsLobValueChangePropagation() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
return new StandardSqlAstTranslatorFactory() {
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@ -746,4 +789,18 @@ public class CockroachDialect extends Dialect {
|
||||||
|
|
||||||
return super.buildIdentifierHelper( builder, dbMetaData );
|
return super.buildIdentifierHelper( builder, dbMetaData );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqmMultiTableMutationStrategy getFallbackSqmMutationStrategy(
|
||||||
|
EntityMappingType rootEntityDescriptor,
|
||||||
|
RuntimeModelCreationContext runtimeModelCreationContext) {
|
||||||
|
return new CteMutationStrategy( rootEntityDescriptor, runtimeModelCreationContext );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqmMultiTableInsertStrategy getFallbackSqmInsertStrategy(
|
||||||
|
EntityMappingType rootEntityDescriptor,
|
||||||
|
RuntimeModelCreationContext runtimeModelCreationContext) {
|
||||||
|
return new CteInsertStrategy( rootEntityDescriptor, runtimeModelCreationContext );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ package org.hibernate.dialect.identity;
|
||||||
|
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
|
||||||
public class CockroachDB1920IdentityColumnSupport extends IdentityColumnSupportImpl {
|
public class CockroachDBIdentityColumnSupport extends IdentityColumnSupportImpl {
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsIdentityColumns() {
|
public boolean supportsIdentityColumns() {
|
||||||
// Full support requires setting the sql.defaults.serial_normalization=sql_sequence in CockroachDB.
|
// Full support requires setting the sql.defaults.serial_normalization=sql_sequence in CockroachDB.
|
|
@ -11,10 +11,14 @@ import java.util.Arrays;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
|
|
||||||
import org.hibernate.testing.DialectChecks;
|
import org.hibernate.testing.DialectChecks;
|
||||||
import org.hibernate.testing.RequiresDialectFeature;
|
import org.hibernate.testing.RequiresDialectFeature;
|
||||||
|
import org.hibernate.testing.SkipForDialect;
|
||||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
|
|
||||||
|
|
||||||
|
import org.hibernate.dialect.CockroachDialect;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
|
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
|
||||||
import org.hibernate.type.descriptor.jdbc.BlobJdbcType;
|
import org.hibernate.type.descriptor.jdbc.BlobJdbcType;
|
||||||
|
@ -32,6 +36,7 @@ public class MaterializedBlobTest extends BaseCoreFunctionalTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@SkipForDialect(value = CockroachDialect.class, comment = "Blob in CockroachDB is same as a varbinary, to assertions will fail")
|
||||||
public void testTypeSelection() {
|
public void testTypeSelection() {
|
||||||
int index = sessionFactory().getRuntimeMetamodels().getMappingMetamodel().getEntityDescriptor(MaterializedBlobEntity.class.getName()).getEntityMetamodel().getPropertyIndex( "theBytes" );
|
int index = sessionFactory().getRuntimeMetamodels().getMappingMetamodel().getEntityDescriptor(MaterializedBlobEntity.class.getName()).getEntityMetamodel().getPropertyIndex( "theBytes" );
|
||||||
BasicType<?> type = (BasicType<?>) sessionFactory().getRuntimeMetamodels().getMappingMetamodel().getEntityDescriptor(MaterializedBlobEntity.class.getName()).getEntityMetamodel().getProperties()[index].getType();
|
BasicType<?> type = (BasicType<?>) sessionFactory().getRuntimeMetamodels().getMappingMetamodel().getEntityDescriptor(MaterializedBlobEntity.class.getName()).getEntityMetamodel().getProperties()[index].getType();
|
||||||
|
|
|
@ -19,6 +19,7 @@ import org.hibernate.Session;
|
||||||
import org.hibernate.Transaction;
|
import org.hibernate.Transaction;
|
||||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.dialect.CockroachDialect;
|
||||||
import org.hibernate.dialect.H2Dialect;
|
import org.hibernate.dialect.H2Dialect;
|
||||||
import org.hibernate.dialect.MySQLDialect;
|
import org.hibernate.dialect.MySQLDialect;
|
||||||
import org.hibernate.exception.ConstraintViolationException;
|
import org.hibernate.exception.ConstraintViolationException;
|
||||||
|
@ -30,6 +31,7 @@ import org.hibernate.query.Query;
|
||||||
|
|
||||||
import org.hibernate.testing.DialectChecks;
|
import org.hibernate.testing.DialectChecks;
|
||||||
import org.hibernate.testing.RequiresDialectFeature;
|
import org.hibernate.testing.RequiresDialectFeature;
|
||||||
|
import org.hibernate.testing.SkipForDialect;
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -81,6 +83,7 @@ public class BulkManipulationTest extends BaseCoreFunctionalTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@SkipForDialect(value = CockroachDialect.class, comment = "https://github.com/cockroachdb/cockroach/issues/41943")
|
||||||
public void testUpdateWithSubquery() {
|
public void testUpdateWithSubquery() {
|
||||||
Session s = openSession();
|
Session s = openSession();
|
||||||
s.beginTransaction();
|
s.beginTransaction();
|
||||||
|
@ -518,7 +521,8 @@ public class BulkManipulationTest extends BaseCoreFunctionalTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@RequiresDialectFeature( value = DialectChecks.SupportsTemporaryTableIdentity.class, comment = "The use of the native generator leads to using identity which also needs to be supported on temporary tables")
|
@SkipForDialect(value = CockroachDialect.class, comment = "https://github.com/cockroachdb/cockroach/issues/75101")
|
||||||
|
@RequiresDialectFeature(value = DialectChecks.SupportsTemporaryTableIdentity.class, comment = "The use of the native generator leads to using identity which also needs to be supported on temporary tables")
|
||||||
public void testInsertIntoSuperclassPropertiesFails() {
|
public void testInsertIntoSuperclassPropertiesFails() {
|
||||||
TestData data = new TestData();
|
TestData data = new TestData();
|
||||||
data.prepare();
|
data.prepare();
|
||||||
|
|
Loading…
Reference in New Issue