use of mondrian.calc.TupleList in project mondrian by pentaho.
the class SqlConstraintUtils method expandSetFromCalculatedMember.
public static void expandSetFromCalculatedMember(Evaluator evaluator, Member member, TupleConstraintStruct expandedSet) {
assert member.getExpression() instanceof ResolvedFunCall;
ResolvedFunCall fun = (ResolvedFunCall) member.getExpression();
// Calling the main set evaluator to extend this.
Exp exp = fun.getArg(0);
TupleIterable tupleIterable = evaluator.getSetEvaluator(exp, true).evaluateTupleIterable();
Iterator<List<Member>> tupleIterator = tupleIterable.iterator();
TupleList tupleList = TupleCollections.materialize(tupleIterable, false);
boolean disjointSlicerTuple = false;
if (tupleList != null) {
disjointSlicerTuple = SqlConstraintUtils.isDisjointTuple(tupleList);
}
if (disjointSlicerTuple) {
if (!tupleList.isEmpty()) {
expandedSet.addTupleList(tupleList);
}
} else {
while (tupleIterator.hasNext()) {
expandedSet.addMembers(tupleIterator.next());
}
}
}
use of mondrian.calc.TupleList in project mondrian by pentaho.
the class SqlTupleReader method projectTupleList.
/**
* Projects the attributes using the original ordering in targets, then
* copies to a ArrayTupleList (the .project method returns a basic TupleList
* without support for methods like .remove, which may be needed downstream).
*/
private TupleList projectTupleList(TupleList tupleList) {
tupleList = tupleList.project(getLevelIndices(tupleList, targets));
TupleList arrayTupleList = new ArrayTupleList(tupleList.getArity(), tupleList.size());
arrayTupleList.addAll(tupleList);
return arrayTupleList;
}
use of mondrian.calc.TupleList in project mondrian by pentaho.
the class SqlTupleReader method prepareTuples.
protected void prepareTuples(DataSource dataSource, TupleList partialResult, List<List<RolapMember>> newPartialResult, List<TargetBase> targetGroup) {
String message = "Populating member cache with members for " + targetGroup;
SqlStatement stmt = null;
final ResultSet resultSet;
boolean execQuery = (partialResult == null);
try {
if (execQuery) {
// we're only reading tuples from the targets that are
// non-enum targets
List<TargetBase> partialTargets = new ArrayList<TargetBase>();
for (TargetBase target : targetGroup) {
if (target.srcMembers == null) {
partialTargets.add(target);
}
}
final Pair<String, List<SqlStatement.Type>> pair = makeLevelMembersSql(dataSource, targetGroup);
String sql = pair.left;
List<SqlStatement.Type> types = pair.right;
assert sql != null && !sql.equals("");
stmt = RolapUtil.executeQuery(dataSource, sql, types, maxRows, 0, new SqlStatement.StatementLocus(Locus.peek().execution, "SqlTupleReader.readTuples " + partialTargets, message, SqlStatementEvent.Purpose.TUPLES, 0), -1, -1, null);
resultSet = stmt.getResultSet();
} else {
resultSet = null;
}
for (TargetBase target : targetGroup) {
target.open();
}
int limit = MondrianProperties.instance().ResultLimit.get();
int fetchCount = 0;
// determine how many enum targets we have
int enumTargetCount = getEnumTargetCount();
int[] srcMemberIdxes = null;
if (enumTargetCount > 0) {
srcMemberIdxes = new int[enumTargetCount];
}
boolean moreRows;
int currPartialResultIdx = 0;
if (execQuery) {
moreRows = resultSet.next();
if (moreRows) {
++stmt.rowCount;
}
} else {
moreRows = currPartialResultIdx < partialResult.size();
}
Execution execution = Locus.peek().execution;
while (moreRows) {
// Check if the MDX query was canceled.
CancellationChecker.checkCancelOrTimeout(stmt.rowCount, execution);
if (limit > 0 && limit < ++fetchCount) {
// result limit exceeded, throw an exception
throw MondrianResource.instance().MemberFetchLimitExceeded.ex((long) limit);
}
if (enumTargetCount == 0) {
int column = 0;
for (TargetBase target : targetGroup) {
target.setCurrMember(null);
column = target.addRow(stmt, column);
}
} else {
// find the first enum target, then call addTargets()
// to form the cross product of the row from resultSet
// with each of the list of members corresponding to
// the enumerated targets
int firstEnumTarget = 0;
for (; firstEnumTarget < targetGroup.size(); firstEnumTarget++) {
if (targetGroup.get(firstEnumTarget).srcMembers != null) {
break;
}
}
List<RolapMember> partialRow;
if (execQuery) {
partialRow = null;
} else {
partialRow = Util.cast(partialResult.get(currPartialResultIdx));
}
resetCurrMembers(partialRow);
addTargets(0, firstEnumTarget, enumTargetCount, srcMemberIdxes, stmt, message);
if (newPartialResult != null) {
savePartialResult(newPartialResult);
}
}
if (execQuery) {
moreRows = resultSet.next();
if (moreRows) {
++stmt.rowCount;
}
} else {
currPartialResultIdx++;
moreRows = currPartialResultIdx < partialResult.size();
}
}
} catch (SQLException e) {
if (stmt == null) {
throw Util.newError(e, message);
} else {
throw stmt.handle(e);
}
} finally {
if (stmt != null) {
stmt.close();
}
}
}
use of mondrian.calc.TupleList in project mondrian by pentaho.
the class SqlTupleReader method readTuples.
public TupleList readTuples(DataSource jdbcConnection, TupleList partialResult, List<List<RolapMember>> newPartialResult) {
// The following algorithm will first group targets based on the cubes
// that are applicable to each. This allows loading the tuple data
// in groups that join correctly to the associated fact table.
// Once each group has been loaded, results of each are
// brought together in a crossjoin, and then projected into a new
// tuple list based on the ordering originally specified by the
// targets list.
// For non-virtual cube queries there is only a single
// targetGroup.
List<List<TargetBase>> targetGroups = groupTargets(targets, constraint.getEvaluator().getQuery());
List<TupleList> tupleLists = new ArrayList<>();
for (List<TargetBase> targetGroup : targetGroups) {
prepareTuples(jdbcConnection, partialResult, newPartialResult, targetGroup);
int size = targetGroup.size();
final Iterator<Member>[] iter = new Iterator[size];
for (int i = 0; i < size; i++) {
TargetBase t = targetGroup.get(i);
iter[i] = t.close().iterator();
}
List<Member> members = new ArrayList<>();
while (iter[0].hasNext()) {
for (int i = 0; i < size; i++) {
members.add(iter[i].next());
}
}
tupleLists.add(size + emptySets == 1 ? new UnaryTupleList(members) : new ListTupleList(size + emptySets, members));
}
if (tupleLists.isEmpty()) {
return TupleCollections.emptyList(targets.size());
}
TupleList tupleList = CrossJoinFunDef.mutableCrossJoin(tupleLists);
if (!tupleList.isEmpty() && targetGroups.size() > 1) {
tupleList = projectTupleList(tupleList);
}
// need to hierarchize the columns from the enumerated targets
// since we didn't necessarily add them in the order in which
// they originally appeared in the cross product
int enumTargetCount = getEnumTargetCount();
if (enumTargetCount > 0) {
tupleList = FunUtil.hierarchizeTupleList(tupleList, false);
}
return tupleList;
}
use of mondrian.calc.TupleList in project mondrian by pentaho.
the class ModulosTest method testThree.
public void testThree() {
Axis[] axes = new Axis[3];
TupleList positions = newPositionList(4);
axes[0] = new RolapAxis(positions);
positions = newPositionList(3);
axes[1] = new RolapAxis(positions);
positions = newPositionList(2);
axes[2] = new RolapAxis(positions);
Modulos modulosMany = Modulos.Generator.createMany(axes);
Modulos modulos = Modulos.Generator.create(axes);
int ordinal = 23;
int[] posMany = modulosMany.getCellPos(ordinal);
int[] pos = modulos.getCellPos(ordinal);
assertTrue("Pos are not equal", Arrays.equals(posMany, pos));
ordinal = 11;
posMany = modulosMany.getCellPos(ordinal);
pos = modulos.getCellPos(ordinal);
assertTrue("Pos are not equal", Arrays.equals(posMany, pos));
ordinal = 7;
posMany = modulosMany.getCellPos(ordinal);
pos = modulos.getCellPos(ordinal);
assertTrue("Pos are not equal", Arrays.equals(posMany, pos));
pos[0] = 3;
pos[1] = 2;
pos[2] = 1;
int oMany = modulosMany.getCellOrdinal(pos);
int o = modulos.getCellOrdinal(pos);
assertTrue("Ordinals are not equal", oMany == o);
pos[0] = 2;
oMany = modulosMany.getCellOrdinal(pos);
o = modulos.getCellOrdinal(pos);
assertTrue("Ordinals are not equal", oMany == o);
pos[0] = 1;
oMany = modulosMany.getCellOrdinal(pos);
o = modulos.getCellOrdinal(pos);
assertTrue("Ordinals are not equal", oMany == o);
}
Aggregations