Value getMergedValue(Database database, boolean distinct) { if (distinct) { count = 0; groupDistinct(database); } Value v = null; switch (aggregateType) { case Aggregate.COUNT: case Aggregate.COUNT_ALL: v = ValueLong.get(count); break; case Aggregate.SUM: case Aggregate.MIN: case Aggregate.MAX: case Aggregate.BOOL_OR: case Aggregate.BOOL_AND: v = value; break; case Aggregate.AVG: case Aggregate.STDDEV_POP: case Aggregate.STDDEV_SAMP: case Aggregate.VAR_POP: case Aggregate.VAR_SAMP: return value == null ? ValueNull.INSTANCE : value; case Aggregate.SELECTIVITY: if (value != null) { v = divide(value, count); } break; case Aggregate.GROUP_CONCAT: return null; case Aggregate.HISTOGRAM: ValueArray[] values = new ValueArray[distinctValues.size()]; int i = 0; for (Value dv : distinctValues.keys()) { AggregateData d = distinctValues.get(dv); values[i] = ValueArray.get(new Value[] {dv, ValueLong.get(d.count)}); i++; } final CompareMode compareMode = database.getCompareMode(); Arrays.sort( values, new Comparator<ValueArray>() { public int compare(ValueArray v1, ValueArray v2) { Value a1 = v1.getList()[0]; Value a2 = v2.getList()[0]; return a1.compareTo(a2, compareMode); } }); v = ValueArray.get(values); break; default: DbException.throwInternalError("type=" + aggregateType); } return v == null ? ValueNull.INSTANCE : v.convertTo(dataType); }
private ValueResultSet getTable( Session session, Expression[] argList, boolean onlyColumnList, boolean distinctRows) { int len = columnList.length; Expression[] header = new Expression[len]; Database db = session.getDatabase(); for (int i = 0; i < len; i++) { Column c = columnList[i]; ExpressionColumn col = new ExpressionColumn(db, c); header[i] = col; } LocalResult result = new LocalResult(session, header, len); if (distinctRows) { result.setDistinct(); } if (!onlyColumnList) { Value[][] list = new Value[len][]; int rows = 0; for (int i = 0; i < len; i++) { Value v = argList[i].getValue(session); if (v == ValueNull.INSTANCE) { list[i] = new Value[0]; } else { ValueArray array = (ValueArray) v.convertTo(Value.ARRAY); Value[] l = array.getList(); list[i] = l; rows = Math.max(rows, l.length); } } for (int row = 0; row < rows; row++) { Value[] r = new Value[len]; for (int j = 0; j < len; j++) { Value[] l = list[j]; Value v; if (l.length <= row) { v = ValueNull.INSTANCE; } else { Column c = columnList[j]; v = l[row]; v = c.convert(v); v = v.convertPrecision(c.getPrecision(), false); v = v.convertScale(true, c.getScale()); } r[j] = v; } result.addRow(r); } } result.done(); ValueResultSet vr = ValueResultSet.get(getSimpleResultSet(result, Integer.MAX_VALUE)); return vr; }
/** * Get the aggregate result. * * @param database the database * @param distinct if distinct is used * @return the value */ Value getValue(Database database, boolean distinct) { if (distinct) { count = 0; groupDistinct(database); } Value v = null; switch (aggregateType) { case Aggregate.SELECTIVITY: { int s = 0; if (count == 0) { s = 0; } else { m2 += distinctHashes.size(); m2 = 100 * m2 / count; s = (int) m2; s = s <= 0 ? 1 : s > 100 ? 100 : s; } v = ValueInt.get(s); break; } case Aggregate.COUNT: case Aggregate.COUNT_ALL: v = ValueLong.get(count); break; case Aggregate.SUM: case Aggregate.MIN: case Aggregate.MAX: case Aggregate.BOOL_OR: case Aggregate.BOOL_AND: v = value; break; case Aggregate.AVG: if (value != null) { v = divide(value, count); } break; case Aggregate.GROUP_CONCAT: return null; case Aggregate.STDDEV_POP: { if (count < 1) { return ValueNull.INSTANCE; } v = ValueDouble.get(Math.sqrt(m2 / count)); break; } case Aggregate.STDDEV_SAMP: { if (count < 2) { return ValueNull.INSTANCE; } v = ValueDouble.get(Math.sqrt(m2 / (count - 1))); break; } case Aggregate.VAR_POP: { if (count < 1) { return ValueNull.INSTANCE; } v = ValueDouble.get(m2 / count); break; } case Aggregate.VAR_SAMP: { if (count < 2) { return ValueNull.INSTANCE; } v = ValueDouble.get(m2 / (count - 1)); break; } case Aggregate.HISTOGRAM: ValueArray[] values = new ValueArray[distinctValues.size()]; int i = 0; for (Value dv : distinctValues.keys()) { AggregateData d = distinctValues.get(dv); values[i] = ValueArray.get(new Value[] {dv, ValueLong.get(d.count)}); i++; } final CompareMode compareMode = database.getCompareMode(); Arrays.sort( values, new Comparator<ValueArray>() { public int compare(ValueArray v1, ValueArray v2) { Value a1 = v1.getList()[0]; Value a2 = v2.getList()[0]; return a1.compareTo(a2, compareMode); } }); v = ValueArray.get(values); break; default: DbException.throwInternalError("type=" + aggregateType); } return v == null ? ValueNull.INSTANCE : v.convertTo(dataType); }