use of mondrian.server.Execution in project mondrian by pentaho.
the class FunUtil method evaluateSet.
/**
* Evaluates one or more expressions against the member list returning
* a SetWrapper array. Where this differs very significantly from the
* above evaluateSet methods is how it count null values and Throwables;
* this method adds nulls to the SetWrapper Vector rather than not adding
* anything - as the above method does. The impact of this is that if, for
* example, one was creating a list of x,y values then each list will have
* the same number of values (though some might be null) - this allows
* higher level code to determine how to handle the lack of data rather than
* having a non-equal number (if one is plotting x,y values it helps to
* have the same number and know where a potential gap is the data is.
*/
static SetWrapper[] evaluateSet(Evaluator evaluator, TupleList list, DoubleCalc[] calcs) {
Util.assertPrecondition(calcs != null, "calcs != null");
// todo: treat constant exps as evaluateMembers() does
SetWrapper[] retvals = new SetWrapper[calcs.length];
for (int i = 0; i < calcs.length; i++) {
retvals[i] = new SetWrapper();
}
final TupleCursor cursor = list.tupleCursor();
int currentIteration = 0;
Execution execution = evaluator.getQuery().getStatement().getCurrentExecution();
while (cursor.forward()) {
CancellationChecker.checkCancelOrTimeout(currentIteration++, execution);
cursor.setContext(evaluator);
for (int i = 0; i < calcs.length; i++) {
DoubleCalc calc = calcs[i];
SetWrapper retval = retvals[i];
double o = calc.evaluateDouble(evaluator);
if (o == FunUtil.DoubleNull) {
retval.nullCount++;
retval.v.add(null);
} else {
retval.v.add(o);
}
// TODO: If the expression yielded an error, carry on
// summing, so that if we are running in a
// BatchingCellReader, we find out all the dependent cells
// we need
}
}
return retvals;
}
use of mondrian.server.Execution in project mondrian by pentaho.
the class RolapStatisticsCache method getTableCardinality.
private long getTableCardinality(String catalog, String schema, String table) {
final List<String> key = Arrays.asList(catalog, schema, table);
long rowCount = -1;
if (tableMap.containsKey(key)) {
rowCount = tableMap.get(key);
} else {
final Dialect dialect = star.getSqlQueryDialect();
final List<StatisticsProvider> statisticsProviders = dialect.getStatisticsProviders();
final Execution execution = new Execution(star.getSchema().getInternalConnection().getInternalStatement(), 0);
for (StatisticsProvider statisticsProvider : statisticsProviders) {
rowCount = statisticsProvider.getTableCardinality(dialect, star.getDataSource(), catalog, schema, table, execution);
if (rowCount >= 0) {
break;
}
}
// Note: If all providers fail, we put -1 into the cache, to ensure
// that we won't try again.
tableMap.put(key, rowCount);
}
return rowCount;
}
use of mondrian.server.Execution in project mondrian by pentaho.
the class RolapStatisticsCache method getQueryCardinality.
private long getQueryCardinality(String sql) {
long rowCount = -1;
if (queryMap.containsKey(sql)) {
rowCount = queryMap.get(sql);
} else {
final Dialect dialect = star.getSqlQueryDialect();
final List<StatisticsProvider> statisticsProviders = dialect.getStatisticsProviders();
final Execution execution = new Execution(star.getSchema().getInternalConnection().getInternalStatement(), 0);
for (StatisticsProvider statisticsProvider : statisticsProviders) {
rowCount = statisticsProvider.getQueryCardinality(dialect, star.getDataSource(), sql, execution);
if (rowCount >= 0) {
break;
}
}
// Note: If all providers fail, we put -1 into the cache, to ensure
// that we won't try again.
queryMap.put(sql, rowCount);
}
return rowCount;
}
use of mondrian.server.Execution in project mondrian by pentaho.
the class SqlMemberSource method getMemberChildren2.
private void getMemberChildren2(RolapMember parentMember, List<RolapMember> children, MemberChildrenConstraint constraint) {
Pair<String, List<SqlStatement.Type>> pair;
boolean parentChild;
final RolapLevel parentLevel = parentMember.getLevel();
RolapLevel childLevel;
if (parentLevel.isParentChild()) {
pair = makeChildMemberSqlPC(parentMember);
parentChild = true;
childLevel = parentLevel;
} else {
childLevel = (RolapLevel) parentLevel.getChildLevel();
if (childLevel == null) {
// member is at last level, so can have no children
return;
}
if (childLevel.isParentChild()) {
pair = makeChildMemberSql_PCRoot(parentMember);
parentChild = true;
} else {
pair = makeChildMemberSql(parentMember, dataSource, constraint);
parentChild = false;
}
}
final String sql = pair.left;
int startChildrenSize = children.size();
HashMap<RolapMember, Object> rolapToOrdinalMap = new HashMap<>();
final List<SqlStatement.Type> types = pair.right;
SqlStatement stmt = RolapUtil.executeQuery(dataSource, sql, types, 0, 0, new SqlStatement.StatementLocus(Locus.peek().execution, "SqlMemberSource.getMemberChildren", "while building member cache", SqlStatementEvent.Purpose.TUPLES, 0), -1, -1, null);
try {
int limit = MondrianProperties.instance().ResultLimit.get();
boolean checkCacheStatus = true;
final List<SqlStatement.Accessor> accessors = stmt.getAccessors();
ResultSet resultSet = stmt.getResultSet();
RolapMember parentMember2 = RolapUtil.strip(parentMember);
Execution execution = Locus.peek().execution;
while (resultSet.next()) {
// Check if the MDX query was canceled.
CancellationChecker.checkCancelOrTimeout(++stmt.rowCount, execution);
if (limit > 0 && limit < stmt.rowCount) {
// result limit exceeded, throw an exception
throw MondrianResource.instance().MemberFetchLimitExceeded.ex(limit);
}
Object value = accessors.get(0).get();
if (value == null) {
value = RolapUtil.sqlNullValue;
}
Object captionValue;
int columnOffset = 1;
if (childLevel.hasCaptionColumn()) {
// The columnOffset needs to take into account
// the caption column if one exists
captionValue = accessors.get(columnOffset++).get();
} else {
captionValue = null;
}
Object key = cache.makeKey(parentMember2, value);
RolapMember member = cache.getMember(key, checkCacheStatus);
checkCacheStatus = false;
/* Only check the first time */
if (member == null) {
member = makeMember(parentMember2, childLevel, value, captionValue, parentChild, stmt, key, columnOffset);
}
if (value == RolapUtil.sqlNullValue) {
children.toArray();
addAsOldestSibling(children, member);
} else {
children.add(member);
}
if (!childLevel.getOrdinalExp().equals(childLevel.getKeyExp())) {
Object ordinal = accessors.get(columnOffset).get();
Object prevValue = rolapToOrdinalMap.put(member, ordinal);
if (prevValue != null && !Util.equals(prevValue, ordinal)) {
LOGGER.error("Column expression for " + member.getUniqueName() + " is inconsistent with ordinal or caption expression." + " It should have 1:1 relationship");
}
}
}
} catch (SQLException e) {
throw stmt.handle(e);
} finally {
stmt.close();
}
}
use of mondrian.server.Execution 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();
}
}
}
Aggregations