use of org.hibernate.query.sqm.tree.expression.SqmTrimSpecification in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method visitTrimFunction.
@Override
public SqmExpression<?> visitTrimFunction(HqlParser.TrimFunctionContext ctx) {
final SqmExpression<?> source = (SqmExpression<?>) ctx.getChild(ctx.getChildCount() - 2).accept(this);
final SqmTrimSpecification trimSpec;
final SqmLiteral<Character> trimChar;
int index = 2;
ParseTree parseTree = ctx.getChild(index);
if (parseTree instanceof HqlParser.TrimSpecificationContext) {
trimSpec = visitTrimSpecification((HqlParser.TrimSpecificationContext) parseTree);
index = 3;
} else {
trimSpec = visitTrimSpecification(null);
}
parseTree = ctx.getChild(index);
if (parseTree instanceof HqlParser.TrimCharacterContext) {
trimChar = visitTrimCharacter((HqlParser.TrimCharacterContext) parseTree);
} else {
trimChar = visitTrimCharacter(null);
}
return getFunctionDescriptor("trim").generateSqmExpression(asList(trimSpec, trimChar, source), null, creationContext.getQueryEngine(), creationContext.getJpaMetamodel().getTypeConfiguration());
}
use of org.hibernate.query.sqm.tree.expression.SqmTrimSpecification in project hibernate-orm by hibernate.
the class SqmCriteriaNodeBuilder method createTrimNode.
private SqmFunction<String> createTrimNode(TrimSpec trimSpecification, SqmExpression<Character> trimCharacter, SqmExpression<String> source) {
if (trimSpecification == null) {
trimSpecification = TrimSpec.BOTH;
}
if (trimCharacter == null) {
trimCharacter = new SqmLiteral<>(' ', getTypeConfiguration().standardBasicTypeForJavaType(Character.class), this);
}
final ArrayList<SqmTypedNode<?>> arguments = new ArrayList<>(3);
arguments.add(new SqmTrimSpecification(trimSpecification, this));
arguments.add(trimCharacter);
arguments.add(source);
return getFunctionDescriptor("trim").generateSqmExpression(arguments, null, getQueryEngine(), getJpaMetamodel().getTypeConfiguration());
}
use of org.hibernate.query.sqm.tree.expression.SqmTrimSpecification in project hibernate-orm by hibernate.
the class LpadRpadPadEmulation method generateSqmFunctionExpression.
@Override
protected <T> SelfRenderingSqmFunction<T> generateSqmFunctionExpression(List<? extends SqmTypedNode<?>> arguments, ReturnableType<T> impliedResultType, QueryEngine queryEngine, TypeConfiguration typeConfiguration) {
SqmTrimSpecification padSpec = (SqmTrimSpecification) arguments.get(2);
String padName = padSpec.getSpecification() == TrimSpec.LEADING ? "lpad" : "rpad";
return queryEngine.getSqmFunctionRegistry().findFunctionDescriptor(padName).generateSqmExpression(arguments.size() > 3 ? asList(arguments.get(0), arguments.get(1), arguments.get(3)) : asList(arguments.get(0), arguments.get(1)), impliedResultType, queryEngine, typeConfiguration);
}
use of org.hibernate.query.sqm.tree.expression.SqmTrimSpecification in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method visitPadFunction.
@Override
public SqmExpression<?> visitPadFunction(HqlParser.PadFunctionContext ctx) {
final SqmExpression<?> source = (SqmExpression<?>) ctx.getChild(2).accept(this);
final SqmExpression<?> length = (SqmExpression<?>) ctx.getChild(4).accept(this);
final SqmTrimSpecification padSpec = visitPadSpecification((HqlParser.PadSpecificationContext) ctx.getChild(5));
final SqmLiteral<Character> padChar;
if (ctx.getChildCount() == 8) {
padChar = visitPadCharacter((HqlParser.PadCharacterContext) ctx.getChild(6));
} else {
padChar = null;
}
return getFunctionDescriptor("pad").generateSqmExpression(padChar != null ? asList(source, length, padSpec, padChar) : asList(source, length, padSpec), null, creationContext.getQueryEngine(), creationContext.getJpaMetamodel().getTypeConfiguration());
}
use of org.hibernate.query.sqm.tree.expression.SqmTrimSpecification 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