org.babyfish.jimmer.sql.ast.impl.AggregationExpression Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jimmer-sql Show documentation
Show all versions of jimmer-sql Show documentation
A revolutionary ORM framework for both java and kotlin
package org.babyfish.jimmer.sql.ast.impl;
import org.babyfish.jimmer.sql.ast.Expression;
import org.babyfish.jimmer.sql.ast.PropExpression;
import org.babyfish.jimmer.sql.ast.impl.render.AbstractSqlBuilder;
import org.babyfish.jimmer.sql.ast.table.spi.PropExpressionImplementor;
import org.babyfish.jimmer.sql.meta.EmbeddedColumns;
import org.babyfish.jimmer.sql.runtime.JSqlClientImplementor;
import org.jetbrains.annotations.NotNull;
import java.math.BigDecimal;
import java.util.Objects;
abstract class AggregationExpression extends AbstractExpression {
Expression> expression;
public AggregationExpression(Expression> expression) {
this.expression = expression;
}
protected abstract String functionName();
protected String prefix() {
return null;
}
@Override
public void accept(@NotNull AstVisitor visitor) {
visitor.visitAggregation(functionName(), expression, prefix());
}
@Override
public final void renderTo(@NotNull AbstractSqlBuilder> builder) {
validate(builder.sqlClient());
builder.sql(functionName());
builder.sql("(");
String prefix = prefix();
if (prefix != null) {
builder.sql(prefix);
builder.sql(" ");
}
renderExpression(builder);
builder.sql(")");
}
@Override
protected boolean determineHasVirtualPredicate() {
return hasVirtualPredicate(expression);
}
@Override
protected Ast onResolveVirtualPredicate(AstContext ctx) {
this.expression = ctx.resolveVirtualPredicate(expression);
return this;
}
private void validate(JSqlClientImplementor sqlClient) {
if (!sqlClient.getDialect().isTupleCountSupported()) {
if (expression instanceof PropExpression>) {
PropExpressionImpl> propExpr = (PropExpressionImpl>) expression;
EmbeddedColumns.Partial partial = propExpr.getPartial(sqlClient.getMetadataStrategy());
if (partial != null && partial.size() > 1) {
throw new IllegalArgumentException(
"The `count` function does not support embedded property " +
"because multiple columns `count` is not supported by current dialect \"" +
sqlClient.getDialect().getClass().getName() +
"\""
);
}
} else if (expression instanceof TupleExpressionImplementor>) {
throw new IllegalArgumentException(
"The `count` function does not support tuple expression " +
"because multiple columns `count` is not supported by current dialect \"" +
sqlClient.getDialect().getClass().getName() +
"\""
);
}
}
}
protected void renderExpression(@NotNull AbstractSqlBuilder> builder) {
renderChild((Ast) expression, builder);
}
@Override
public int precedence() {
return 0;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AggregationExpression> that = (AggregationExpression>) o;
return expression.equals(that.expression);
}
@Override
public int hashCode() {
return Objects.hash(expression);
}
static class Count extends AggregationExpression implements NumericExpressionImplementor {
public Count(Expression> expression) {
super(expression);
}
@Override
protected String functionName() {
return "count";
}
@Override
public Class getType() {
return Long.class;
}
}
static class CountDistinct extends Count {
public CountDistinct(Expression> expression) {
super(expression);
}
@Override
protected String prefix() {
return "distinct";
}
@Override
protected void renderExpression(@NotNull AbstractSqlBuilder> builder) {
if (builder.sqlClient().getDialect().isTupleCountSupported()) {
if (expression instanceof PropExpressionImplementor>) {
((PropExpressionImplementor>) expression).renderTo(builder, true);
return;
}
if (expression instanceof TupleExpressionImplementor>) {
((TupleExpressionImplementor>) expression).renderTo(builder, true);
return;
}
}
super.renderExpression(builder);
}
}
static class Sum> extends AggregationExpression implements NumericExpressionImplementor {
public Sum(Expression> expression) {
super(expression);
}
@Override
protected String functionName() {
return "sum";
}
@SuppressWarnings("unchecked")
@Override
public Class getType() {
return (Class)((AbstractExpression>)expression).getType();
}
}
static class Min> extends AggregationExpression implements NumericExpressionImplementor {
public Min(Expression> expression) {
super(expression);
}
@Override
protected String functionName() {
return "min";
}
@SuppressWarnings("unchecked")
@Override
public Class getType() {
return (Class)((AbstractExpression>)expression).getType();
}
}
static class Max> extends AggregationExpression implements NumericExpressionImplementor {
public Max(Expression> expression) {
super(expression);
}
@Override
protected String functionName() {
return "max";
}
@SuppressWarnings("unchecked")
@Override
public Class getType() {
return (Class)((AbstractExpression>)expression).getType();
}
}
static class Avg extends AggregationExpression implements NumericExpressionImplementor {
public Avg(Expression extends Number> expression) {
super(expression);
}
@Override
protected String functionName() {
return "avg";
}
@SuppressWarnings("unchecked")
@Override
public Class getType() {
return BigDecimal.class;
}
}
}