Search in sources :

Example 1 with TemporalUnit

use of org.hibernate.query.sqm.TemporalUnit in project hibernate-orm by hibernate.

the class IntegralTimestampaddFunction method render.

@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);
    }
}
Also used : SelfRenderingFunctionSqlAstExpression(org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression) Expression(org.hibernate.sql.ast.tree.expression.Expression) BinaryArithmeticExpression(org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression) TemporalUnit(org.hibernate.query.sqm.TemporalUnit) DurationUnit(org.hibernate.sql.ast.tree.expression.DurationUnit)

Example 2 with TemporalUnit

use of org.hibernate.query.sqm.TemporalUnit in project hibernate-orm by hibernate.

the class BaseSqmToSqlAstConverter method visitBasicValuedPath.

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// SqmPath
@Override
public Expression visitBasicValuedPath(SqmBasicValuedSimplePath<?> sqmPath) {
    final BasicValuedPathInterpretation<?> path = prepareReusablePath(sqmPath, () -> BasicValuedPathInterpretation.from(sqmPath, this, this, jpaQueryComplianceEnabled));
    Expression result = path;
    if (isDuration(sqmPath.getNodeType())) {
        // Durations are stored (at least by default)
        // in a NUMERIC column in seconds with fractional
        // seconds in the decimal places
        // which we need to convert to the given unit
        // 
        // This does not work at all for a Duration
        // mapped to a VARCHAR column, in which case
        // we would need to parse the weird format
        // defined by java.time.Duration (a bit hard
        // to do without some custom function).
        // Nor does it work for databases which have
        // a well-defined INTERVAL type, but that is
        // something we could implement.
        // first let's apply the propagated scale
        Expression scaledExpression = applyScale(toSqlExpression(path));
        if (adjustedTimestamp != null) {
            if (appliedByUnit != null) {
                throw new IllegalStateException();
            }
            // we're adding this variable duration to the
            // given date or timestamp, producing an
            // adjusted date or timestamp
            result = timestampadd().expression((ReturnableType<?>) adjustedTimestampType, new DurationUnit(SECOND, basicType(Long.class)), scaledExpression, adjustedTimestamp);
        } else if (appliedByUnit != null) {
            // we're applying the 'by unit' operator,
            // producing a literal scalar value, so
            // we must convert this duration from
            // nanoseconds to the given unit
            JdbcMappingContainer durationType = scaledExpression.getExpressionType();
            Duration duration;
            if (durationType.getJdbcMappings().get(0).getJdbcType().isInterval()) {
                // For interval types, we need to extract the epoch for integer arithmetic for the 'by unit' operator
                duration = new Duration(extractEpoch(scaledExpression), SECOND, (BasicValuedMapping) durationType);
            } else {
                // The absolute value of the expression is in seconds
                // as the fractional seconds are in the fraction part as can be seen in DurationJavaType
                duration = new Duration(scaledExpression, SECOND, (BasicValuedMapping) durationType);
            }
            TemporalUnit appliedUnit = appliedByUnit.getUnit().getUnit();
            BasicValuedMapping scalarType = (BasicValuedMapping) appliedByUnit.getNodeType();
            result = new Conversion(duration, appliedUnit, scalarType);
        } else {
            // a "bare" Duration value in nanoseconds
            result = scaledExpression;
        }
    }
    return withTreatRestriction(result, sqmPath);
}
Also used : ReturnableType(org.hibernate.query.ReturnableType) BasicValuedMapping(org.hibernate.metamodel.mapping.BasicValuedMapping) JdbcMappingContainer(org.hibernate.metamodel.mapping.JdbcMappingContainer) BinaryArithmeticExpression(org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression) SqmModifiedSubQueryExpression(org.hibernate.query.sqm.tree.expression.SqmModifiedSubQueryExpression) SelfRenderingFunctionSqlAstExpression(org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression) SelfRenderingAggregateFunctionSqlAstExpression(org.hibernate.query.sqm.function.SelfRenderingAggregateFunctionSqlAstExpression) CaseSearchedExpression(org.hibernate.sql.ast.tree.expression.CaseSearchedExpression) SelfRenderingSqlFragmentExpression(org.hibernate.sql.ast.tree.expression.SelfRenderingSqlFragmentExpression) Expression(org.hibernate.sql.ast.tree.expression.Expression) SelfRenderingExpression(org.hibernate.sql.ast.tree.expression.SelfRenderingExpression) SqmExpression(org.hibernate.query.sqm.tree.expression.SqmExpression) CaseSimpleExpression(org.hibernate.sql.ast.tree.expression.CaseSimpleExpression) SqlSelectionExpression(org.hibernate.sql.ast.tree.expression.SqlSelectionExpression) ModifiedSubQueryExpression(org.hibernate.sql.ast.tree.expression.ModifiedSubQueryExpression) TemporalUnit(org.hibernate.query.sqm.TemporalUnit) SqmDurationUnit(org.hibernate.query.sqm.tree.expression.SqmDurationUnit) DurationUnit(org.hibernate.sql.ast.tree.expression.DurationUnit) SqmToDuration(org.hibernate.query.sqm.tree.expression.SqmToDuration) Duration(org.hibernate.sql.ast.tree.expression.Duration) TypeConfiguration.isDuration(org.hibernate.type.spi.TypeConfiguration.isDuration) Conversion(org.hibernate.query.sqm.tree.expression.Conversion)

