split out IntegralTimestampaddFunction
This commit is contained in:
parent
3e97fe39a7
commit
addc3ea4c2
|
@ -14,6 +14,7 @@ import org.hibernate.boot.model.TypeContributions;
|
|||
import org.hibernate.boot.model.naming.Identifier;
|
||||
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
|
||||
import org.hibernate.dialect.function.CommonFunctionFactory;
|
||||
import org.hibernate.dialect.function.IntegralTimestampaddFunction;
|
||||
import org.hibernate.dialect.identity.HANAIdentityColumnSupport;
|
||||
import org.hibernate.dialect.identity.IdentityColumnSupport;
|
||||
import org.hibernate.dialect.pagination.LimitHandler;
|
||||
|
@ -283,6 +284,7 @@ public abstract class AbstractHANADialect extends Dialect {
|
|||
).setArgumentListSignature("(pattern, string[, start])");
|
||||
|
||||
CommonFunctionFactory functionFactory = new CommonFunctionFactory(queryEngine);
|
||||
|
||||
functionFactory.ceiling_ceil();
|
||||
functionFactory.concat_pipeOperator();
|
||||
functionFactory.trim2();
|
||||
|
@ -312,6 +314,9 @@ public abstract class AbstractHANADialect extends Dialect {
|
|||
functionFactory.listagg_stringAgg( "varchar" );
|
||||
functionFactory.inverseDistributionOrderedSetAggregates();
|
||||
functionFactory.hypotheticalOrderedSetAggregates();
|
||||
|
||||
queryEngine.getSqmFunctionRegistry().register( "timestampadd",
|
||||
new IntegralTimestampaddFunction( this, queryEngine.getTypeConfiguration() ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1659,7 +1664,7 @@ public abstract class AbstractHANADialect extends Dialect {
|
|||
@Override
|
||||
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) throws SQLException {
|
||||
JdbcType descriptor = BlobJdbcType.BLOB_BINDING;
|
||||
if ( byte[].class.isInstance( value ) ) {
|
||||
if ( value instanceof byte[] ) {
|
||||
// performance shortcut for binding BLOB data in byte[] format
|
||||
descriptor = BlobJdbcType.PRIMITIVE_ARRAY_BINDING;
|
||||
}
|
||||
|
|
|
@ -841,18 +841,21 @@ public abstract class Dialect implements ConversionContext {
|
|||
//only some databases support the ANSI SQL-style position() function, so
|
||||
//define it here as an alias for locate()
|
||||
|
||||
queryEngine.getSqmFunctionRegistry().register( "position", new LocatePositionEmulation( queryEngine.getTypeConfiguration() ) );
|
||||
queryEngine.getSqmFunctionRegistry().register( "position",
|
||||
new LocatePositionEmulation( queryEngine.getTypeConfiguration() ) );
|
||||
|
||||
//very few databases support ANSI-style overlay() function, so emulate
|
||||
//it here in terms of either insert() or concat()/substring()
|
||||
|
||||
queryEngine.getSqmFunctionRegistry().register( "overlay", new InsertSubstringOverlayEmulation( queryEngine.getTypeConfiguration(), false ) );
|
||||
queryEngine.getSqmFunctionRegistry().register( "overlay",
|
||||
new InsertSubstringOverlayEmulation( queryEngine.getTypeConfiguration(), false ) );
|
||||
|
||||
//ANSI SQL trim() function is supported on almost all of the databases
|
||||
//we care about, but on some it must be emulated using ltrim(), rtrim(),
|
||||
//and replace()
|
||||
|
||||
queryEngine.getSqmFunctionRegistry().register( "trim", new TrimFunction( this, queryEngine.getTypeConfiguration() ) );
|
||||
queryEngine.getSqmFunctionRegistry().register( "trim",
|
||||
new TrimFunction( this, queryEngine.getTypeConfiguration() ) );
|
||||
|
||||
//ANSI SQL cast() function is supported on the databases we care most
|
||||
//about but in certain cases it doesn't allow some useful typecasts,
|
||||
|
@ -879,7 +882,8 @@ public abstract class Dialect implements ConversionContext {
|
|||
//additional non-standard temporal field types, which must be emulated in
|
||||
//a very dialect-specific way
|
||||
|
||||
queryEngine.getSqmFunctionRegistry().register( "extract", new ExtractFunction( this ) );
|
||||
queryEngine.getSqmFunctionRegistry().register( "extract",
|
||||
new ExtractFunction( this ) );
|
||||
|
||||
//comparison functions supported on every known database
|
||||
|
||||
|
@ -888,7 +892,8 @@ public abstract class Dialect implements ConversionContext {
|
|||
//two-argument synonym for coalesce() supported on most but not every
|
||||
//database, so define it here as an alias for coalesce(arg1,arg2)
|
||||
|
||||
queryEngine.getSqmFunctionRegistry().register( "ifnull", new CoalesceIfnullEmulation() );
|
||||
queryEngine.getSqmFunctionRegistry().register( "ifnull",
|
||||
new CoalesceIfnullEmulation() );
|
||||
|
||||
//rpad() and pad() are supported on almost every database, and emulated
|
||||
//where not supported, but they're not considered "standard" ... instead
|
||||
|
@ -898,12 +903,14 @@ public abstract class Dialect implements ConversionContext {
|
|||
|
||||
//pad() is a function we've designed to look like ANSI trim()
|
||||
|
||||
queryEngine.getSqmFunctionRegistry().register( "pad", new LpadRpadPadEmulation( queryEngine.getTypeConfiguration() ) );
|
||||
queryEngine.getSqmFunctionRegistry().register( "pad",
|
||||
new LpadRpadPadEmulation( queryEngine.getTypeConfiguration() ) );
|
||||
|
||||
//legacy Hibernate convenience function for casting to string, defined
|
||||
//here as an alias for cast(arg as String)
|
||||
|
||||
queryEngine.getSqmFunctionRegistry().register( "str", new CastStrEmulation( queryEngine.getTypeConfiguration() ) );
|
||||
queryEngine.getSqmFunctionRegistry().register( "str",
|
||||
new CastStrEmulation( queryEngine.getTypeConfiguration() ) );
|
||||
|
||||
//format() function for datetimes, emulated on many databases using the
|
||||
//Oracle-style to_char() function, and on others using their native
|
||||
|
@ -914,8 +921,10 @@ public abstract class Dialect implements ConversionContext {
|
|||
//timestampadd()/timestampdiff() delegated back to the Dialect itself
|
||||
//since there is a great variety of different ways to emulate them
|
||||
|
||||
queryEngine.getSqmFunctionRegistry().register( "timestampadd", new TimestampaddFunction( this, queryEngine.getTypeConfiguration() ) );
|
||||
queryEngine.getSqmFunctionRegistry().register( "timestampdiff", new TimestampdiffFunction( this, queryEngine.getTypeConfiguration() ) );
|
||||
queryEngine.getSqmFunctionRegistry().register( "timestampadd",
|
||||
new TimestampaddFunction( this ) );
|
||||
queryEngine.getSqmFunctionRegistry().register( "timestampdiff",
|
||||
new TimestampdiffFunction( this, queryEngine.getTypeConfiguration() ) );
|
||||
queryEngine.getSqmFunctionRegistry().registerAlternateKey( "dateadd", "timestampadd" );
|
||||
queryEngine.getSqmFunctionRegistry().registerAlternateKey( "datediff", "timestampdiff" );
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.dialect;
|
|||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.boot.model.TypeContributions;
|
||||
import org.hibernate.dialect.function.CommonFunctionFactory;
|
||||
import org.hibernate.dialect.function.IntegralTimestampaddFunction;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||
import org.hibernate.engine.jdbc.env.spi.IdentifierCaseStrategy;
|
||||
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
|
||||
|
@ -221,6 +222,9 @@ public class SybaseDialect extends AbstractTransactSQLDialect {
|
|||
functionFactory.replace_strReplace();
|
||||
functionFactory.everyAny_sumCaseCase();
|
||||
functionFactory.bitLength_pattern( "datalength(?1) * 8" );
|
||||
|
||||
queryEngine.getSqmFunctionRegistry().register( "timestampadd",
|
||||
new IntegralTimestampaddFunction( this, queryEngine.getTypeConfiguration() ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* 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.function;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||
import org.hibernate.query.sqm.BinaryArithmeticOperator;
|
||||
import org.hibernate.query.sqm.TemporalUnit;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||
import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression;
|
||||
import org.hibernate.sql.ast.tree.expression.CastTarget;
|
||||
import org.hibernate.sql.ast.tree.expression.DurationUnit;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.sql.ast.tree.expression.QueryLiteral;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Used in place of {@link TimestampaddFunction} for databases which don't
|
||||
* support fractional seconds in the {@code timestampadd()} function.
|
||||
*
|
||||
* @author Christian Beikov
|
||||
*/
|
||||
public class IntegralTimestampaddFunction
|
||||
extends TimestampaddFunction {
|
||||
|
||||
private final Dialect dialect;
|
||||
private final CastFunction castFunction;
|
||||
private final BasicType<Integer> integerType;
|
||||
|
||||
public IntegralTimestampaddFunction(Dialect dialect, TypeConfiguration typeConfiguration) {
|
||||
super( dialect );
|
||||
this.dialect = dialect;
|
||||
this.integerType = typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER );
|
||||
//This is kinda wrong, we're supposed to use findFunctionDescriptor("cast"), not instantiate CastFunction
|
||||
//However, since no Dialects currently override the cast() function, it's OK for now
|
||||
this.castFunction = new CastFunction( dialect, dialect.getPreferredSqlTypeCodeForBoolean() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> arguments,
|
||||
SqlAstTranslator<?> walker) {
|
||||
|
||||
final DurationUnit field = (DurationUnit) arguments.get( 0 );
|
||||
final Expression magnitude = (Expression) arguments.get(1);
|
||||
final Expression to = (Expression) arguments.get( 2 );
|
||||
|
||||
final TemporalUnit unit = bestTemporalUnit( magnitude, field );
|
||||
if ( unit != field.getUnit() ) {
|
||||
renderWithUnitConversion( sqlAppender, magnitude, to, walker, field, unit );
|
||||
}
|
||||
else {
|
||||
super.render( sqlAppender, arguments, walker );
|
||||
}
|
||||
}
|
||||
|
||||
private void renderWithUnitConversion(
|
||||
SqlAppender sqlAppender,
|
||||
Expression magnitude,
|
||||
Expression to,
|
||||
SqlAstTranslator<?> walker,
|
||||
DurationUnit field,
|
||||
TemporalUnit unit) {
|
||||
patternRenderer( unit, magnitude, to )
|
||||
.render( sqlAppender, convertedArguments( field, unit, magnitude, to ), walker );
|
||||
}
|
||||
|
||||
private List<SqlAstNode> convertedArguments(
|
||||
DurationUnit field,
|
||||
TemporalUnit unit,
|
||||
Expression magnitude,
|
||||
Expression to) {
|
||||
|
||||
return Arrays.asList(
|
||||
new DurationUnit( unit, field.getExpressionType() ),
|
||||
new SelfRenderingFunctionSqlAstExpression(
|
||||
"cast",
|
||||
castFunction,
|
||||
Arrays.asList(
|
||||
convertedArgument(field, unit, magnitude),
|
||||
new CastTarget( integerType )
|
||||
),
|
||||
integerType,
|
||||
integerType
|
||||
),
|
||||
to
|
||||
);
|
||||
}
|
||||
|
||||
private Expression convertedArgument(DurationUnit field, TemporalUnit unit, Expression magnitude) {
|
||||
final BasicValuedMapping expressionType = (BasicValuedMapping) magnitude.getExpressionType();
|
||||
final String conversionFactor = field.getUnit().conversionFactor( unit, dialect );
|
||||
return conversionFactor.isEmpty()
|
||||
? magnitude
|
||||
: new BinaryArithmeticExpression(
|
||||
magnitude,
|
||||
conversionFactor.charAt(0) == '*'
|
||||
? BinaryArithmeticOperator.MULTIPLY
|
||||
: BinaryArithmeticOperator.DIVIDE,
|
||||
new QueryLiteral<>(
|
||||
expressionType.getExpressibleJavaType().fromString( conversionFactor.substring(1) ),
|
||||
expressionType
|
||||
),
|
||||
expressionType
|
||||
);
|
||||
}
|
||||
|
||||
private TemporalUnit bestTemporalUnit(Expression magnitude, DurationUnit field) {
|
||||
final JdbcType jdbcType = magnitude.getExpressionType().getJdbcMappings().get( 0 ).getJdbcType();
|
||||
if ( jdbcType.isFloat() ) {
|
||||
// We need to multiply the magnitude by the conversion factor and cast to int
|
||||
// Use second by default and nanosecond if we encounter fractional seconds
|
||||
return field.getUnit() == TemporalUnit.SECOND
|
||||
? TemporalUnit.NANOSECOND
|
||||
: TemporalUnit.SECOND;
|
||||
}
|
||||
else {
|
||||
return field.getUnit();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,9 +8,7 @@ package org.hibernate.dialect.function;
|
|||
|
||||
import jakarta.persistence.TemporalType;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.BinaryArithmeticOperator;
|
||||
import org.hibernate.query.sqm.IntervalType;
|
||||
import org.hibernate.query.sqm.TemporalUnit;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
|
@ -22,17 +20,9 @@ import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
|
|||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||
import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression;
|
||||
import org.hibernate.sql.ast.tree.expression.CastTarget;
|
||||
import org.hibernate.sql.ast.tree.expression.DurationUnit;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.sql.ast.tree.expression.QueryLiteral;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
@ -43,16 +33,20 @@ import static org.hibernate.type.spi.TypeConfiguration.getSqlIntervalType;
|
|||
import static org.hibernate.type.spi.TypeConfiguration.getSqlTemporalType;
|
||||
|
||||
/**
|
||||
* The {@code timestampadd()} or {@code dateadd()} function has a funny
|
||||
* syntax which accepts a {@link TemporalUnit} as the first argument,
|
||||
* and the actual set of accepted units varies widely. This class uses
|
||||
* {@link Dialect#timestampaddPattern(TemporalUnit, TemporalType, IntervalType)}
|
||||
* to abstract these differences.
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class TimestampaddFunction
|
||||
extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||
|
||||
private final Dialect dialect;
|
||||
private final CastFunction castFunction;
|
||||
private final BasicType<Integer> integerType;
|
||||
|
||||
public TimestampaddFunction(Dialect dialect, TypeConfiguration typeConfiguration) {
|
||||
public TimestampaddFunction(Dialect dialect) {
|
||||
super(
|
||||
"timestampadd",
|
||||
new ArgumentTypesValidator(
|
||||
|
@ -62,10 +56,6 @@ public class TimestampaddFunction
|
|||
StandardFunctionReturnTypeResolvers.useArgType( 3 )
|
||||
);
|
||||
this.dialect = dialect;
|
||||
this.integerType = typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER );
|
||||
//This is kinda wrong, we're supposed to use findFunctionDescriptor("cast"), not instantiate CastFunction
|
||||
//However, since no Dialects currently override the cast() function, it's OK for now
|
||||
this.castFunction = new CastFunction( dialect, dialect.getPreferredSqlTypeCodeForBoolean() );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,89 +68,15 @@ public class TimestampaddFunction
|
|||
final Expression magnitude = (Expression) arguments.get(1);
|
||||
final Expression to = (Expression) arguments.get( 2 );
|
||||
|
||||
final TemporalUnit unit = bestTemporalUnit( magnitude, field );
|
||||
if ( unit != field.getUnit() ) {
|
||||
renderWithUnitConversion( sqlAppender, arguments, walker, field, unit );
|
||||
}
|
||||
else {
|
||||
patternRenderer( to, magnitude, unit ).render( sqlAppender, arguments, walker );
|
||||
}
|
||||
patternRenderer( field.getUnit(), magnitude, to ).render( sqlAppender, arguments, walker );
|
||||
}
|
||||
|
||||
private PatternRenderer patternRenderer(Expression to, Expression interval, TemporalUnit unit) {
|
||||
PatternRenderer patternRenderer(TemporalUnit unit, Expression interval, Expression to) {
|
||||
TemporalType temporalType = getSqlTemporalType( to.getExpressionType() );
|
||||
IntervalType intervalType = getSqlIntervalType( interval.getExpressionType().getJdbcMappings().get(0) );
|
||||
return new PatternRenderer( dialect.timestampaddPattern( unit, temporalType, intervalType ) );
|
||||
}
|
||||
|
||||
private void renderWithUnitConversion(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> arguments,
|
||||
SqlAstTranslator<?> walker,
|
||||
DurationUnit field,
|
||||
TemporalUnit unit) {
|
||||
final Expression magnitude = (Expression) arguments.get( 1 );
|
||||
final Expression to = (Expression) arguments.get( 2 );
|
||||
final Expression interval = (Expression) arguments.get(1);
|
||||
|
||||
final List<SqlAstNode> castArguments = new ArrayList<>( 2 );
|
||||
final List<SqlAstNode> newArguments = new ArrayList<>( arguments );
|
||||
|
||||
castArguments.add( convertedArgument( field, unit, magnitude ) );
|
||||
castArguments.add( new CastTarget( integerType ) );
|
||||
newArguments.set( 0, new DurationUnit( unit, field.getExpressionType() ) );
|
||||
newArguments.set(
|
||||
1,
|
||||
new SelfRenderingFunctionSqlAstExpression(
|
||||
"cast",
|
||||
castFunction,
|
||||
castArguments,
|
||||
integerType,
|
||||
integerType
|
||||
)
|
||||
|
||||
);
|
||||
patternRenderer( to, interval, unit ).render( sqlAppender, newArguments, walker );
|
||||
}
|
||||
|
||||
private Expression convertedArgument(DurationUnit field, TemporalUnit unit, Expression magnitude) {
|
||||
final BasicValuedMapping expressionType = (BasicValuedMapping) magnitude.getExpressionType();
|
||||
final String conversionFactor = field.getUnit().conversionFactor( unit, dialect );
|
||||
return conversionFactor.isEmpty()
|
||||
? magnitude
|
||||
: new BinaryArithmeticExpression(
|
||||
magnitude,
|
||||
conversionFactor.charAt(0) == '*'
|
||||
? BinaryArithmeticOperator.MULTIPLY
|
||||
: BinaryArithmeticOperator.DIVIDE,
|
||||
new QueryLiteral<>(
|
||||
expressionType.getExpressibleJavaType().fromString( conversionFactor.substring(1) ),
|
||||
expressionType
|
||||
),
|
||||
expressionType
|
||||
);
|
||||
}
|
||||
|
||||
private TemporalUnit bestTemporalUnit(Expression magnitude, DurationUnit field) {
|
||||
if ( dialect.supportsFractionalTimestampArithmetic() ) {
|
||||
return field.getUnit();
|
||||
}
|
||||
else {
|
||||
final JdbcType jdbcType = magnitude.getExpressionType().getJdbcMappings().get( 0 ).getJdbcType();
|
||||
if ( jdbcType.isFloat() ) {
|
||||
// Some databases don't support fractional seconds
|
||||
// We need to multiply the magnitude by the conversion factor and cast to int
|
||||
// Use second by default and nanosecond if we encounter fractional seconds
|
||||
return field.getUnit() == TemporalUnit.SECOND
|
||||
? TemporalUnit.NANOSECOND
|
||||
: TemporalUnit.SECOND;
|
||||
}
|
||||
else {
|
||||
return field.getUnit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
// protected <T> SelfRenderingSqlFunctionExpression<T> generateSqmFunctionExpression(
|
||||
// List<SqmTypedNode<?>> arguments,
|
||||
|
|
|
@ -8,8 +8,10 @@ package org.hibernate.dialect.function;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.persistence.TemporalType;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.TemporalUnit;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
|
@ -27,8 +29,15 @@ import org.hibernate.type.spi.TypeConfiguration;
|
|||
import static java.util.Arrays.asList;
|
||||
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.TEMPORAL;
|
||||
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.TEMPORAL_UNIT;
|
||||
import static org.hibernate.type.spi.TypeConfiguration.getSqlTemporalType;
|
||||
|
||||
/**
|
||||
* The {@code timestampdiff()} or {@code datediff()} function has a funny
|
||||
* syntax which accepts a {@link TemporalUnit} as the first argument, and
|
||||
* the actual set of accepted units varies widely. This class uses
|
||||
* {@link Dialect#timestampdiffPattern(TemporalUnit, TemporalType, TemporalType)}
|
||||
* to abstract these differences.
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class TimestampdiffFunction
|
||||
|
@ -59,13 +68,14 @@ public class TimestampdiffFunction
|
|||
final DurationUnit field = (DurationUnit) arguments.get( 0 );
|
||||
final Expression from = (Expression) arguments.get( 1 );
|
||||
final Expression to = (Expression) arguments.get( 2 );
|
||||
final String pattern = dialect.timestampdiffPattern(
|
||||
field.getUnit(),
|
||||
TypeConfiguration.getSqlTemporalType( from.getExpressionType() ),
|
||||
TypeConfiguration.getSqlTemporalType( to.getExpressionType() )
|
||||
);
|
||||
|
||||
new PatternRenderer( pattern ).render( sqlAppender, arguments, walker );
|
||||
patternRenderer( field.getUnit(), from, to ).render( sqlAppender, arguments, walker );
|
||||
}
|
||||
|
||||
private PatternRenderer patternRenderer(TemporalUnit unit, Expression from, Expression to) {
|
||||
TemporalType lhsTemporalType = getSqlTemporalType( from.getExpressionType() );
|
||||
TemporalType rhsTemporalType = getSqlTemporalType( to.getExpressionType() );
|
||||
return new PatternRenderer( dialect.timestampdiffPattern( unit, lhsTemporalType, rhsTemporalType ) );
|
||||
}
|
||||
|
||||
// @Override
|
||||
|
|
Loading…
Reference in New Issue