Fix type resolution issues and add missing JTDs. Fix SQL trim parsing and some newly added tests

This commit is contained in:
Christian Beikov 2021-03-31 13:31:46 +02:00
parent e22dc55adb
commit f1ede3df4f
11 changed files with 86 additions and 40 deletions

View File

@ -102,35 +102,35 @@ public class InferredBasicValueResolver {
legacyType = jdbcMapping;
}
else {
// here we have the legacy case
// - we mimic how this used to be done
final BasicType registeredType = typeConfiguration.getBasicTypeRegistry().getRegisteredType( reflectedJtd.getJavaType() );
// Use JTD if we know it to apply any specialized resolutions
if ( registeredType != null ) {
// reuse the "legacy type"
legacyType = resolveSqlTypeIndicators( stdIndicators, registeredType );
jdbcMapping = legacyType;
if ( reflectedJtd instanceof EnumJavaTypeDescriptor ) {
return fromEnum(
(EnumJavaTypeDescriptor) reflectedJtd,
explicitJavaTypeAccess.apply( typeConfiguration ),
explicitSqlTypeAccess.apply( typeConfiguration ),
stdIndicators,
typeConfiguration
);
}
else if ( reflectedJtd instanceof TemporalJavaTypeDescriptor ) {
return fromTemporal(
(TemporalJavaTypeDescriptor) reflectedJtd,
explicitJavaTypeAccess,
explicitSqlTypeAccess,
stdIndicators,
typeConfiguration
);
}
else {
// Use JTD if we know it to apply any specialized resolutions
// here we have the legacy case
// - we mimic how this used to be done
final BasicType registeredType = typeConfiguration.getBasicTypeRegistry().getRegisteredType( reflectedJtd.getJavaType() );
if ( reflectedJtd instanceof EnumJavaTypeDescriptor ) {
return fromEnum(
(EnumJavaTypeDescriptor) reflectedJtd,
explicitJavaTypeAccess.apply( typeConfiguration ),
explicitSqlTypeAccess.apply( typeConfiguration ),
stdIndicators,
typeConfiguration
);
}
else if ( reflectedJtd instanceof TemporalJavaTypeDescriptor ) {
return fromTemporal(
(TemporalJavaTypeDescriptor) reflectedJtd,
explicitJavaTypeAccess,
explicitSqlTypeAccess,
stdIndicators,
typeConfiguration
);
if ( registeredType != null ) {
// reuse the "legacy type"
legacyType = resolveSqlTypeIndicators( stdIndicators, registeredType );
jdbcMapping = legacyType;
}
else if ( reflectedJtd instanceof SerializableTypeDescriptor ) {
legacyType = new SerializableType<>( reflectedJtd.getJavaTypeClass() );

View File

@ -225,7 +225,7 @@ public class EmbeddableMappingType implements ManagedMappingType, SelectableMapp
containingTableExpression,
columnExpression,
selectable.isFormula(),
selectable.getTemplate( dialect, sessionFactory.getQueryEngine().getSqmFunctionRegistry() ),
selectable.getCustomReadExpression(),
selectable.getCustomWriteExpression(),
representationStrategy.resolvePropertyAccess( bootPropertyDescriptor ),
compositeType.getCascadeStyle( attributeIndex ),

View File

@ -1512,7 +1512,11 @@ public abstract class AbstractEntityPersister
),
sqlAstProcessingState -> new ColumnReference(
rootTableReference.getIdentificationVariable(),
selection,
rootPkColumnName,
false,
null,
null,
selection.getJdbcMapping(),
getFactory()
)
);

View File

@ -3733,7 +3733,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
: mappingModelExpressable.getElementDescriptor();
final List<SqlAstNode> arguments = new ArrayList<>( 1 );
collectionPart.forEachSelection(
collectionPart.forEachSelectable(
(selectionIndex, selectionMapping) -> {
arguments.add(
new ColumnReference(

View File

@ -219,7 +219,18 @@ public final class Template {
boolean hasMoreOperands = true;
String operandToken = tokens.nextToken();
switch ( operandToken.toLowerCase( Locale.ROOT ) ) {
case "leading":
case "trailing":
case "both":
operands.add( operandToken );
if ( hasMoreOperands = tokens.hasMoreTokens() ) {
operandToken = tokens.nextToken();
}
break;
}
boolean quotedOperand = false;
int parenthesis = 0;
while ( hasMoreOperands ) {
final boolean isQuote = "'".equals( operandToken );
if ( isQuote ) {
@ -235,14 +246,40 @@ public final class Template {
else if ( quotedOperand ) {
builder.append( operandToken );
}
else if ( operandToken.length() == 1 && Character.isWhitespace( operandToken.charAt( 0 ) ) ) {
// do nothing
else if ( parenthesis != 0 ) {
builder.append( operandToken );
switch ( operandToken ) {
case "(":
parenthesis++;
break;
case ")":
parenthesis--;
break;
}
}
else {
operands.add( operandToken );
builder.append( operandToken );
switch ( operandToken.toLowerCase( Locale.ROOT ) ) {
case "(":
parenthesis++;
break;
case ")":
parenthesis--;
break;
case "from":
if ( builder.length() != 0 ) {
operands.add( builder.substring( 0, builder.length() - 4 ) );
builder.setLength( 0 );
operands.add( operandToken );
}
break;
}
}
operandToken = tokens.nextToken();
hasMoreOperands = tokens.hasMoreTokens() && ! ")".equals( operandToken );
hasMoreOperands = tokens.hasMoreTokens() && ( parenthesis != 0 || ! ")".equals( operandToken ) );
}
if ( builder.length() != 0 ) {
operands.add( builder.toString() );
}
TrimOperands trimOperands = new TrimOperands( operands );

View File

@ -2662,7 +2662,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
else if ( elementDescriptor instanceof EntityCollectionPart ) {
final ForeignKeyDescriptor foreignKeyDescriptor = ( (EntityCollectionPart) elementDescriptor ).getForeignKeyDescriptor();
if ( foreignKeyDescriptor instanceof SimpleForeignKeyDescriptor ) {
foreignKeyDescriptor.visitTargetColumns(
foreignKeyDescriptor.visitTargetSelectables(
(selectionIndex, selectionMapping) -> appendSql( selectionMapping.getSelectionExpression() )
);
}
@ -2671,7 +2671,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
else if ( modelPart instanceof ToOneAttributeMapping ) {
final ForeignKeyDescriptor foreignKeyDescriptor = ( (ToOneAttributeMapping) modelPart ).getForeignKeyDescriptor();
if ( foreignKeyDescriptor instanceof SimpleForeignKeyDescriptor ) {
foreignKeyDescriptor.visitTargetColumns(
foreignKeyDescriptor.visitTargetSelectables(
(selectionIndex, selectionMapping) -> appendSql( selectionMapping.getSelectionExpression() )
);
}

View File

@ -51,9 +51,11 @@ import org.hibernate.type.descriptor.java.IntegerTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaObjectTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.JdbcDateTypeDescriptor;
import org.hibernate.type.descriptor.java.JdbcTimeTypeDescriptor;
import org.hibernate.type.descriptor.java.JdbcTimestampTypeDescriptor;
import org.hibernate.type.descriptor.java.LocalDateJavaDescriptor;
import org.hibernate.type.descriptor.java.LocalDateTimeJavaDescriptor;
import org.hibernate.type.descriptor.java.LocalTimeJavaDescriptor;
import org.hibernate.type.descriptor.java.LocaleTypeDescriptor;
import org.hibernate.type.descriptor.java.LongTypeDescriptor;
import org.hibernate.type.descriptor.java.NClobTypeDescriptor;
@ -66,6 +68,7 @@ import org.hibernate.type.descriptor.java.StringTypeDescriptor;
import org.hibernate.type.descriptor.java.TimeZoneTypeDescriptor;
import org.hibernate.type.descriptor.java.UUIDTypeDescriptor;
import org.hibernate.type.descriptor.java.UrlTypeDescriptor;
import org.hibernate.type.descriptor.java.ZoneOffsetJavaDescriptor;
import org.hibernate.type.descriptor.java.ZonedDateTimeJavaDescriptor;
/**
@ -109,6 +112,7 @@ public class JavaTypeDescriptorBaseline {
target.addBaselineDescriptor( InstantJavaDescriptor.INSTANCE );
target.addBaselineDescriptor( LocalDateJavaDescriptor.INSTANCE );
target.addBaselineDescriptor( LocalDateTimeJavaDescriptor.INSTANCE );
target.addBaselineDescriptor( LocalTimeJavaDescriptor.INSTANCE );
target.addBaselineDescriptor( OffsetDateTimeJavaDescriptor.INSTANCE );
target.addBaselineDescriptor( OffsetTimeJavaDescriptor.INSTANCE );
target.addBaselineDescriptor( ZonedDateTimeJavaDescriptor.INSTANCE );
@ -116,9 +120,10 @@ public class JavaTypeDescriptorBaseline {
target.addBaselineDescriptor( CalendarTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( DateTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( java.sql.Date.class, JdbcDateTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( java.sql.Time.class, JdbcTimestampTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( java.sql.Time.class, JdbcTimeTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( java.sql.Timestamp.class, JdbcTimestampTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( TimeZoneTypeDescriptor.INSTANCE );
target.addBaselineDescriptor( ZoneOffsetJavaDescriptor.INSTANCE );
target.addBaselineDescriptor( ClassTypeDescriptor.INSTANCE );

View File

@ -169,10 +169,9 @@ public class ForeignKeyConstraintTest {
}
@Test
@NotImplementedYet( strict = false, reason = "Problem with non-root-entity based FKs" )
public void testGet(SessionFactoryScope scope) {
scope.inTransaction(
session -> session.get( Student.class, 1l )
session -> session.get( Student.class, 1L )
);
}

View File

@ -13,7 +13,8 @@
<class name="org.hibernate.orm.test.mapping.formula.EntityOfFormulas" table="formulas">
<id name="id" />
<property name="realValue" column="real_value" />
<property name="stringFormula" formula="real_value || ' a'" />
<!-- Workaround for Derby which requires an intermediate cast -->
<property name="stringFormula" formula="{fn concat(cast(trim(cast(real_value as char(254))) as varchar(255)), ' a')}" />
<property name="integerFormula" formula="real_value + 1" />
</class>

View File

@ -19,9 +19,9 @@ import javax.persistence.OneToMany;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.RequiresDialect;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;

View File

@ -31,10 +31,10 @@ import org.hibernate.type.descriptor.jdbc.BasicBinder;
import org.hibernate.type.descriptor.jdbc.BasicExtractor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
import org.hibernate.testing.orm.junit.Jpa;
import org.hibernate.testing.orm.junit.RequiresDialect;
import org.junit.jupiter.api.Test;
/**