![JAR search and dependency download from the Maven repository](/logo.png)
org.h2.command.query.SelectGroups Maven / Gradle / Ivy
/*
* Copyright 2004-2021 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (https://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.command.query;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import org.h2.engine.SessionLocal;
import org.h2.expression.Expression;
import org.h2.expression.analysis.DataAnalysisOperation;
import org.h2.expression.analysis.PartitionData;
import org.h2.value.Value;
import org.h2.value.ValueRow;
/**
* Grouped data for aggregates.
*
*
* Call sequence:
*
*
* - {@link #reset()}.
* - For each source row {@link #nextSource()} should be invoked.
* - {@link #done()}.
* - {@link #next()} is invoked inside a loop until it returns null.
*
*
* Call sequence for lazy group sorted result:
*
*
* - {@link #resetLazy()} (not required before the first execution).
* - For each source group {@link #nextLazyGroup()} should be invoked.
* - For each source row {@link #nextLazyRow()} should be invoked. Each group
* can have one or more rows.
*
*/
public abstract class SelectGroups {
private static final class Grouped extends SelectGroups {
private final int[] groupIndex;
/**
* Map of group-by key to group-by expression data e.g. AggregateData
*/
private TreeMap groupByData;
/**
* Key into groupByData that produces currentGroupByExprData. Not used
* in lazy mode.
*/
private ValueRow currentGroupsKey;
/**
* Cursor for {@link #next()} method.
*/
private Iterator> cursor;
Grouped(SessionLocal session, ArrayList expressions, int[] groupIndex) {
super(session, expressions);
this.groupIndex = groupIndex;
}
@Override
public void reset() {
super.reset();
groupByData = new TreeMap<>(session.getDatabase().getCompareMode());
currentGroupsKey = null;
cursor = null;
}
@Override
public void nextSource() {
if (groupIndex == null) {
currentGroupsKey = ValueRow.EMPTY;
} else {
Value[] keyValues = new Value[groupIndex.length];
// update group
for (int i = 0; i < groupIndex.length; i++) {
int idx = groupIndex[i];
Expression expr = expressions.get(idx);
keyValues[i] = expr.getValue(session);
}
currentGroupsKey = ValueRow.get(keyValues);
}
Object[] values = groupByData.get(currentGroupsKey);
if (values == null) {
values = createRow();
groupByData.put(currentGroupsKey, values);
}
currentGroupByExprData = values;
currentGroupRowId++;
}
@Override
void updateCurrentGroupExprData() {
// this can be null in lazy mode
if (currentGroupsKey != null) {
// since we changed the size of the array, update the object in
// the groups map
groupByData.put(currentGroupsKey, currentGroupByExprData);
}
}
@Override
public void done() {
super.done();
if (groupIndex == null && groupByData.size() == 0) {
groupByData.put(ValueRow.EMPTY, createRow());
}
cursor = groupByData.entrySet().iterator();
}
@Override
public ValueRow next() {
if (cursor.hasNext()) {
Map.Entry entry = cursor.next();
currentGroupByExprData = entry.getValue();
currentGroupRowId++;
return entry.getKey();
}
return null;
}
@Override
public void remove() {
cursor.remove();
currentGroupByExprData = null;
currentGroupRowId--;
}
@Override
public void resetLazy() {
super.resetLazy();
currentGroupsKey = null;
}
}
private static final class Plain extends SelectGroups {
private ArrayList
© 2015 - 2025 Weber Informatics LLC | Privacy Policy