use of org.h2.value.ValueArray in project h2database by h2database.
the class Aggregate method getValue.
@Override
public Value getValue(Session session) {
if (select.isQuickAggregateQuery()) {
switch(type) {
case COUNT:
case COUNT_ALL:
Table table = select.getTopTableFilter().getTable();
return ValueLong.get(table.getRowCount(session));
case MIN:
case MAX:
{
boolean first = type == AggregateType.MIN;
Index index = getMinMaxColumnIndex();
int sortType = index.getIndexColumns()[0].sortType;
if ((sortType & SortOrder.DESCENDING) != 0) {
first = !first;
}
Cursor cursor = index.findFirstOrLast(session, first);
SearchRow row = cursor.getSearchRow();
Value v;
if (row == null) {
v = ValueNull.INSTANCE;
} else {
v = row.getValue(index.getColumns()[0].getColumnId());
}
return v;
}
case MEDIAN:
{
return AggregateDataMedian.getResultFromIndex(session, on, dataType);
}
default:
DbException.throwInternalError("type=" + type);
}
}
HashMap<Expression, Object> group = select.getCurrentGroup();
if (group == null) {
throw DbException.get(ErrorCode.INVALID_USE_OF_AGGREGATE_FUNCTION_1, getSQL());
}
AggregateData data = (AggregateData) group.get(this);
if (data == null) {
data = AggregateData.create(type);
}
if (type == AggregateType.GROUP_CONCAT) {
Value[] array = ((AggregateDataCollecting) data).getArray();
if (array == null) {
return ValueNull.INSTANCE;
}
if (orderByList != null || distinct) {
sortWithOrderBy(array);
}
StatementBuilder buff = new StatementBuilder();
String sep = groupConcatSeparator == null ? "," : groupConcatSeparator.getValue(session).getString();
for (Value val : array) {
String s;
if (val.getType() == Value.ARRAY) {
s = ((ValueArray) val).getList()[0].getString();
} else {
s = val.getString();
}
if (s == null) {
continue;
}
if (sep != null) {
buff.appendExceptFirst(sep);
}
buff.append(s);
}
return ValueString.get(buff.toString());
} else if (type == AggregateType.ARRAY_AGG) {
Value[] array = ((AggregateDataCollecting) data).getArray();
if (array == null) {
return ValueNull.INSTANCE;
}
if (orderByList != null || distinct) {
sortWithOrderBy(array);
}
if (orderByList != null) {
for (int i = 0; i < array.length; i++) {
array[i] = ((ValueArray) array[i]).getList()[0];
}
}
return ValueArray.get(array);
}
return data.getValue(session.getDatabase(), dataType, distinct);
}
use of org.h2.value.ValueArray in project h2database by h2database.
the class AggregateDataHistogram method getValue.
@Override
Value getValue(Database database, int dataType, boolean distinct) {
if (distinct) {
count = 0;
groupDistinct(database, dataType);
}
ValueArray[] values = new ValueArray[distinctValues.size()];
int i = 0;
for (Value dv : distinctValues.keys()) {
AggregateDataHistogram 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>() {
@Override
public int compare(ValueArray v1, ValueArray v2) {
Value a1 = v1.getList()[0];
Value a2 = v2.getList()[0];
return a1.compareTo(a2, compareMode);
}
});
Value v = ValueArray.get(values);
return v.convertTo(dataType);
}
use of org.h2.value.ValueArray in project h2database by h2database.
the class MVSecondaryIndex method find.
private Cursor find(Session session, SearchRow first, boolean bigger, SearchRow last) {
ValueArray min = convertToKey(first);
if (min != null) {
min.getList()[keyColumns - 1] = ValueLong.MIN;
}
TransactionMap<Value, Value> map = getMap(session);
if (bigger && min != null) {
// search for the next: first skip 1, then 2, 4, 8, until
// we have a higher key; then skip 4, 2,...
// (binary search), until 1
int offset = 1;
while (true) {
ValueArray v = (ValueArray) map.relativeKey(min, offset);
if (v != null) {
boolean foundHigher = false;
for (int i = 0; i < keyColumns - 1; i++) {
int idx = columnIds[i];
Value b = first.getValue(idx);
if (b == null) {
break;
}
Value a = v.getList()[i];
if (database.compare(a, b) > 0) {
foundHigher = true;
break;
}
}
if (!foundHigher) {
offset += offset;
min = v;
continue;
}
}
if (offset > 1) {
offset /= 2;
continue;
}
if (map.get(v) == null) {
min = (ValueArray) map.higherKey(min);
if (min == null) {
break;
}
continue;
}
min = v;
break;
}
if (min == null) {
return new MVStoreCursor(session, Collections.<Value>emptyList().iterator(), null);
}
}
return new MVStoreCursor(session, map.keyIterator(min), last);
}
use of org.h2.value.ValueArray in project h2database by h2database.
the class MVSecondaryIndex method addBufferedRows.
@Override
public void addBufferedRows(List<String> bufferNames) {
ArrayList<String> mapNames = new ArrayList<>(bufferNames);
CompareMode compareMode = database.getCompareMode();
int buffersCount = bufferNames.size();
Queue<Source> queue = new PriorityQueue<>(buffersCount, new Source.Comparator(compareMode));
for (String bufferName : bufferNames) {
Iterator<ValueArray> iter = openMap(bufferName).keyIterator(null);
if (iter.hasNext()) {
queue.add(new Source(iter));
}
}
try {
while (!queue.isEmpty()) {
Source s = queue.remove();
ValueArray rowData = s.next();
if (indexType.isUnique()) {
Value[] array = rowData.getList();
// don't change the original value
array = array.clone();
array[keyColumns - 1] = ValueLong.MIN;
ValueArray unique = ValueArray.get(array);
SearchRow row = convertToSearchRow(rowData);
if (!mayHaveNullDuplicates(row)) {
requireUnique(row, dataMap, unique);
}
}
dataMap.putCommitted(rowData, ValueNull.INSTANCE);
if (s.hasNext()) {
queue.offer(s);
}
}
} finally {
for (String tempMapName : mapNames) {
MVMap<ValueArray, Value> map = openMap(tempMapName);
map.getStore().removeMap(map);
}
}
}
use of org.h2.value.ValueArray in project h2database by h2database.
the class MVSecondaryIndex method convertToSearchRow.
/**
* Convert array of values to a SearchRow.
*
* @param key the index key
* @return the row
*/
SearchRow convertToSearchRow(ValueArray key) {
Value[] array = key.getList();
SearchRow searchRow = mvTable.getTemplateRow();
searchRow.setKey((array[array.length - 1]).getLong());
Column[] cols = getColumns();
for (int i = 0; i < array.length - 1; i++) {
Column c = cols[i];
int idx = c.getColumnId();
Value v = array[i];
searchRow.setValue(idx, v);
}
return searchRow;
}
Aggregations