Skip to content

Commit

Permalink
Repurpose DefaultSizeStrategy to SizeStrategy for resolving final siz…
Browse files Browse the repository at this point in the history
…e. Fix boolean encoding/decoding issues. Remove duplicate order bys. Fix set operation nesting. Fix lots of tests for SQLServer, MariaDB, Derby and Oracle
  • Loading branch information
beikov committed Feb 12, 2021
1 parent 019f934 commit 9f096e8
Show file tree
Hide file tree
Showing 97 changed files with 1,911 additions and 1,010 deletions.
4 changes: 2 additions & 2 deletions docker_db.sh
Expand Up @@ -2,12 +2,12 @@

mysql_5_7() {
docker rm -f mysql || true
docker run --name mysql -e MYSQL_USER=hibernate_orm_test -e MYSQL_PASSWORD=hibernate_orm_test -e MYSQL_DATABASE=hibernate_orm_test -p3306:3306 -d mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
docker run --name mysql -e MYSQL_USER=hibernate_orm_test -e MYSQL_PASSWORD=hibernate_orm_test -e MYSQL_DATABASE=hibernate_orm_test -e MYSQL_ROOT_PASSWORD=hibernate_orm_test -p3306:3306 -d mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
}

mysql_8_0() {
docker rm -f mysql || true
docker run --name mysql -e MYSQL_USER=hibernate_orm_test -e MYSQL_PASSWORD=hibernate_orm_test -e MYSQL_DATABASE=hibernate_orm_test -p3306:3306 -d mysql:8.0.21 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
docker run --name mysql -e MYSQL_USER=hibernate_orm_test -e MYSQL_PASSWORD=hibernate_orm_test -e MYSQL_DATABASE=hibernate_orm_test -e MYSQL_ROOT_PASSWORD=hibernate_orm_test -p3306:3306 -d mysql:8.0.21 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
}

