use of org.hibernate.query.sqm.tree.expression.SqmExtractUnit in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method visitGenericFunctionArguments.
@Override
public List<SqmTypedNode<?>> visitGenericFunctionArguments(HqlParser.GenericFunctionArgumentsContext ctx) {
final int size = ctx.getChildCount();
final int lastIndex = size - 1;
// Shift 1 bit instead of division by 2
final int estimateArgumentCount = size >> 1;
final List<SqmTypedNode<?>> arguments = new ArrayList<>(estimateArgumentCount);
int i = 0;
boolean distinct = false;
final ParseTree firstChild = ctx.getChild(0);
if (firstChild instanceof HqlParser.DatetimeFieldContext) {
arguments.add(toDurationUnit((SqmExtractUnit<?>) firstChild.accept(this)));
i += 2;
} else if (firstChild instanceof TerminalNode) {
distinct = true;
i++;
}
for (; i < size; i += 2) {
// we handle the final argument differently...
if (i == lastIndex) {
arguments.add(visitFinalFunctionArgument(ctx.getChild(i)));
} else {
arguments.add((SqmTypedNode<?>) ctx.getChild(i).accept(this));
}
}
if (distinct) {
final NodeBuilder nodeBuilder = getCreationContext().getNodeBuilder();
if (arguments.size() == 1) {
arguments.set(0, new SqmDistinct<>((SqmExpression<?>) arguments.get(0), nodeBuilder));
} else {
final List<SqmTypedNode<?>> newArguments = new ArrayList<>(1);
// noinspection unchecked
newArguments.add(new SqmDistinct<>(new SqmTuple<>((List<SqmExpression<?>>) (List<?>) arguments, nodeBuilder), nodeBuilder));
return newArguments;
}
}
return arguments;
}
use of org.hibernate.query.sqm.tree.expression.SqmExtractUnit in project hibernate-orm by hibernate.
the class ArgumentTypesValidator method validate.
/**
* We do an initial validation phase with just the SQM tree, even though we don't
* have all typing information available here (in particular, we don't have the
* final JDBC type codes for things with converters) because this is the phase
* that is run at startup for named queries, and can be done in an IDE.
*/
@Override
public void validate(List<? extends SqmTypedNode<?>> arguments, String functionName, QueryEngine queryEngine) {
delegate.validate(arguments, functionName, queryEngine);
int count = 0;
for (SqmTypedNode<?> argument : arguments) {
JdbcTypeIndicators indicators = queryEngine.getTypeConfiguration().getCurrentBaseSqlTypeIndicators();
SqmExpressible<?> nodeType = argument.getNodeType();
FunctionParameterType type = count < types.length ? types[count++] : types[types.length - 1];
if (nodeType != null) {
JavaType<?> javaType = nodeType.getExpressibleJavaType();
if (javaType != null) {
try {
JdbcType jdbcType = javaType.getRecommendedJdbcType(indicators);
checkType(count, functionName, type, jdbcType.getJdbcTypeCode(), javaType.getJavaTypeClass());
} catch (JdbcTypeRecommendationException e) {
// it's a converter or something like that, and we will check it later
}
}
switch(type) {
case TEMPORAL_UNIT:
if (!(argument instanceof SqmExtractUnit) && !(argument instanceof SqmDurationUnit)) {
throwError(type, Object.class, functionName, count);
}
break;
// something crazy by the parser
case TRIM_SPEC:
if (!(argument instanceof SqmTrimSpecification)) {
throwError(type, Object.class, functionName, count);
}
break;
case COLLATION:
if (!(argument instanceof SqmCollation)) {
throwError(type, Object.class, functionName, count);
}
break;
}
} else {
// TODO: appropriate error?
}
}
}
Aggregations