use of org.hibernate.query.sqm.SqmExpressible in project hibernate-orm by hibernate.
the class TypeConfiguration method resolveTupleType.
public SqmExpressible<?> resolveTupleType(List<? extends SqmTypedNode<?>> typedNodes) {
final SqmExpressible<?>[] components = new SqmExpressible<?>[typedNodes.size()];
for (int i = 0; i < typedNodes.size(); i++) {
final SqmExpressible<?> sqmExpressible = typedNodes.get(i).getNodeType();
components[i] = sqmExpressible != null ? sqmExpressible : getBasicTypeForJavaType(Object.class);
}
return arrayTuples.computeIfAbsent(new ArrayCacheKey(components), key -> new ArrayTupleType(key.components));
}
use of org.hibernate.query.sqm.SqmExpressible in project hibernate-orm by hibernate.
the class SqlTuple method createDomainResult.
@Override
public DomainResult createDomainResult(String resultVariable, DomainResultCreationState creationState) {
final JavaType javaType = ((SqmExpressible<?>) valueMapping).getExpressibleJavaType();
final int[] valuesArrayPositions = new int[expressions.size()];
for (int i = 0; i < expressions.size(); i++) {
valuesArrayPositions[i] = creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(expressions.get(i), javaType, creationState.getSqlAstCreationState().getCreationContext().getMappingMetamodel().getTypeConfiguration()).getValuesArrayPosition();
}
return new TupleResult(valuesArrayPositions, resultVariable, javaType);
}
use of org.hibernate.query.sqm.SqmExpressible in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method transformDurationArithmetic.
private Object transformDurationArithmetic(SqmBinaryArithmetic<?> expression) {
BinaryArithmeticOperator operator = expression.getOperator();
// the expression tree
switch(operator) {
case ADD:
case SUBTRACT:
// the only legal binary operations involving
// a duration with a date or timestamp are
// addition and subtraction with the duration
// on the right and the date or timestamp on
// the left, producing a date or timestamp
//
// ts + d or ts - d
//
// the only legal binary operations involving
// two durations are addition and subtraction,
// producing a duration
//
// d1 + d2
// re-express addition of non-leaf duration
// expressions to a date or timestamp as
// addition of leaf durations to a date or
// timestamp
// ts + x * (d1 + d2) => (ts + x * d1) + x * d2
// ts - x * (d1 + d2) => (ts - x * d1) - x * d2
// ts + x * (d1 - d2) => (ts + x * d1) - x * d2
// ts - x * (d1 - d2) => (ts - x * d1) + x * d2
Expression timestamp = adjustedTimestamp;
SqmExpressible<?> timestampType = adjustedTimestampType;
adjustedTimestamp = toSqlExpression(expression.getLeftHandOperand().accept(this));
JdbcMappingContainer type = adjustedTimestamp.getExpressionType();
if (type instanceof SqmExpressible) {
adjustedTimestampType = (SqmExpressible<?>) type;
} else if (type instanceof AttributeMapping) {
adjustedTimestampType = (SqmExpressible<?>) ((AttributeMapping) type).getMappedType();
} else {
// else we know it has not been transformed
adjustedTimestampType = expression.getLeftHandOperand().getNodeType();
}
if (operator == SUBTRACT) {
negativeAdjustment = !negativeAdjustment;
}
try {
return expression.getRightHandOperand().accept(this);
} finally {
if (operator == SUBTRACT) {
negativeAdjustment = !negativeAdjustment;
}
adjustedTimestamp = timestamp;
adjustedTimestampType = timestampType;
}
case MULTIPLY:
// finally, we can multiply a duration on the
// right by a scalar value on the left
// scalar multiplication produces a duration
// x * d
// distribute scalar multiplication over the
// terms, not forgetting the propagated scale
// x * (d1 + d2) => x * d1 + x * d2
// x * (d1 - d2) => x * d1 - x * d2
// -x * (d1 + d2) => - x * d1 - x * d2
// -x * (d1 - d2) => - x * d1 + x * d2
Expression duration = toSqlExpression(expression.getLeftHandOperand().accept(this));
Expression scale = adjustmentScale;
boolean negate = negativeAdjustment;
adjustmentScale = applyScale(duration);
// was sucked into the scale
negativeAdjustment = false;
try {
return expression.getRightHandOperand().accept(this);
} finally {
adjustmentScale = scale;
negativeAdjustment = negate;
}
default:
throw new SemanticException("illegal operator for a duration " + operator);
}
}
use of org.hibernate.query.sqm.SqmExpressible in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method determineValueMapping.
private MappingModelExpressible<?> determineValueMapping(SqmExpression<?> sqmExpression, FromClauseIndex fromClauseIndex) {
if (sqmExpression instanceof SqmParameter) {
return determineValueMapping((SqmParameter<?>) sqmExpression);
} else if (sqmExpression instanceof SqmPath) {
log.debugf("Determining mapping-model type for SqmPath : %s ", sqmExpression);
final MappingMetamodel domainModel = creationContext.getSessionFactory().getRuntimeMetamodels().getMappingMetamodel();
return SqmMappingModelHelper.resolveMappingModelExpressible(sqmExpression, domainModel, fromClauseIndex::findTableGroup);
} else // The model type of an enum literal is always inferred
if (sqmExpression instanceof SqmEnumLiteral<?>) {
final MappingModelExpressible<?> mappingModelExpressible = resolveInferredType();
if (mappingModelExpressible != null) {
return mappingModelExpressible;
}
} else if (sqmExpression instanceof SqmSubQuery<?>) {
final SqmSubQuery<?> subQuery = (SqmSubQuery<?>) sqmExpression;
final SqmSelectClause selectClause = subQuery.getQuerySpec().getSelectClause();
if (selectClause.getSelections().size() == 1) {
final SqmSelection<?> subQuerySelection = selectClause.getSelections().get(0);
final SqmSelectableNode<?> selectableNode = subQuerySelection.getSelectableNode();
if (selectableNode instanceof SqmExpression<?>) {
return determineValueMapping((SqmExpression<?>) selectableNode, fromClauseIndex);
}
final SqmExpressible<?> selectionNodeType = subQuerySelection.getNodeType();
if (selectionNodeType != null) {
final MappingMetamodel domainModel = creationContext.getSessionFactory().getRuntimeMetamodels().getMappingMetamodel();
final MappingModelExpressible<?> expressible = domainModel.resolveMappingExpressible(selectionNodeType, this::findTableGroupByPath);
if (expressible != null) {
return expressible;
}
try {
final MappingModelExpressible<?> mappingModelExpressible = resolveInferredType();
if (mappingModelExpressible != null) {
return mappingModelExpressible;
}
} catch (Exception ignore) {
return null;
}
}
}
}
log.debugf("Determining mapping-model type for generalized SqmExpression : %s", sqmExpression);
final SqmExpressible<?> nodeType = sqmExpression.getNodeType();
if (nodeType == null) {
// We can't determine the type of the expression
return null;
}
final MappingMetamodel domainModel = creationContext.getSessionFactory().getRuntimeMetamodels().getMappingMetamodel();
final MappingModelExpressible<?> valueMapping = domainModel.resolveMappingExpressible(nodeType, fromClauseIndex::getTableGroup);
if (valueMapping == null) {
final MappingModelExpressible<?> mappingModelExpressible = resolveInferredType();
if (mappingModelExpressible != null) {
return mappingModelExpressible;
}
}
if (valueMapping == null) {
// For literals it is totally possible that we can't figure out a mapping type
if (sqmExpression instanceof SqmLiteral<?>) {
return null;
}
throw new ConversionException("Could not determine ValueMapping for SqmExpression: " + sqmExpression);
}
return valueMapping;
}
Aggregations