Example 3 with TemporalUnit

use of org.hibernate.query.sqm.TemporalUnit in project hibernate-orm by hibernate.

the class ExtractFunction method generateSqmFunctionExpression.

@Override
protected <T> SelfRenderingSqmFunction generateSqmFunctionExpression(List<? extends SqmTypedNode<?>> arguments, ReturnableType<T> impliedResultType, QueryEngine queryEngine, TypeConfiguration typeConfiguration) {
    SqmExtractUnit<?> field = (SqmExtractUnit<?>) arguments.get(0);
    SqmExpression<?> expression = (SqmExpression<?>) arguments.get(1);
    TemporalUnit unit = field.getUnit();
    switch(unit) {
        case NANOSECOND:
            return extractNanoseconds(expression, queryEngine, typeConfiguration);
        case NATIVE:
            throw new SemanticException("can't extract() the field TemporalUnit.NATIVE");
        case OFFSET:
            // use format(arg, 'xxx') to get the offset
            return extractOffsetUsingFormat(expression, queryEngine, typeConfiguration);
        case DATE:
        case TIME:
            // on the type of the expression we're extracting from
            return extractDateOrTimeUsingCast(expression, field.getType(), queryEngine, typeConfiguration);
        case WEEK_OF_MONTH:
            // use ceiling(extract(day of month, arg)/7.0)
            return extractWeek(expression, field, DAY_OF_MONTH, queryEngine, typeConfiguration);
        case WEEK_OF_YEAR:
            // use ceiling(extract(day of year, arg)/7.0)
            return extractWeek(expression, field, DAY_OF_YEAR, queryEngine, typeConfiguration);
        default:
            // otherwise it's something we expect the SQL dialect
            // itself to understand, either natively, or via the
            // method Dialect.extract()
            String pattern = dialect.extractPattern(unit);
            return queryEngine.getSqmFunctionRegistry().patternDescriptorBuilder("extract", pattern).setExactArgumentCount(2).setReturnTypeResolver(useArgType(1)).descriptor().generateSqmExpression(arguments, impliedResultType, queryEngine, typeConfiguration);
    }
}
Also used : TemporalUnit(org.hibernate.query.sqm.TemporalUnit) SemanticException(org.hibernate.query.SemanticException)

Example 4 with TemporalUnit

use of org.hibernate.query.sqm.TemporalUnit in project hibernate-orm by hibernate.

the class BaseSqmToSqlAstConverter method visitToDuration.