mariadb() {
Expand Down
Expand Up @@ -75,13 +75,13 @@ values
// QUERY SPEC - general structure of root sqm or sub sqm

queryExpression
: queryGroup queryOrder?
: simpleQueryExpression # SimpleQueryGroup
| queryExpression (setOperator simpleQueryExpression)+ # SetQueryGroup
;

queryGroup
: querySpec # QuerySpecQueryGroup
| LEFT_PAREN queryGroup RIGHT_PAREN # NestedQueryGroup
| queryGroup queryOrder? (setOperator (querySpec | LEFT_PAREN queryGroup RIGHT_PAREN))+ # SetQueryGroup
simpleQueryExpression
: querySpec queryOrder? # QuerySpecExpression
| LEFT_PAREN queryExpression RIGHT_PAREN queryOrder? # NestedQueryExpression
;

setOperator
Expand Down
Expand Up @@ -225,6 +225,7 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
private final boolean procedureParameterNullPassingEnabled;
private final boolean collectionJoinSubqueryRewriteEnabled;
private final boolean omitJoinOfSuperclassTablesEnabled;
private final int preferredSqlTypeCodeForBoolean;

// Caching
private boolean secondLevelCacheEnabled;
Expand Down Expand Up @@ -415,6 +416,7 @@ public SessionFactoryOptionsBuilder(StandardServiceRegistry serviceRegistry, Boo
this.procedureParameterNullPassingEnabled = cfgService.getSetting( PROCEDURE_NULL_PARAM_PASSING, BOOLEAN, false );
this.collectionJoinSubqueryRewriteEnabled = cfgService.getSetting( COLLECTION_JOIN_SUBQUERY, BOOLEAN, true );
this.omitJoinOfSuperclassTablesEnabled = cfgService.getSetting( OMIT_JOIN_OF_SUPERCLASS_TABLES, BOOLEAN, true );
this.preferredSqlTypeCodeForBoolean = ConfigurationHelper.getPreferredSqlTypeCodeForBoolean( serviceRegistry );

final RegionFactory regionFactory = serviceRegistry.getService( RegionFactory.class );
if ( !NoCachingRegionFactory.class.isInstance( regionFactory ) ) {
Expand Down Expand Up @@ -1204,8 +1206,11 @@ public boolean isOmitJoinOfSuperclassTablesEnabled() {
return omitJoinOfSuperclassTablesEnabled;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override
public int getPreferredSqlTypeCodeForBoolean() {
return preferredSqlTypeCodeForBoolean;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// In-flight mutation access

public void applyBeanManager(Object beanManager) {
Expand Down
Expand Up @@ -156,7 +156,7 @@ else if ( reflectedJtd != null ) {
}

@SuppressWarnings("rawtypes")
private static BasicType<?> resolveSqlTypeIndicators(
public static BasicType<?> resolveSqlTypeIndicators(
SqlTypeDescriptorIndicators stdIndicators,
BasicType<?> resolved) {
if ( resolved instanceof SqlTypeDescriptorIndicatorCapable ) {
Expand Down
Expand Up @@ -143,14 +143,12 @@ public void bindColumn(
if ( columnSource.getSizeSource().getLength() != null ) {
column.setLength( columnSource.getSizeSource().getLength() );
}
final Integer precision = columnSource.getSizeSource().getPrecision();

if ( columnSource.getSizeSource().getScale() != null ) {
if ( precision != null && precision > 0 ) {
column.setPrecision( precision );
column.setScale( columnSource.getSizeSource().getScale() );
}

if ( columnSource.getSizeSource().getPrecision() != null ) {
column.setPrecision( columnSource.getSizeSource().getPrecision() );
}
}

column.setNullable( interpretNullability( columnSource.isNullable(), areColumnsNullableByDefault ) );
Expand Down
Expand Up @@ -484,4 +484,9 @@ public SqmFunctionRegistry getCustomSqmFunctionRegistry() {
public boolean isOmitJoinOfSuperclassTablesEnabled() {
return delegate.isOmitJoinOfSuperclassTablesEnabled();
}

@Override
public int getPreferredSqlTypeCodeForBoolean() {
return delegate.getPreferredSqlTypeCodeForBoolean();
}
}
Expand Up @@ -358,4 +358,6 @@ default boolean isCollectionsInDefaultFetchGroupEnabled() {
}

boolean isOmitJoinOfSuperclassTablesEnabled();

int getPreferredSqlTypeCodeForBoolean();
}
Expand Up @@ -233,7 +233,7 @@ protected void initMappingColumn(
this.mappingColumn = new Column();
redefineColumnName( columnName, propertyName, applyNamingStrategy );
this.mappingColumn.setLength( length );
if ( precision!=null ) { //relevant precision
if ( precision != null && precision > 0 ) { //relevant precision
this.mappingColumn.setPrecision( precision );
this.mappingColumn.setScale( scale );
}
Expand Down
Expand Up @@ -1539,7 +1539,7 @@ public boolean supportsNoColumnsInsert() {
@Override
public String translateDatetimeFormat(String format) {
//I don't think HANA needs FM
return OracleDialect.datetimeFormat( format, false ).result();
return OracleDialect.datetimeFormat( format, false, false ).result();
}

public boolean isUseUnicodeStringTypes() {
Expand Down
Expand Up @@ -12,6 +12,7 @@
import org.hibernate.boot.TempTableDdlTransactionHandling;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.CommonFunctionFactory;
import org.hibernate.dialect.function.IndividualLeastGreatestEmulation;
import org.hibernate.dialect.identity.AbstractTransactSQLIdentityColumnSupport;
import org.hibernate.dialect.identity.IdentityColumnSupport;
import org.hibernate.metamodel.mapping.EntityMappingType;
Expand Down Expand Up @@ -100,6 +101,9 @@ public void initializeFunctionRegistry(QueryEngine queryEngine) {
CommonFunctionFactory.substring_substringLen( queryEngine );
CommonFunctionFactory.datepartDatename( queryEngine );
CommonFunctionFactory.lastDay_eomonth( queryEngine );

queryEngine.getSqmFunctionRegistry().register( "least", new IndividualLeastGreatestEmulation( true ) );
queryEngine.getSqmFunctionRegistry().register( "greatest", new IndividualLeastGreatestEmulation( false ) );
}

@Override
Expand Down
104 changes: 104 additions & 0 deletions hibernate-core/src/main/java/org/hibernate/dialect/BooleanDecoder.java
@@ -0,0 +1,104 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.dialect;

import org.hibernate.query.CastType;

/**
* Utility for decoding boolean representations.
*
* @author Christian Beikov
*/
public final class BooleanDecoder {

public static String toInteger(CastType from) {
switch ( from ) {
case BOOLEAN:
return "decode(?1,false,0,true,1,null)";
case YN_BOOLEAN:
return "decode(?1,'Y',1,'N',0,null)";
case TF_BOOLEAN:
return "decode(?1,'T',1,'F',0,null)";
}
return null;
}

public static String toBoolean(CastType from) {
switch ( from ) {
case STRING:
return "decode(?1,'T',true,'F',false,'Y',true,'N',false,null)";
case YN_BOOLEAN:
return "decode(?1,'Y',true,'N',false,null)";
case TF_BOOLEAN:
return "decode(?1,'T',true,'F',false,null)";
case INTEGER:
case LONG:
case INTEGER_BOOLEAN:
return "decode(?1,abs(sign(?1)),1,true,0,false,null)";
}
return null;
}

public static String toIntegerBoolean(CastType from) {
switch ( from ) {
case STRING:
return "decode(?1,'T',1,'F',0,'Y',1,'N',0,null)";
case YN_BOOLEAN:
return "decode(?1,'Y',1,'N',0,null)";
case TF_BOOLEAN:
return "decode(?1,'T',1,'F',0,null)";
case INTEGER:
case LONG:
return "abs(sign(?1))";
}
return null;
}

public static String toYesNoBoolean(CastType from) {
switch ( from ) {
case STRING:
return "decode(?1,'T','Y','F','N','Y','Y','N','N',null)";
case INTEGER_BOOLEAN:
return "decode(?1,1,'Y',0,'N',null)";
case TF_BOOLEAN:
return "decode(?1,'T','Y','F','N',null)";
case INTEGER:
case LONG:
return "decode(abs(sign(?1)),1,'Y',0,'N',null)";
}
return null;
}

public static String toTrueFalseBoolean(CastType from) {
switch ( from ) {
case STRING:
return "decode(?1,'T','T','F','F','Y','T','N','F',null)";
case INTEGER_BOOLEAN:
return "decode(?1,1,'T',0,'F',null)";
case YN_BOOLEAN:
return "decode(?1,'Y','T','N','F',null)";
case INTEGER:
case LONG:
return "decode(abs(sign(?1)),1,'T',0,'F',null)";
}
return null;
}

public static String toString(CastType from) {
switch ( from ) {
case INTEGER_BOOLEAN:
return "decode(?1,0,'false',1,'true',null)";
case TF_BOOLEAN:
return "decode(?1,'T','true','F','false',null)";
case YN_BOOLEAN:
return "decode(?1,'Y','true','N','false',null)";
case BOOLEAN:
return "decode(?1,true,'true',false,'false',null)";
}
return null;
}
}
Expand Up @@ -304,7 +304,7 @@ public boolean supportsPartitionBy() {
public String translateDatetimeFormat(String format) {
//I do not know if CUBRID supports FM, but it
//seems that it does pad by default, so it needs it!
return OracleDialect.datetimeFormat( format, true )
return OracleDialect.datetimeFormat( format, true, false )
.replace("SSSSSS", "FF")
.replace("SSSSS", "FF")
.replace("SSSS", "FF")
Expand Down
Expand Up @@ -394,7 +394,7 @@ public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() {
@Override
public String translateDatetimeFormat(String format) {
//I don't think Cache needs FM
return OracleDialect.datetimeFormat( format, false ).result();
return OracleDialect.datetimeFormat( format, false, false ).result();
}

}
28 changes: 16 additions & 12 deletions hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java
Expand Up @@ -28,7 +28,6 @@
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.query.CastType;
import org.hibernate.query.TemporalUnit;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.mutation.internal.cte.CteStrategy;
Expand Down Expand Up @@ -661,11 +660,26 @@ public IdentityColumnSupport getIdentityColumnSupport() {
return new DB2IdentityColumnSupport();
}

@Override
public boolean supportsValuesList() {
return true;
}

@Override
public boolean supportsRowValueConstructorSyntaxInInList() {
return false;
}

@Override
public boolean supportsPartitionBy() {
return true;
}

@Override
public boolean supportsNonQueryWithCTE() {
return true;
}

@Override
public GroupBySummarizationRenderingStrategy getGroupBySummarizationRenderingStrategy() {
return GroupBySummarizationRenderingStrategy.FUNCTION;
Expand All @@ -679,7 +693,7 @@ public GroupByConstantRenderingStrategy getGroupByConstantRenderingStrategy() {
@Override
public String translateDatetimeFormat(String format) {
//DB2 does not need nor support FM
return OracleDialect.datetimeFormat( format, false ).result();
return OracleDialect.datetimeFormat( format, false, false ).result();
}

@Override
Expand All @@ -703,16 +717,6 @@ public String toBooleanValueString(boolean bool) {
}
}

@Override
public String castPattern(CastType from, CastType to) {
if ( getVersion() < 1100 && from == CastType.BOOLEAN && to == CastType.STRING ) {
return "case when ?1 = 1 then 'true' else 'false' end";
}
else {
return super.castPattern( from, to );
}
}

@Override
public String extractPattern(TemporalUnit unit) {
if ( unit == TemporalUnit.WEEK ) {
Expand Down

0 comments on commit 9f096e8

Please sign in to comment.