in HSQL/src/org/hsqldb1/Expression.java [2988:3209]
Object getAggregatedValue(Session session,
Object currValue) throws HsqlException {
if (!isAggregate()) {
return currValue;
}
// handle expressions
Object leftValue = null,
rightValue = null;
switch (aggregateSpec) {
case AGGREGATE_SELF : {
// handles results of aggregates plus NEGATE and CONVERT
switch (exprType) {
case COUNT :
if (currValue == null) {
return INTEGER_0;
}
return ((SetFunction) currValue).getValue();
case MAX :
case MIN :
case SUM :
case AVG :
case EVERY :
case SOME :
case STDDEV_POP :
case STDDEV_SAMP :
case VAR_POP :
case VAR_SAMP :
if (currValue == null) {
return null;
}
return ((SetFunction) currValue).getValue();
}
}
case AGGREGATE_LEFT :
leftValue = eArg.getAggregatedValue(session,
currValue == null ? null
: ((Object[]) currValue)[0]);
if (currValue == null) {
rightValue = eArg2 == null ? null
: eArg2.getValue(session);
} else {
rightValue = ((Object[]) currValue)[1];
}
break;
case AGGREGATE_RIGHT :
if (currValue == null) {
leftValue = eArg == null ? null
: eArg.getValue(session);
} else {
leftValue = ((Object[]) currValue)[0];
}
rightValue = eArg2.getAggregatedValue(session,
currValue == null ? null
: ((Object[]) currValue)[1]);
break;
case AGGREGATE_BOTH :
if (currValue == null) {
currValue = new Object[2];
}
leftValue = eArg.getAggregatedValue(session,
((Object[]) currValue)[0]);
rightValue =
eArg2.getAggregatedValue(session,
((Object[]) currValue)[1]);
break;
}
// handle other operations
switch (exprType) {
case NEGATE :
return Column.negate(leftValue, dataType);
case CONVERT :
return Column.convertObject(session, leftValue, dataType,
precision, scale);
case TRUE :
return Boolean.TRUE;
case FALSE :
return Boolean.FALSE;
case NOT :
if (leftValue == null) {
return null;
}
return ((Boolean) leftValue).booleanValue() ? Boolean.FALSE
: Boolean.TRUE;
case AND :
if (leftValue == null || rightValue == null) {
return null;
}
return ((Boolean) leftValue).booleanValue()
&& ((Boolean) rightValue).booleanValue() ? Boolean.TRUE
: Boolean
.FALSE;
case OR :
if (Boolean.TRUE.equals(leftValue)) {
return Boolean.TRUE;
}
return Boolean.TRUE.equals(rightValue) ? Boolean.TRUE
: Boolean.FALSE;
case IS_NULL :
return leftValue == null ? Boolean.TRUE
: Boolean.FALSE;
case LIKE :
String s = (String) Column.convertObject(rightValue,
Types.VARCHAR);
if (eArg2.isParam || eArg2.exprType != VALUE) {
likeObject.resetPattern(session, s);
}
String c = (String) Column.convertObject(leftValue,
Types.VARCHAR);
return likeObject.compare(session, c);
case ALL :
case ANY :
return null;
case IN :
return eArg2.testInCondition(session, leftValue);
case EXISTS :
if (!eArg.subQuery.isResolved) {
Result r = eArg.subQuery.select.getResult(session, 1); // 1 is already enough
return r.rRoot == null ? Boolean.FALSE
: Boolean.TRUE;
} else {
return subQuery.table.isEmpty(session) ? Boolean.FALSE
: Boolean.TRUE;
}
case CASEWHEN :
leftValue = Column.convertObject(leftValue, Types.BOOLEAN);
boolean test = ((Boolean) leftValue).booleanValue();
Object result = test ? ((Object[]) rightValue)[0]
: ((Object[]) rightValue)[1];
return Column.convertObject(result, dataType);
case ALTERNATIVE :
leftValue = Column.convertObject(leftValue, dataType);
rightValue = Column.convertObject(rightValue, dataType);
Object[] objectPair = new Object[2];
objectPair[0] = leftValue;
objectPair[1] = rightValue;
return objectPair;
case FUNCTION :
return function.getAggregatedValue(session, currValue);
}
// handle comparisons
if (isCompare(exprType)) {
if (eArg2.exprType == Expression.ANY
|| eArg2.exprType == Expression.ALL) {
return testAnyAllCondition(session, leftValue);
}
return compareValues(session, leftValue, rightValue);
}
// handle arithmetic and concat operations
if (leftValue != null) {
leftValue = Column.convertObject(leftValue, dataType);
}
if (rightValue != null) {
rightValue = Column.convertObject(rightValue, dataType);
}
switch (exprType) {
case ADD :
return Column.add(leftValue, rightValue, dataType);
case SUBTRACT :
return Column.subtract(leftValue, rightValue, dataType);
case MULTIPLY :
return Column.multiply(leftValue, rightValue, dataType);
case DIVIDE :
return Column.divide(leftValue, rightValue, dataType);
case CONCAT :
return Column.concat(leftValue, rightValue);
default :
throw Trace.error(Trace.NEED_AGGREGATE,
this.describe(session));
}
}