@Override
public Object visitToDuration(SqmToDuration<?> toDuration) {
    // TODO: do we need to temporarily set appliedByUnit
    // to null before we recurse down the tree?
    // and what about scale?
    Expression magnitude = toSqlExpression(toDuration.getMagnitude().accept(this));
    DurationUnit unit = (DurationUnit) toDuration.getUnit().accept(this);
    // let's start by applying the propagated scale
    // so we don't forget to do it in what follows
    Expression scaledMagnitude = applyScale(magnitude);
    if (adjustedTimestamp != null) {
        // adjusted date or timestamp
        if (appliedByUnit != null) {
            throw new IllegalStateException();
        }
        return timestampadd().expression(// TODO should be adjustedTimestamp.getType()
        (ReturnableType<?>) adjustedTimestampType, unit, scaledMagnitude, adjustedTimestamp);
    } else {
        BasicValuedMapping durationType = (BasicValuedMapping) toDuration.getNodeType();
        Duration duration;
        if (scaledMagnitude.getExpressionType().getJdbcMappings().get(0).getJdbcType().isInterval()) {
            duration = new Duration(extractEpoch(scaledMagnitude), SECOND, durationType);
        } else {
            duration = new Duration(scaledMagnitude, unit.getUnit(), durationType);
        }
        if (appliedByUnit != null) {
            // we're applying the 'by unit' operator,
            // producing a literal scalar value in
            // the given unit
            TemporalUnit appliedUnit = appliedByUnit.getUnit().getUnit();
            BasicValuedMapping scalarType = (BasicValuedMapping) appliedByUnit.getNodeType();
            return new Conversion(duration, appliedUnit, scalarType);
        } else {
            // a "bare" Duration value (gets rendered as nanoseconds)
            return duration;
        }
    }
}
Also used : BasicValuedMapping(org.hibernate.metamodel.mapping.BasicValuedMapping) BinaryArithmeticExpression(org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression) SqmModifiedSubQueryExpression(org.hibernate.query.sqm.tree.expression.SqmModifiedSubQueryExpression) SelfRenderingFunctionSqlAstExpression(org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression) SelfRenderingAggregateFunctionSqlAstExpression(org.hibernate.query.sqm.function.SelfRenderingAggregateFunctionSqlAstExpression) CaseSearchedExpression(org.hibernate.sql.ast.tree.expression.CaseSearchedExpression) SelfRenderingSqlFragmentExpression(org.hibernate.sql.ast.tree.expression.SelfRenderingSqlFragmentExpression) Expression(org.hibernate.sql.ast.tree.expression.Expression) SelfRenderingExpression(org.hibernate.sql.ast.tree.expression.SelfRenderingExpression) SqmExpression(org.hibernate.query.sqm.tree.expression.SqmExpression) CaseSimpleExpression(org.hibernate.sql.ast.tree.expression.CaseSimpleExpression) SqlSelectionExpression(org.hibernate.sql.ast.tree.expression.SqlSelectionExpression) ModifiedSubQueryExpression(org.hibernate.sql.ast.tree.expression.ModifiedSubQueryExpression) TemporalUnit(org.hibernate.query.sqm.TemporalUnit) SqmDurationUnit(org.hibernate.query.sqm.tree.expression.SqmDurationUnit) DurationUnit(org.hibernate.sql.ast.tree.expression.DurationUnit) SqmToDuration(org.hibernate.query.sqm.tree.expression.SqmToDuration) Duration(org.hibernate.sql.ast.tree.expression.Duration) TypeConfiguration.isDuration(org.hibernate.type.spi.TypeConfiguration.isDuration) Conversion(org.hibernate.query.sqm.tree.expression.Conversion)

Example 5 with TemporalUnit

use of org.hibernate.query.sqm.TemporalUnit in project hibernate-orm by hibernate.

the class BaseSqmToSqlAstConverter method transformDatetimeArithmetic.

