More test fixes and stored procedure fixes for H2

This commit is contained in:
Christian Beikov 2022-01-26 21:16:13 +01:00
parent da00adf0da
commit c06b5c18e3
7 changed files with 61 additions and 6 deletions

View File

@ -6,6 +6,8 @@
*/
package org.hibernate.dialect;
import java.sql.CallableStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
@ -36,11 +38,11 @@ import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.FetchClauseType;
import org.hibernate.query.sqm.IntervalType;
import org.hibernate.query.sqm.NullOrdering;
import org.hibernate.query.sqm.TemporalUnit;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.mutation.internal.temptable.BeforeUseAction;
import org.hibernate.query.sqm.mutation.internal.temptable.LocalTemporaryTableInsertStrategy;
import org.hibernate.query.sqm.mutation.internal.temptable.LocalTemporaryTableMutationStrategy;
@ -66,7 +68,14 @@ import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import jakarta.persistence.TemporalType;
import static org.hibernate.query.sqm.TemporalUnit.SECOND;
import static org.hibernate.type.SqlTypes.*;
import static org.hibernate.type.SqlTypes.ARRAY;
import static org.hibernate.type.SqlTypes.DECIMAL;
import static org.hibernate.type.SqlTypes.DOUBLE;
import static org.hibernate.type.SqlTypes.FLOAT;
import static org.hibernate.type.SqlTypes.LONG32NVARCHAR;
import static org.hibernate.type.SqlTypes.LONG32VARBINARY;
import static org.hibernate.type.SqlTypes.LONG32VARCHAR;
import static org.hibernate.type.SqlTypes.NUMERIC;
/**
* A {@linkplain Dialect SQL dialect} for H2.
@ -569,6 +578,11 @@ public class H2Dialect extends Dialect {
return new H2IdentityColumnSupport();
}
@Override
public int registerResultSetOutParameter(CallableStatement statement, int position) throws SQLException {
return position;
}
@Override
public String getQueryHintString(String query, String hints) {
return IndexQueryHintHandler.INSTANCE.addQueryHints( query, hints );

View File

@ -7,10 +7,13 @@
package org.hibernate.dialect;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.sqm.BinaryArithmeticOperator;
import org.hibernate.query.sqm.ComparisonOperator;
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.ast.tree.cte.CteStatement;
import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.expression.Literal;
import org.hibernate.sql.ast.tree.expression.Summarization;
@ -105,6 +108,26 @@ public class HANASqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAs
}
}
@Override
public void visitBinaryArithmeticExpression(BinaryArithmeticExpression arithmeticExpression) {
final BinaryArithmeticOperator operator = arithmeticExpression.getOperator();
if ( operator == BinaryArithmeticOperator.MODULO ) {
append( "mod" );
appendSql( OPEN_PARENTHESIS );
arithmeticExpression.getLeftHandOperand().accept( this );
appendSql( ',' );
arithmeticExpression.getRightHandOperand().accept( this );
appendSql( CLOSE_PARENTHESIS );
}
else {
appendSql( OPEN_PARENTHESIS );
render( arithmeticExpression.getLeftHandOperand(), SqlAstNodeRenderingMode.NO_PLAIN_PARAMETER );
appendSql( arithmeticExpression.getOperator().getOperatorSqlTextString() );
render( arithmeticExpression.getRightHandOperand(), SqlAstNodeRenderingMode.NO_PLAIN_PARAMETER );
appendSql( CLOSE_PARENTHESIS );
}
}
@Override
protected boolean supportsRowValueConstructorSyntaxInQuantifiedPredicates() {
return false;

View File

@ -125,7 +125,17 @@ public class ProcedureOutputsImpl extends OutputsImpl implements ProcedureOutput
if ( ProcedureOutputsImpl.this.refCursorParamIndex == -1 ) {
// Handle the function return
ProcedureOutputsImpl.this.refCursorParamIndex = 0;
return buildResultSetOutput( () -> List.of( getOutputParameterValue( procedureCall.getFunctionReturn() ) ) );
final Object outputParameterValue = getOutputParameterValue( procedureCall.getFunctionReturn() );
return buildResultSetOutput(
() -> {
if ( outputParameterValue instanceof ResultSet ) {
return extractResults( (ResultSet) outputParameterValue );
}
else {
return List.of( outputParameterValue );
}
}
);
}
else {
final JdbcCallRefCursorExtractor refCursorParam = refCursorParameters[ProcedureOutputsImpl.this.refCursorParamIndex++];

View File

@ -346,7 +346,6 @@ public class OutputsImpl implements Outputs {
else if ( hasExtendedReturns() ) {
return buildExtendedReturn();
}
// else if ( procedureCall)
throw new NoMoreOutputsException();
}

View File

@ -18,6 +18,7 @@ import org.hibernate.annotations.Filter;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.annotations.ParamDef;
import org.hibernate.dialect.AbstractHANADialect;
import org.hibernate.dialect.DB2Dialect;
import org.hibernate.dialect.DerbyDialect;
import org.hibernate.dialect.H2Dialect;
@ -27,6 +28,7 @@ import org.hibernate.dialect.MySQLDialect;
import org.hibernate.dialect.OracleDialect;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.dialect.SybaseDialect;
import org.hibernate.dialect.TiDBDialect;
import org.hibernate.type.NumericBooleanConverter;
import org.hibernate.type.YesNoConverter;
@ -74,7 +76,9 @@ public class FilterParameterTests {
@SkipForDialect(dialectClass = DB2Dialect.class, reason = "DB2 silently converts a boolean to string types")
@SkipForDialect(dialectClass = MySQLDialect.class, reason = "MySQL silently converts a boolean to string types")
@SkipForDialect(dialectClass = MariaDBDialect.class, reason = "MariaDB silently converts a boolean to string types")
@SkipForDialect(dialectClass = TiDBDialect.class, reason = "TiDB silently converts a boolean to string types")
@SkipForDialect(dialectClass = SybaseDialect.class, matchSubTypes = true, reason = "Sybase silently converts a boolean to string types")
@SkipForDialect(dialectClass = AbstractHANADialect.class, matchSubTypes = true, reason = "HANA silently converts a boolean to string types")
public void testYesNoMismatch(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
final EntityOne loaded = session.byId( EntityOne.class ).load( 1 );
@ -117,8 +121,10 @@ public class FilterParameterTests {
@SkipForDialect(dialectClass = DB2Dialect.class, reason = "DB2 silently converts a boolean to integral types")
@SkipForDialect(dialectClass = MySQLDialect.class, reason = "MySQL silently converts a boolean to integral types")
@SkipForDialect(dialectClass = MariaDBDialect.class, reason = "MariaDB silently converts a boolean to integral types")
@SkipForDialect(dialectClass = TiDBDialect.class, reason = "TiDB silently converts a boolean to integral types")
@SkipForDialect(dialectClass = SQLServerDialect.class, reason = "SQL Server silently converts a boolean to integral types")
@SkipForDialect(dialectClass = SybaseDialect.class, matchSubTypes = true, reason = "Sybase silently converts a boolean to integral types")
@SkipForDialect(dialectClass = AbstractHANADialect.class, matchSubTypes = true, reason = "HANA silently converts a boolean to integral types")
public void testNumericMismatch(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
final EntityTwo loaded = session.byId( EntityTwo.class ).load( 1 );
@ -141,6 +147,7 @@ public class FilterParameterTests {
@Test
@SkipForDialect(dialectClass = MySQLDialect.class, reason = "MySQL silently converts strings to integral types")
@SkipForDialect(dialectClass = MariaDBDialect.class, reason = "MariaDB silently converts strings to integral types")
@SkipForDialect(dialectClass = TiDBDialect.class, reason = "TiDB silently converts strings to integral types")
public void testMismatch(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
final EntityThree loaded = session.byId( EntityThree.class ).load( 1 );

View File

@ -15,6 +15,7 @@ import jakarta.persistence.CollectionTable;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.Table;
/**
@ -30,7 +31,7 @@ public class TheEntityWithUniqueList {
@Basic
private String name;
@CollectionTable(name = "unique_list_contents")
@CollectionTable(name = "unique_list_contents", joinColumns = @JoinColumn(name = "id"))
//tag::ex-collections-custom-type-model[]
@ElementCollection
@CollectionType(type = UniqueListType.class)

View File

@ -12,6 +12,7 @@ import jakarta.persistence.CollectionTable;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.Table;
import org.hibernate.annotations.CollectionTypeRegistration;
@ -31,7 +32,7 @@ public class TheEntityWithUniqueListRegistration {
@Basic
private String name;
@CollectionTable(name = "unique_list_contents_reg")
@CollectionTable(name = "unique_list_contents_reg", joinColumns = @JoinColumn(name = "id"))
//tag::ex-collections-custom-type-model[]
@ElementCollection
private List<String> strings;