use of org.hibernate.sql.ast.tree.SqlAstNode in project hibernate-orm by hibernate.
the class ListaggGroupConcatEmulation method render.
@Override
public void render(SqlAppender sqlAppender, List<? extends SqlAstNode> sqlAstArguments, Predicate filter, List<SortSpecification> withinGroup, SqlAstTranslator<?> translator) {
final boolean caseWrapper = filter != null && !translator.supportsFilterClause();
sqlAppender.appendSql("group_concat(");
final SqlAstNode firstArg = sqlAstArguments.get(0);
final Expression arg;
if (firstArg instanceof Distinct) {
sqlAppender.appendSql("distinct ");
arg = ((Distinct) firstArg).getExpression();
} else {
arg = (Expression) firstArg;
}
if (caseWrapper) {
translator.getCurrentClauseStack().push(Clause.WHERE);
sqlAppender.appendSql("case when ");
filter.accept(translator);
sqlAppender.appendSql(" then ");
arg.accept(translator);
sqlAppender.appendSql(" else null end");
translator.getCurrentClauseStack().pop();
} else {
arg.accept(translator);
}
if (withinGroup != null && !withinGroup.isEmpty()) {
translator.getCurrentClauseStack().push(Clause.WITHIN_GROUP);
sqlAppender.appendSql(" order by ");
withinGroup.get(0).accept(translator);
for (int i = 1; i < withinGroup.size(); i++) {
sqlAppender.appendSql(',');
withinGroup.get(i).accept(translator);
}
translator.getCurrentClauseStack().pop();
}
if (sqlAstArguments.size() != 1) {
SqlAstNode separator = sqlAstArguments.get(1);
// group_concat doesn't support the overflow clause, so we just omit it
if (separator instanceof Overflow) {
separator = ((Overflow) separator).getSeparatorExpression();
}
sqlAppender.appendSql(" separator ");
separator.accept(translator);
}
sqlAppender.appendSql(')');
if (!caseWrapper && filter != null) {
translator.getCurrentClauseStack().push(Clause.WHERE);
sqlAppender.appendSql(" filter (where ");
filter.accept(translator);
sqlAppender.appendSql(')');
translator.getCurrentClauseStack().pop();
}
}
use of org.hibernate.sql.ast.tree.SqlAstNode in project hibernate-orm by hibernate.
the class CountFunction method render.
@Override
public void render(SqlAppender sqlAppender, List<? extends SqlAstNode> sqlAstArguments, Predicate filter, SqlAstTranslator<?> translator) {
final boolean caseWrapper = filter != null && !translator.supportsFilterClause();
final SqlAstNode arg = sqlAstArguments.get(0);
sqlAppender.appendSql("count(");
final SqlTuple tuple;
if (arg instanceof Distinct) {
sqlAppender.appendSql("distinct ");
final Expression distinctArg = ((Distinct) arg).getExpression();
if ((tuple = SqlTupleContainer.getSqlTuple(distinctArg)) != null) {
final List<? extends Expression> expressions = tuple.getExpressions();
// Single element tuple
if (expressions.size() == 1) {
renderSimpleArgument(sqlAppender, filter, translator, caseWrapper, expressions.get(0));
} else // Emulate tuple distinct count
if (!dialect.supportsTupleDistinctCounts()) {
// count(distinct coalesce(nullif(coalesce(col1 || '', '\0'), ''), '\01') || '\0' || coalesce(nullif(coalesce(col2 || '', '\0'), ''), '\02'))
if (caseWrapper) {
translator.getCurrentClauseStack().push(Clause.WHERE);
sqlAppender.appendSql("case when ");
filter.accept(translator);
sqlAppender.appendSql(" then ");
translator.getCurrentClauseStack().pop();
}
if (castDistinctStringConcat) {
sqlAppender.appendSql("cast(");
}
sqlAppender.appendSql("coalesce(nullif(coalesce(");
boolean needsConcat = renderCastedArgument(sqlAppender, translator, expressions.get(0));
int argumentNumber = 1;
for (int i = 1; i < expressions.size(); i++, argumentNumber++) {
if (needsConcat) {
// Concat with empty string to get implicit conversion
sqlAppender.appendSql(concatOperator);
sqlAppender.appendSql("''");
}
sqlAppender.appendSql(",'\\0'),''),'\\0");
sqlAppender.appendSql(argumentNumber);
sqlAppender.appendSql("')");
sqlAppender.appendSql(concatOperator);
sqlAppender.appendSql("'\\0'");
sqlAppender.appendSql(concatOperator);
sqlAppender.appendSql("coalesce(nullif(coalesce(");
needsConcat = renderCastedArgument(sqlAppender, translator, expressions.get(i));
}
if (needsConcat) {
// Concat with empty string to get implicit conversion
sqlAppender.appendSql(concatOperator);
sqlAppender.appendSql("''");
}
sqlAppender.appendSql(",'\\0'),''),'\\0");
sqlAppender.appendSql(argumentNumber);
sqlAppender.appendSql("')");
if (castDistinctStringConcat) {
sqlAppender.appendSql(" as ");
sqlAppender.appendSql(concatArgumentCastType);
sqlAppender.appendSql(')');
}
if (caseWrapper) {
sqlAppender.appendSql(" else null end");
}
} else {
renderTupleCountSupported(sqlAppender, filter, translator, caseWrapper, tuple, expressions, dialect.requiresParensForTupleDistinctCounts());
}
} else {
renderSimpleArgument(sqlAppender, filter, translator, caseWrapper, distinctArg);
}
} else {
if (canReplaceWithStar(arg, translator)) {
renderSimpleArgument(sqlAppender, filter, translator, caseWrapper, Star.INSTANCE);
} else if ((tuple = SqlTupleContainer.getSqlTuple(arg)) != null) {
final List<? extends Expression> expressions = tuple.getExpressions();
// Single element tuple
if (expressions.size() == 1) {
renderSimpleArgument(sqlAppender, filter, translator, caseWrapper, expressions.get(0));
} else // Emulate the tuple count with a case when expression
if (!dialect.supportsTupleCounts()) {
sqlAppender.appendSql("case when ");
if (caseWrapper) {
translator.getCurrentClauseStack().push(Clause.WHERE);
filter.accept(translator);
translator.getCurrentClauseStack().pop();
sqlAppender.appendSql(" and ");
}
translator.render(expressions.get(0), defaultArgumentRenderingMode);
sqlAppender.appendSql(" is not null");
for (int i = 1; i < expressions.size(); i++) {
sqlAppender.appendSql(" and ");
translator.render(expressions.get(i), defaultArgumentRenderingMode);
sqlAppender.appendSql(" is not null");
}
sqlAppender.appendSql(" then 1 else null end");
} else // Tuple counts are supported
{
renderTupleCountSupported(sqlAppender, filter, translator, caseWrapper, tuple, expressions, dialect.requiresParensForTupleCounts());
}
} else {
renderSimpleArgument(sqlAppender, filter, translator, caseWrapper, arg);
}
}
sqlAppender.appendSql(')');
if (filter != null && !caseWrapper) {
translator.getCurrentClauseStack().push(Clause.WHERE);
sqlAppender.appendSql(" filter (where ");
filter.accept(translator);
sqlAppender.appendSql(')');
translator.getCurrentClauseStack().pop();
}
}
use of org.hibernate.sql.ast.tree.SqlAstNode in project hibernate-orm by hibernate.
the class ListaggFunction method render.
@Override
public void render(SqlAppender sqlAppender, List<? extends SqlAstNode> sqlAstArguments, Predicate filter, List<SortSpecification> withinGroup, SqlAstTranslator<?> translator) {
final boolean caseWrapper = filter != null && !translator.supportsFilterClause();
sqlAppender.appendSql("listagg(");
final SqlAstNode firstArg = sqlAstArguments.get(0);
final Expression arg;
if (firstArg instanceof Distinct) {
sqlAppender.appendSql("distinct ");
arg = ((Distinct) firstArg).getExpression();
} else {
arg = (Expression) firstArg;
}
if (caseWrapper) {
sqlAppender.appendSql("case when ");
translator.getCurrentClauseStack().push(Clause.WHERE);
filter.accept(translator);
translator.getCurrentClauseStack().pop();
sqlAppender.appendSql(" then ");
arg.accept(translator);
sqlAppender.appendSql(" else null end");
} else {
arg.accept(translator);
}
if (sqlAstArguments.size() != 1) {
sqlAppender.appendSql(',');
sqlAstArguments.get(1).accept(translator);
}
sqlAppender.appendSql(')');
if (withinGroup != null && !withinGroup.isEmpty()) {
translator.getCurrentClauseStack().push(Clause.WITHIN_GROUP);
sqlAppender.appendSql(" within group (order by ");
withinGroup.get(0).accept(translator);
for (int i = 1; i < withinGroup.size(); i++) {
sqlAppender.appendSql(',');
withinGroup.get(i).accept(translator);
}
sqlAppender.appendSql(')');
translator.getCurrentClauseStack().pop();
} else if (emptyWithinReplacement != null) {
sqlAppender.appendSql(' ');
sqlAppender.appendSql(emptyWithinReplacement);
}
if (!caseWrapper && filter != null) {
translator.getCurrentClauseStack().push(Clause.WHERE);
sqlAppender.appendSql(" filter (where ");
filter.accept(translator);
sqlAppender.appendSql(')');
translator.getCurrentClauseStack().pop();
}
}
use of org.hibernate.sql.ast.tree.SqlAstNode in project hibernate-orm by hibernate.
the class SqlFunction method render.
@Override
public void render(SqlAppender sqlAppender, List<? extends SqlAstNode> arguments, SqlAstTranslator<?> walker) {
final QueryLiteral<String> sqlFragmentLiteral = (QueryLiteral<String>) arguments.get(0);
final String sqlFragment = sqlFragmentLiteral.getLiteralValue();
if (arguments.size() != 1) {
int index = 0;
for (int i = 1; i < arguments.size(); i++) {
final SqlAstNode argument = arguments.get(i);
final int paramIndex = sqlFragment.indexOf('?', index);
if (paramIndex == -1) {
throw new IllegalArgumentException("The SQL function passes an argument at index " + i + " but the fragment contains no placeholder for the argument: " + sqlFragment);
}
sqlAppender.append(sqlFragment, index, paramIndex);
argument.accept(walker);
index = paramIndex + 1;
}
} else {
sqlAppender.appendSql(sqlFragment);
}
}
use of org.hibernate.sql.ast.tree.SqlAstNode in project hibernate-orm by hibernate.
the class AnsiTrimEmulationFunctionTest method render.
private String render(Dialect dialect, TrimFunction function, TrimSpec trimSpec, char trimCharacter, String trimSource) {
SessionFactoryImplementor factory = Mockito.mock(SessionFactoryImplementor.class);
JdbcServices jdbcServices = Mockito.mock(JdbcServices.class);
Mockito.doReturn(jdbcServices).when(factory).getJdbcServices();
Mockito.doReturn(dialect).when(jdbcServices).getDialect();
StandardSqlAstTranslator<JdbcOperation> walker = new StandardSqlAstTranslator<>(factory, null);
List<SqlAstNode> sqlAstArguments = new ArrayList<>();
sqlAstArguments.add(new TrimSpecification(trimSpec));
sqlAstArguments.add(new QueryLiteral<>(trimCharacter, new BasicTypeImpl<>(CharacterJavaType.INSTANCE, CharJdbcType.INSTANCE)));
sqlAstArguments.add(new SelfRenderingExpression() {
@Override
public void renderToSql(SqlAppender sqlAppender, SqlAstTranslator<?> walker, SessionFactoryImplementor sessionFactory) {
sqlAppender.appendSql(trimSource);
}
@Override
public JdbcMappingContainer getExpressionType() {
return null;
}
});
function.render(walker, sqlAstArguments, walker);
return walker.getSql();
}
Aggregations