use of mondrian.calc.TupleList in project mondrian by pentaho.
the class HighCardSqlTupleReader method prepareTuples.
protected void prepareTuples(final DataSource dataSource, final TupleList partialResult, final List<List<RolapMember>> newPartialResult, final List<TargetBase> targetGroup) {
String message = "Populating member cache with members for " + targets;
SqlStatement stmt = null;
boolean execQuery = (partialResult == null);
boolean success = false;
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 : targets) {
if (target.getSrcMembers() == null) {
partialTargets.add(target);
}
}
final Pair<String, List<SqlStatement.Type>> pair = makeLevelMembersSql(dataSource, targetGroup);
String sql = pair.left;
List<SqlStatement.Type> types = pair.right;
stmt = RolapUtil.executeQuery(dataSource, sql, types, maxRows, 0, new SqlStatement.StatementLocus(Locus.peek().execution, "HighCardSqlTupleReader.readTuples " + partialTargets, message, SqlStatementEvent.Purpose.TUPLES, 0), -1, -1, null);
}
for (TargetBase target : targets) {
target.open();
}
// determine how many enum targets we have
int enumTargetCount = getEnumTargetCount();
int currPartialResultIdx = 0;
if (execQuery) {
this.moreRows = stmt.getResultSet().next();
if (this.moreRows) {
++stmt.rowCount;
}
} else {
this.moreRows = currPartialResultIdx < partialResult.size();
}
this.resultLoader = new ResultLoader(enumTargetCount, targets, stmt, execQuery, partialResult, newPartialResult);
// Read first and second elements if exists (or marks
// source as having "no more rows")
readNextTuple();
readNextTuple();
success = true;
} catch (SQLException sqle) {
if (stmt != null) {
throw stmt.handle(sqle);
} else {
throw Util.newError(sqle, message);
}
} finally {
if (!moreRows || !success) {
if (stmt != null) {
stmt.close();
}
}
}
}
use of mondrian.calc.TupleList in project mondrian by pentaho.
the class HighCardSqlTupleReader method readTuples.
public TupleList readTuples(final DataSource jdbcConnection, final TupleList partialResult, final List<List<RolapMember>> newPartialResult) {
prepareTuples(jdbcConnection, partialResult, newPartialResult, targets);
// List of tuples
final int n = targets.size();
@SuppressWarnings({ "unchecked" }) final List<Member>[] lists = new List[n];
for (int i = 0; i < n; i++) {
lists[i] = targets.get(i).close();
}
final List<List<Member>> list = new TraversalList<Member>(lists, Member.class);
TupleList tupleList = new DelegatingTupleList(n, list);
// 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 TupleListTest method testDelegatingTupleList.
public void testDelegatingTupleList() {
final Member genderFMember = xxx("[Gender].[F]");
final Member genderMMember = xxx("[Gender].[M]");
final Member storeUsaMember = xxx("[Store].[USA]");
final List<List<Member>> arrayList = new ArrayList<List<Member>>();
TupleList fm = new DelegatingTupleList(2, arrayList);
fm.addTuple(genderFMember, storeUsaMember);
fm.addTuple(genderMMember, storeUsaMember);
assertEquals(2, fm.size());
assertEquals(2, fm.getArity());
assertEquals("[[[Gender].[F], [Store].[USA]], [[Gender].[M], [Store].[USA]]]", fm.toString());
checkProject(fm);
}
use of mondrian.calc.TupleList in project mondrian by pentaho.
the class TupleListTest method testUnaryTupleList.
public void testUnaryTupleList() {
// empty list
final TupleList list0 = new UnaryTupleList();
assertTrue(list0.isEmpty());
assertEquals(0, list0.size());
assertEquals(list0, TupleCollections.emptyList(1));
TupleList list1 = new UnaryTupleList();
assertEquals(list0, list1);
final Member storeUsaMember = xxx("[Store].[USA]");
list1.add(Collections.singletonList(storeUsaMember));
assertFalse(list1.isEmpty());
assertEquals(1, list1.size());
assertNotSame(list0, list1);
TupleList list2 = new UnaryTupleList();
list2.addTuple(new Member[] { storeUsaMember });
assertFalse(list2.isEmpty());
assertEquals(1, list2.size());
assertEquals(list1, list2);
list2.clear();
assertEquals(list0, list2);
assertEquals(list2, list0);
// For various lists, sublist returns the whole thing.
for (TupleList list : Arrays.asList(list0, list1, list2)) {
assertEquals(list, list.subList(0, list.size()));
assertNotSame(list, list.subList(0, list.size()));
}
// Null members OK (at least for TupleList).
list1.addTuple(new Member[] { null });
list1.add(Collections.<Member>singletonList(null));
}
use of mondrian.calc.TupleList in project mondrian by pentaho.
the class SqlConstraintUtils method addContextConstraint.
/**
* For every restricting member in the current context, generates
* a WHERE condition and a join to the fact table.
*
* @param sqlQuery the query to modify
* @param aggStar Aggregate table, or null if query is against fact table
* @param restrictMemberTypes defines the behavior if the current context
* contains calculated members. If true, thows an exception.
* @param evaluator Evaluator
*/
public static void addContextConstraint(SqlQuery sqlQuery, AggStar aggStar, Evaluator evaluator, RolapCube baseCube, boolean restrictMemberTypes) {
if (baseCube == null && evaluator instanceof RolapEvaluator) {
baseCube = ((RolapEvaluator) evaluator).getCube();
}
RolapEvaluator rEvaluator = (RolapEvaluator) evaluator;
// decide if we should use the tuple-based version instead
TupleList slicerTuples = rEvaluator.getOptimizedSlicerTuples(baseCube);
boolean disjointSlicerTuples = false;
if (slicerTuples != null && slicerTuples.size() > 0 && (SqlConstraintUtils.isDisjointTuple(slicerTuples) || rEvaluator.isMultiLevelSlicerTuple())) {
disjointSlicerTuples = true;
}
TupleConstraintStruct expandedSet = makeContextConstraintSet(rEvaluator, restrictMemberTypes, disjointSlicerTuples);
final CellRequest request = RolapAggregationManager.makeRequest(expandedSet.getMembersArray());
if (request == null) {
if (restrictMemberTypes) {
throw Util.newInternal("CellRequest is null - why?");
}
// request is impossible to satisfy.
return;
}
List<TupleList> slicerTupleList = expandedSet.getDisjoinedTupleLists();
if (disjointSlicerTuples) {
slicerTupleList.add(slicerTuples);
}
// add slicer tuples from the expanded members
if (slicerTupleList.size() > 0) {
LOG.warn("Using tuple-based native slicer.");
for (TupleList tuple : slicerTupleList) {
addContextConstraintTuples(sqlQuery, aggStar, rEvaluator, baseCube, restrictMemberTypes, request, tuple);
}
return;
}
RolapStar.Column[] columns = request.getConstrainedColumns();
Object[] values = request.getSingleValues();
Map<MondrianDef.Expression, Set<RolapMember>> mapOfSlicerMembers = null;
HashMap<MondrianDef.Expression, Boolean> done = new HashMap<MondrianDef.Expression, Boolean>();
for (int i = 0; i < columns.length; i++) {
final RolapStar.Column column = columns[i];
final String value = String.valueOf(values[i]);
// choose from agg or regular star
String expr = getColumnExpr(sqlQuery, aggStar, column);
if ((RolapUtil.mdxNullLiteral().equalsIgnoreCase(value)) || (value.equalsIgnoreCase(RolapUtil.sqlNullValue.toString()))) {
sqlQuery.addWhere(expr, " is ", RolapUtil.sqlNullLiteral);
} else {
if (column.getDatatype().isNumeric()) {
// make sure it can be parsed
Double.valueOf(value);
}
if (mapOfSlicerMembers == null) {
mapOfSlicerMembers = getSlicerMemberMap(evaluator);
}
final MondrianDef.Expression keyForSlicerMap = column.getExpression();
if (mapOfSlicerMembers.containsKey(keyForSlicerMap)) {
if (!done.containsKey(keyForSlicerMap)) {
Set<RolapMember> slicerMembersSet = mapOfSlicerMembers.get(keyForSlicerMap);
// get only constraining members
// TODO: can we do this right at getSlicerMemberMap?
List<RolapMember> slicerMembers = getNonAllMembers(slicerMembersSet);
if (slicerMembers.size() > 0) {
// get level
final int levelIndex = slicerMembers.get(0).getHierarchy().getLevels().length - 1;
RolapLevel levelForWhere = (RolapLevel) slicerMembers.get(0).getHierarchy().getLevels()[levelIndex];
// build where constraint
final String where = generateSingleValueInExpr(sqlQuery, baseCube, aggStar, slicerMembers, levelForWhere, restrictMemberTypes, false, false);
if (!where.equals("")) {
// The where clause might be null because if the
// list of members is greater than the limit
// permitted, we won't constraint.
sqlQuery.addWhere(where);
}
} else {
addSimpleColumnConstraint(sqlQuery, column, expr, value);
}
done.put(keyForSlicerMap, Boolean.TRUE);
}
// if done, no op
} else {
// column not constrained by slicer
addSimpleColumnConstraint(sqlQuery, column, expr, value);
}
}
}
// force Role based Access filtering
addRoleAccessConstraints(sqlQuery, aggStar, restrictMemberTypes, baseCube, evaluator);
}
Aggregations