use of mondrian.server.Execution in project mondrian by pentaho.
the class MemberCacheControlTest method setUp.
protected void setUp() throws Exception {
super.setUp();
propSaver.set(MondrianProperties.instance().EnableRolapCubeMemberCache, false);
RolapSchemaPool.instance().clear();
final RolapConnection conn = (RolapConnection) getConnection();
final Statement statement = conn.getInternalStatement();
final Execution execution = new Execution(statement, 0);
locus = new Locus(execution, getName(), null);
Locus.push(locus);
}
use of mondrian.server.Execution in project mondrian by pentaho.
the class FunUtil method evaluateSet.
/**
* Evaluates {@code exp} (if defined) over {@code members} to
* generate a {@link List} of {@link SetWrapper} objects, which contains
* a {@link Double} value and meta information, unlike
* {@link #evaluateMembers}, which only produces values.
*
* @pre exp != null
*/
static SetWrapper evaluateSet(Evaluator evaluator, TupleIterable members, Calc calc) {
assert members != null;
assert calc != null;
assert calc.getType() instanceof ScalarType;
// todo: treat constant exps as evaluateMembers() does
SetWrapper retval = new SetWrapper();
final TupleCursor cursor = members.tupleCursor();
int currentIteration = 0;
Execution execution = evaluator.getQuery().getStatement().getCurrentExecution();
while (cursor.forward()) {
CancellationChecker.checkCancelOrTimeout(currentIteration++, execution);
cursor.setContext(evaluator);
Object o = calc.evaluate(evaluator);
if (o == null || o == Util.nullValue) {
retval.nullCount++;
} else if (o == RolapUtil.valueNotReadyException) {
// Carry on summing, so that if we are running in a
// BatchingCellReader, we find out all the dependent cells we
// need
retval.errorCount++;
} else if (o instanceof Number) {
retval.v.add(((Number) o).doubleValue());
} else {
retval.v.add(o);
}
}
return retval;
}
use of mondrian.server.Execution in project mondrian by pentaho.
the class FunUtil method sortTuples.
/**
* Sorts a list of Tuples by the value of an applied expression. Stable
* sort.
*
* <p>Helper function for MDX functions TopCount, TopSum, TopPercent,
* BottomCount, BottomSum, BottomPercent, but not the MDX function Order.
*
* <p>NOTE: This function does not preserve the contents of the validator.
*
* <p>If you specify {@code tupleList}, the list is sorted in place, and
* tupleList is returned.
*
* @param evaluator Evaluator
* @param tupleIterable Iterator over tuples
* @param tupleList List of tuples, if known, otherwise null
* @param exp Expression to sort on
* @param desc Whether to sort descending
* @param brk Whether to break
* @param arity Number of members in each tuple
* @return sorted list (never null)
*/
public static TupleList sortTuples(Evaluator evaluator, TupleIterable tupleIterable, TupleList tupleList, Calc exp, boolean desc, boolean brk, int arity) {
// NOTE: This method does not implement the iterable/list concept
// as fully as sortMembers. This is because sortMembers evaluates all
// sort expressions up front. There, it is efficient to unravel the
// iterator and evaluate the sort expressions at the same time.
List<List<Member>> tupleArrayList;
if (tupleList == null) {
tupleArrayList = new ArrayList<List<Member>>();
final TupleCursor cursor = tupleIterable.tupleCursor();
int currentIteration = 0;
Execution execution = evaluator.getQuery().getStatement().getCurrentExecution();
while (cursor.forward()) {
CancellationChecker.checkCancelOrTimeout(currentIteration++, execution);
tupleArrayList.add(cursor.current());
}
if (tupleArrayList.size() <= 1) {
return new DelegatingTupleList(tupleIterable.getArity(), tupleArrayList);
}
} else {
if (tupleList.size() <= 1) {
return tupleList;
}
tupleArrayList = tupleList;
}
@SuppressWarnings({ "unchecked" }) List<Member>[] tuples = tupleArrayList.toArray(new List[tupleArrayList.size()]);
final DelegatingTupleList result = new DelegatingTupleList(tupleIterable.getArity(), Arrays.asList(tuples));
Comparator<List<Member>> comparator;
if (brk) {
comparator = new BreakTupleComparator(evaluator, exp, arity);
if (desc) {
comparator = Collections.reverseOrder(comparator);
}
} else {
comparator = new HierarchicalTupleComparator(evaluator, exp, arity, desc);
}
Arrays.sort(tuples, comparator);
if (LOGGER.isDebugEnabled()) {
StringBuilder sb = new StringBuilder("FunUtil.sortTuples returned:");
for (List<Member> tuple : tuples) {
sb.append("\n");
sb.append(tuple.toString());
}
LOGGER.debug(sb.toString());
}
return result;
}
use of mondrian.server.Execution in project mondrian by pentaho.
the class BatchTestCase method assertRequestSql.
/**
* Checks that a given sequence of cell requests results in a
* particular SQL statement being generated.
*
* <p>Always clears the cache before running the requests.
*
* <p>Runs the requests once for each SQL pattern in the current
* dialect. If there are multiple patterns, runs the MDX query multiple
* times, and expects to see each SQL statement appear. If there are no
* patterns in this dialect, the test trivially succeeds.
*
* @param requests Sequence of cell requests
* @param patterns Set of patterns
* @param negative Set to false in order to 'expect' a query or
* true to 'forbid' a query.
*/
protected void assertRequestSql(CellRequest[] requests, SqlPattern[] patterns, boolean negative) {
final RolapStar star = requests[0].getMeasure().getStar();
final String cubeName = requests[0].getMeasure().getCubeName();
final RolapCube cube = lookupCube(cubeName);
final Dialect sqlDialect = star.getSqlQueryDialect();
Dialect.DatabaseProduct d = sqlDialect.getDatabaseProduct();
SqlPattern sqlPattern = SqlPattern.getPattern(d, patterns);
if (d == Dialect.DatabaseProduct.UNKNOWN) {
// test. We do not print any warning message.
return;
}
boolean patternFound = false;
for (SqlPattern pattern : patterns) {
if (!pattern.hasDatabaseProduct(d)) {
continue;
}
patternFound = true;
clearCache(cube);
String sql = sqlPattern.getSql();
String trigger = sqlPattern.getTriggerSql();
switch(d) {
case ORACLE:
sql = sql.replaceAll(" =as= ", " ");
trigger = trigger.replaceAll(" =as= ", " ");
break;
case TERADATA:
sql = sql.replaceAll(" =as= ", " as ");
trigger = trigger.replaceAll(" =as= ", " as ");
break;
}
// Create a dummy DataSource which will throw a 'bomb' if it is
// asked to execute a particular SQL statement, but will otherwise
// behave exactly the same as the current DataSource.
RolapUtil.setHook(new TriggerHook(trigger));
Bomb bomb;
final Execution execution = new Execution(((RolapConnection) getConnection()).getInternalStatement(), 1000);
final AggregationManager aggMgr = execution.getMondrianStatement().getMondrianConnection().getServer().getAggregationManager();
final Locus locus = new Locus(execution, "BatchTestCase", "BatchTestCase");
try {
FastBatchingCellReader fbcr = new FastBatchingCellReader(execution, getCube(cubeName), aggMgr);
for (CellRequest request : requests) {
fbcr.recordCellRequest(request);
}
// The FBCR will presume there is a current Locus in the stack,
// so let's create a mock one.
Locus.push(locus);
fbcr.loadAggregations();
bomb = null;
} catch (Bomb e) {
bomb = e;
} catch (RuntimeException e) {
// Walk up the exception tree and see if the root cause
// was a SQL bomb.
bomb = Util.getMatchingCause(e, Bomb.class);
if (bomb == null) {
throw e;
}
} finally {
RolapUtil.setHook(null);
Locus.pop(locus);
}
if (!negative && bomb == null) {
fail("expected query [" + sql + "] did not occur");
} else if (negative && bomb != null) {
fail("forbidden query [" + sql + "] detected");
}
TestContext.assertEqualsVerbose(replaceQuotes(sql), replaceQuotes(bomb.sql));
}
// dialect.
if (!patternFound) {
String warnDialect = MondrianProperties.instance().WarnIfNoPatternForDialect.get();
if (warnDialect.equals(d.toString())) {
System.out.println("[No expected SQL statements found for dialect \"" + sqlDialect.toString() + "\" and test not run]");
}
}
}
use of mondrian.server.Execution in project mondrian by pentaho.
the class CancellationTest method testMutableCrossJoinCancellation.
public void testMutableCrossJoinCancellation() throws MondrianException {
// tests that cancellation/timeout is checked in
// CrossJoinFunDef.mutableCrossJoin
propSaver.set(propSaver.properties.CheckCancelOrTimeoutInterval, 1);
RolapCube salesCube = (RolapCube) cubeByName(getTestContext().getConnection(), "Sales");
SchemaReader salesCubeSchemaReader = salesCube.getSchemaReader(getTestContext().getConnection().getRole()).withLocus();
TupleList productMembers = productMembersPotScrubbersPotsAndPans(salesCubeSchemaReader);
String selectGenders = "select Gender.members on 0 from sales";
Result genders = executeQuery(selectGenders);
Evaluator gendersEval = ((RolapResult) genders).getEvaluator(new int[] { 0 });
TupleList genderMembers = new UnaryTupleList();
for (Position pos : genders.getAxes()[0].getPositions()) {
genderMembers.add(pos);
}
Execution execution = spy(new Execution(genders.getQuery().getStatement(), 0));
TupleList mutableCrossJoinResult = mutableCrossJoin(productMembers, genderMembers, execution);
gendersEval.getQuery().getStatement().start(execution);
// checkCancelOrTimeout should be called once
// for each tuple from mutableCrossJoin since phase interval is 1
// plus once for each productMembers item
// since it gets through SqlStatement.execute
int expectedCallsQuantity = mutableCrossJoinResult.size() + productMembers.size();
verify(execution, times(expectedCallsQuantity)).checkCancelOrTimeout();
}
Aggregations