📄 recognizer.java
字号:
uit.hasNext(); ) {
JdbcSchema.Table.Column.Usage aggUsage =
(JdbcSchema.Table.Column.Usage) uit.next();
MondrianDef.Relation rel = hierarchyUsage.getJoinTable();
String cName = levelColumnName;
if (! aggUsage.relation.equals(rel) ||
! aggColumn.column.name.equals(cName)) {
// this is an error so return
String msg = mres.DoubleMatchForLevel.str(
aggTable.getName(),
dbFactTable.getName(),
aggColumn.getName(),
aggUsage.relation.toString(),
aggColumn.column.name,
rel.toString(),
cName);
msgRecorder.reportError(msg);
returnValue = false;
msgRecorder.throwRTException();
}
}
} else {
JdbcSchema.Table.Column.Usage aggUsage =
aggColumn.newUsage(JdbcSchema.LEVEL_COLUMN_USAGE);
// Cache table and column for the above
// check
aggUsage.relation = hierarchyUsage.getJoinTable();
aggUsage.joinExp = hierarchyUsage.getJoinExp();
aggUsage.levelColumnName = levelColumnName;
aggUsage.setSymbolicName(symbolicName);
String tableAlias = null;
if (aggUsage.joinExp instanceof MondrianDef.Column) {
MondrianDef.Column mcolumn =
(MondrianDef.Column) aggUsage.joinExp;
tableAlias = mcolumn.table;
} else {
tableAlias = aggUsage.relation.getAlias();
}
RolapStar.Table factTable = star.getFactTable();
RolapStar.Table descTable = factTable.findDescendant(tableAlias);
if (descTable == null) {
// TODO: what to do here???
StringBuffer buf = new StringBuffer(256);
buf.append("descendant table is null for factTable=");
buf.append(factTable.getAlias());
buf.append(", tableAlias=");
buf.append(tableAlias);
msgRecorder.reportError(buf.toString());
returnValue = false;
msgRecorder.throwRTException();
}
RolapStar.Column rc = descTable.lookupColumn(factColumnName);
if (rc == null) {
rc = lookupInChildren(descTable, factColumnName);
}
if (rc == null) {
StringBuffer buf = new StringBuffer(256);
buf.append("Rolap.Column not found (null) for tableAlias=");
buf.append(tableAlias);
buf.append(", factColumnName=");
buf.append(factColumnName);
buf.append(", levelColumnName=");
buf.append(levelColumnName);
buf.append(", symbolicName=");
buf.append(symbolicName);
msgRecorder.reportError(buf.toString());
returnValue = false;
msgRecorder.throwRTException();
} else {
aggUsage.rColumn = rc;
}
}
} finally {
msgRecorder.popContextName();
}
}
protected RolapStar.Column lookupInChildren(final RolapStar.Table table,
final String factColumnName) {
RolapStar.Column rc = null;
// This can happen if we are looking at a collapsed dimension
// table, and the collapsed dimension in question in the
// fact table is a snowflake (not just a star), so we
// must look deeper...
for (Iterator it = table.getChildren(); it.hasNext(); ) {
RolapStar.Table child = (RolapStar.Table) it.next();
rc = child.lookupColumn(factColumnName);
if (rc != null) {
break;
} else {
rc = lookupInChildren(child, factColumnName);
if (rc != null) {
break;
}
}
}
return rc;
}
// Question: what if foreign key is seen, but there are also level
// columns - is this at least is a warning.
/**
* If everything is ok, issue warning for each aggTable column
* that has not been identified as a FACT_COLUMN, MEASURE_COLUMN or
* LEVEL_COLUMN.
*/
protected void checkUnusedColumns() {
msgRecorder.pushContextName("Recognizer.checkUnusedColumns");
for (Iterator it = aggTable.getColumns(); it.hasNext(); ) {
JdbcSchema.Table.Column aggColumn =
(JdbcSchema.Table.Column) it.next();
if (! aggColumn.hasUsage()) {
String msg = mres.AggUnknownColumn.str(
aggTable.getName(),
dbFactTable.getName(),
aggColumn.getName()
);
// This is a fatal error for explicit recognizer
/*
if (this instanceof ExplicitRecognizer) {
msgRecorder.reportError(msg);
} else {
msgRecorder.reportWarning(msg);
}
Make this just a warning
*/
msgRecorder.reportWarning(msg);
}
}
msgRecorder.popContextName();
}
/**
* Figure out what aggregator should be associated with a column usage.
* Generally, this aggregator is simply the RolapAggregator returned by
* calling the getRollup() method of the fact table column's
* RolapAggregator. But in the case that the fact table column's
* RolapAggregator is the "Avg" aggregator, then the special
* RolapAggregator.AvgFromSum is used.
* <p>
* Note: this code assumes that the aggregate table does not have an
* explicit average aggregation column.
*
* @param aggUsage
* @param factAgg
*/
protected void convertAggregator(final JdbcSchema.Table.Column.Usage aggUsage,
final RolapAggregator factAgg) {
RolapAggregator rollupAgg = null;
// NOTE: This assumes that the aggregate table does not have an explicit
// average column.
if (factAgg == RolapAggregator.Avg) {
String columnExpr = getFactCountExpr(aggUsage);
rollupAgg = new RolapAggregator.AvgFromSum(columnExpr);
} else {
rollupAgg = (RolapAggregator) factAgg.getRollup();
}
aggUsage.setAggregator(rollupAgg);
}
/**
* The method chooses a special aggregator for the aggregate table column's
* usage.
* <pre>
* If the fact table column's aggregator was "Avg":
* then if the sibling aggregator was "Avg":
* the new aggregator is RolapAggregator.AvgFromAvg
* else if the sibling aggregator was "Sum":
* the new aggregator is RolapAggregator.AvgFromSum
* else if the fact table column's aggregator was "Sum":
* if the sibling aggregator was "Avg":
* the new aggregator is RolapAggregator.SumFromAvg
* </pre>
* Note that there is no SumFromSum since that is not a special case
* requiring a special aggregator.
* <p>
* if no new aggregator was selected, then the fact table's aggregator
* rollup aggregator is used.
*
* @param aggUsage
* @param factAgg
* @param siblingAgg
*/
protected void convertAggregator(final JdbcSchema.Table.Column.Usage aggUsage,
final RolapAggregator factAgg,
final RolapAggregator siblingAgg) {
msgRecorder.pushContextName("Recognizer.convertAggregator");
RolapAggregator rollupAgg = null;
String columnExpr = getFactCountExpr(aggUsage);
if (factAgg == RolapAggregator.Avg) {
if (siblingAgg == RolapAggregator.Avg) {
rollupAgg = new RolapAggregator.AvgFromAvg(columnExpr);
} else if (siblingAgg == RolapAggregator.Sum) {
rollupAgg = new RolapAggregator.AvgFromSum(columnExpr);
}
} else if (factAgg == RolapAggregator.Sum) {
if (siblingAgg == RolapAggregator.Avg) {
rollupAgg = new RolapAggregator.SumFromAvg(columnExpr);
}
}
if (rollupAgg == null) {
rollupAgg = (RolapAggregator) factAgg.getRollup();
}
if (rollupAgg == null) {
String msg = mres.NoAggregatorFound.str(
aggUsage.getSymbolicName(),
factAgg.getName(),
siblingAgg.getName());
msgRecorder.reportError(msg);
}
aggUsage.setAggregator(rollupAgg);
msgRecorder.popContextName();
}
/**
* Given an aggregate table column usage, find the column name of the
* table's fact count column usage.
*
* @param aggUsage
* @return
*/
private String getFactCountExpr(final JdbcSchema.Table.Column.Usage aggUsage) {
// get the fact count column name.
JdbcSchema.Table aggTable = aggUsage.getColumn().getTable();
// iterator over fact count usages - in the end there can be only one!!
Iterator it =
aggTable.getColumnUsages(JdbcSchema.FACT_COUNT_COLUMN_USAGE);
it.hasNext();
JdbcSchema.Table.Column.Usage usage =
(JdbcSchema.Table.Column.Usage) it.next();
// get the columns name
String factCountColumnName = usage.getColumn().getName();
String tableName = aggTable.getName();
// we want the fact count expression
MondrianDef.Column column =
new MondrianDef.Column(tableName, factCountColumnName);
SqlQuery sqlQuery = star.getSqlQuery();
String columnExpr = column.getExpression(sqlQuery);
return columnExpr;
}
/**
* Find all cubes that use this fact table.
*
* @return
*/
protected Iterator findCubes() {
String name = dbFactTable.getName();
List l = new ArrayList();
RolapSchema schema = star.getSchema();
for (Iterator it = schema.getCubeIterator(); it.hasNext(); ) {
RolapCube cube = (RolapCube) it.next();
if (cube.isVirtual()) {
continue;
}
RolapStar cubeStar = cube.getStar();
String factTableName = cubeStar.getFactTable().getAlias();
if (name.equals(factTableName)) {
l.add(cube);
}
}
return l.iterator();
}
/**
* Given a MondrianDef.Expression, get the associated column name.
* <p>
* Note: if the MondrianDef.Expression is not a MondrianDef.Column or
* MondrianDef.KeyExpression, then null is returned. This will result in
* an error.
*
* @param expr
* @return
*/
protected String getColumnName(MondrianDef.Expression expr) {
msgRecorder.pushContextName("Recognizer.getColumnName");
try {
if (expr instanceof MondrianDef.Column) {
MondrianDef.Column column = (MondrianDef.Column) expr;
return column.getColumnName();
} else if (expr instanceof MondrianDef.KeyExpression) {
MondrianDef.KeyExpression key = (MondrianDef.KeyExpression) expr;
return key.toString();
}
String msg = mres.NoColumnNameFromExpression.str(
expr.toString());
msgRecorder.reportError(msg);
return null;
} finally {
msgRecorder.popContextName();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -