Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MONDRIAN-2279] - When a query is cancelled or times out, Mondrian may continue iterating over large tuple lists #639

Merged
merged 2 commits into from
Jan 28, 2016
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
[MONDRIAN-2279] - Test
  • Loading branch information
YuryBY committed Jan 28, 2016
commit 8312435cafa4ec7c77e9f095e5e881480475ecb3
60 changes: 57 additions & 3 deletions testsrc/main/mondrian/rolap/CancellationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// http://www.eclipse.org/legal/epl-v10.html.
// You must accept the terms of that agreement to use this software.
//
// Copyright (c) 2002-2015 Pentaho Corporation.. All rights reserved.
// Copyright (c) 2002-2016 Pentaho Corporation.. All rights reserved.
*/
package mondrian.rolap;

Expand All @@ -15,6 +15,7 @@
import mondrian.olap.fun.CrossJoinFunDef;
import mondrian.olap.fun.CrossJoinTest;
import mondrian.server.Execution;
import mondrian.server.Locus;
import mondrian.test.FoodMartTestCase;

import static org.mockito.Mockito.*;
Expand All @@ -28,8 +29,8 @@ public void testNonEmptyListCancellation() throws MondrianException {
propSaver.set(propSaver.properties.CheckCancelOrTimeoutInterval, 1);
CrossJoinFunDefTester crossJoinFunDef =
new CrossJoinFunDefTester(new CrossJoinTest.NullFunDef());
Result result = executeQuery(
"select store.[store name].members on 0 from sales");
Result result =
executeQuery("select store.[store name].members on 0 from sales");
Evaluator eval = ((RolapResult) result).getEvaluator(new int[]{0});
TupleList list = new UnaryTupleList();
for (Position pos : result.getAxes()[0].getPositions()) {
Expand All @@ -43,6 +44,59 @@ public void testNonEmptyListCancellation() throws MondrianException {
verify(exec, times(list.size())).checkCancelOrTimeout();
}

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();
}

private TupleList mutableCrossJoin(
final TupleList list1, final TupleList list2, final Execution execution)
{
return Locus.execute(
execution, "CancellationTest",
new Locus.Action<TupleList>() {
public TupleList execute() {
return CrossJoinFunDef.mutableCrossJoin(list1, list2);
}
});
}

public class CrossJoinFunDefTester extends CrossJoinFunDef {
public CrossJoinFunDefTester(FunDef dummyFunDef) {
super(dummyFunDef);
Expand Down