private Object transformDatetimeArithmetic(SqmBinaryArithmetic<?> expression) {
    BinaryArithmeticOperator operator = expression.getOperator();
    // timestamps are ill-formed
    if (operator != SUBTRACT) {
        throw new SemanticException("illegal operator for temporal type: " + operator);
    }
    // a difference between two dates or two
    // timestamps is a leaf duration, so we
    // must apply the scale, and the 'by unit'
    // ts1 - ts2
    Expression left = cleanly(() -> toSqlExpression(expression.getLeftHandOperand().accept(this)));
    Expression right = cleanly(() -> toSqlExpression(expression.getRightHandOperand().accept(this)));
    TypeConfiguration typeConfiguration = getCreationContext().getMappingMetamodel().getTypeConfiguration();
    TemporalType leftTimestamp = typeConfiguration.getSqlTemporalType(expression.getLeftHandOperand().getNodeType());
    TemporalType rightTimestamp = typeConfiguration.getSqlTemporalType(expression.getRightHandOperand().getNodeType());
    // when we're dealing with Dates, we use
    // DAY as the smallest unit, otherwise we
    // use a platform-specific granularity
    TemporalUnit baseUnit = (rightTimestamp == TemporalType.TIMESTAMP || leftTimestamp == TemporalType.TIMESTAMP) ? NATIVE : DAY;
    if (adjustedTimestamp != null) {
        if (appliedByUnit != null) {
            throw new IllegalStateException();
        }
        // we're using the resulting duration to
        // adjust a date or timestamp on the left
        // baseUnit is the finest resolution for the
        // temporal type, so we must use it for both
        // the diff, and then the subsequent add
        DurationUnit unit = new DurationUnit(baseUnit, basicType(Integer.class));
        Expression magnitude = applyScale(timestampdiff().expression(null, unit, right, left));
        return timestampadd().expression(// TODO should be adjustedTimestamp.getType()
        (ReturnableType<?>) adjustedTimestampType, unit, magnitude, adjustedTimestamp);
    } else if (appliedByUnit != null) {
        // we're immediately converting the resulting
        // duration to a scalar in the given unit
        DurationUnit unit = (DurationUnit) appliedByUnit.getUnit().accept(this);
        return applyScale(timestampdiff().expression(null, unit, right, left));
    } else {
        // a plain "bare" Duration
        DurationUnit unit = new DurationUnit(baseUnit, basicType(Integer.class));
        BasicValuedMapping durationType = (BasicValuedMapping) expression.getNodeType();
        Expression scaledMagnitude = applyScale(timestampdiff().expression((ReturnableType<?>) expression.getNodeType(), unit, right, left));
        return new Duration(scaledMagnitude, baseUnit, durationType);
    }
}
Also used : BigInteger(java.math.BigInteger) BasicValuedMapping(org.hibernate.metamodel.mapping.BasicValuedMapping) BinaryArithmeticExpression(org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression) SqmModifiedSubQueryExpression(org.hibernate.query.sqm.tree.expression.SqmModifiedSubQueryExpression) SelfRenderingFunctionSqlAstExpression(org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression) SelfRenderingAggregateFunctionSqlAstExpression(org.hibernate.query.sqm.function.SelfRenderingAggregateFunctionSqlAstExpression) CaseSearchedExpression(org.hibernate.sql.ast.tree.expression.CaseSearchedExpression) SelfRenderingSqlFragmentExpression(org.hibernate.sql.ast.tree.expression.SelfRenderingSqlFragmentExpression) Expression(org.hibernate.sql.ast.tree.expression.Expression) SelfRenderingExpression(org.hibernate.sql.ast.tree.expression.SelfRenderingExpression) SqmExpression(org.hibernate.query.sqm.tree.expression.SqmExpression) CaseSimpleExpression(org.hibernate.sql.ast.tree.expression.CaseSimpleExpression) SqlSelectionExpression(org.hibernate.sql.ast.tree.expression.SqlSelectionExpression) ModifiedSubQueryExpression(org.hibernate.sql.ast.tree.expression.ModifiedSubQueryExpression) TemporalUnit(org.hibernate.query.sqm.TemporalUnit) BinaryArithmeticOperator(org.hibernate.query.sqm.BinaryArithmeticOperator) SqmDurationUnit(org.hibernate.query.sqm.tree.expression.SqmDurationUnit) DurationUnit(org.hibernate.sql.ast.tree.expression.DurationUnit) SqmToDuration(org.hibernate.query.sqm.tree.expression.SqmToDuration) Duration(org.hibernate.sql.ast.tree.expression.Duration) TypeConfiguration.isDuration(org.hibernate.type.spi.TypeConfiguration.isDuration) TypeConfiguration(org.hibernate.type.spi.TypeConfiguration) SemanticException(org.hibernate.query.SemanticException) TemporalType(jakarta.persistence.TemporalType)

Aggregations

TemporalUnit (org.hibernate.query.sqm.TemporalUnit)5 SelfRenderingFunctionSqlAstExpression (org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression)4 BinaryArithmeticExpression (org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression)4 DurationUnit (org.hibernate.sql.ast.tree.expression.DurationUnit)4 Expression (org.hibernate.sql.ast.tree.expression.Expression)4 BasicValuedMapping (org.hibernate.metamodel.mapping.BasicValuedMapping)3 SelfRenderingAggregateFunctionSqlAstExpression (org.hibernate.query.sqm.function.SelfRenderingAggregateFunctionSqlAstExpression)3 SqmDurationUnit (org.hibernate.query.sqm.tree.expression.SqmDurationUnit)3 SqmExpression (org.hibernate.query.sqm.tree.expression.SqmExpression)3 SqmModifiedSubQueryExpression (org.hibernate.query.sqm.tree.expression.SqmModifiedSubQueryExpression)3 SqmToDuration (org.hibernate.query.sqm.tree.expression.SqmToDuration)3 CaseSearchedExpression (org.hibernate.sql.ast.tree.expression.CaseSearchedExpression)3 CaseSimpleExpression (org.hibernate.sql.ast.tree.expression.CaseSimpleExpression)3 Duration (org.hibernate.sql.ast.tree.expression.Duration)3 ModifiedSubQueryExpression (org.hibernate.sql.ast.tree.expression.ModifiedSubQueryExpression)3 SelfRenderingExpression (org.hibernate.sql.ast.tree.expression.SelfRenderingExpression)3 SelfRenderingSqlFragmentExpression (org.hibernate.sql.ast.tree.expression.SelfRenderingSqlFragmentExpression)3 SqlSelectionExpression (org.hibernate.sql.ast.tree.expression.SqlSelectionExpression)3 TypeConfiguration.isDuration (org.hibernate.type.spi.TypeConfiguration.isDuration)3 SemanticException (org.hibernate.query.SemanticException)2