rolapstar.java
来自「数据仓库展示程序」· Java 代码 · 共 1,660 行 · 第 1/4 页
JAVA
1,660 行
return expr + " is null";
case 1:
// Special case -- one not-null value, and null, for
// example "(x = 1 or x is null)".
buf = new StringBuffer(64);
buf.append('(');
buf.append(expr);
buf.append(" = ");
quoteValue(constraints[0].getValue(), buf, isNumeric);
buf.append(" or ");
buf.append(expr);
buf.append(" is null)");
return buf.toString();
default:
// Nulls and values, for example,
// "(x in (1, 2) or x IS NULL)".
buf = new StringBuffer(64);
buf.append('(');
buf.append(sb.toString());
buf.append(" or ");
buf.append(expr);
buf.append(" is null)");
return buf.toString();
}
} else {
// No nulls. Return, for example, "x in (1, 2, 3)".
return sb.toString();
}
}
public String toString() {
StringWriter sw = new StringWriter(256);
PrintWriter pw = new PrintWriter(sw);
print(pw, "");
pw.flush();
return sw.toString();
}
/**
* Prints this table and its children.
*/
public void print(PrintWriter pw, String prefix) {
SqlQuery sqlQuery = getSqlQuery();
pw.print(prefix);
pw.print(getName());
pw.print(" (");
pw.print(getBitPosition());
pw.print("): ");
pw.print(getExpression(sqlQuery));
}
}
/**
* Definition of a measure in a star schema.
*
* <p>A measure is basically just a column; except that its
* {@link #aggregator} defines how it is to be rolled up.
*/
public static class Measure extends Column {
private final RolapAggregator aggregator;
private Measure(String name,
RolapAggregator aggregator,
Table table,
MondrianDef.Expression expression,
boolean isNumeric) {
super(name, table, expression, isNumeric);
this.aggregator = aggregator;
}
public RolapAggregator getAggregator() {
return aggregator;
}
public boolean equals(Object obj) {
if (! super.equals(obj)) {
return false;
}
if (! (obj instanceof RolapStar.Measure)) {
return false;
}
RolapStar.Measure other = (RolapStar.Measure) obj;
// Note: both measure have to have the same aggregator
return (other.aggregator == this.aggregator);
}
/**
* Prints this table and its children.
*/
public void print(PrintWriter pw, String prefix) {
SqlQuery sqlQuery = getSqlQuery();
pw.print(prefix);
pw.print(getName());
pw.print(" (");
pw.print(getBitPosition());
pw.print("): ");
pw.print(aggregator.getExpression(getExpression(sqlQuery)));
}
}
/**
* Definition of a table in a star schema.
*
* <p>A 'table' is defined by a {@link MondrianDef.Relation} so may, in
* fact, be a view.
*
* <p>Every table in the star schema except the fact table has a parent
* table, and a condition which specifies how it is joined to its parent.
* So the star schema is, in effect, a hierarchy with the fact table at
* its root.
*/
public static class Table {
private final RolapStar star;
private final MondrianDef.Relation relation;
private final List columnList;
private final Table parent;
private List children;
/** Condition with which it is connected to its parent. **/
private final Condition joinCondition;
private final String alias;
private Table(RolapStar star,
MondrianDef.Relation relation,
Table parent,
Condition joinCondition) {
this.star = star;
this.relation = relation;
Util.assertTrue(
relation instanceof MondrianDef.Table ||
relation instanceof MondrianDef.View,
"todo: allow dimension which is not a Table or View, [" +
relation + "]");
this.alias = chooseAlias();
this.parent = parent;
final AliasReplacer aliasReplacer =
new AliasReplacer(relation.getAlias(), this.alias);
this.joinCondition = aliasReplacer.visit(joinCondition);
if (this.joinCondition != null) {
this.joinCondition.table = this;
}
this.columnList = new ArrayList();
this.children = Collections.EMPTY_LIST;
Util.assertTrue((parent == null) == (joinCondition == null));
}
public Condition getCondition() {
return joinCondition;
}
public Table getParentTable() {
return parent;
}
private void addColumn(Column column) {
columnList.add(column);
}
public void loadColumns(BitKey bitKey, List list) {
for (Iterator it = getColumns(); it.hasNext(); ) {
Column column = (Column) it.next();
if (bitKey.isSetByPos(column.getBitPosition())) {
list.add(column);
}
}
for (Iterator it = getChildren(); it.hasNext(); ) {
Table child = (Table) it.next();
child.loadColumns(bitKey, list);
}
}
public Column[] lookupColumns(String columnName) {
List l = new ArrayList();
for (Iterator it = getColumns(); it.hasNext(); ) {
Column column = (Column) it.next();
if (column.getExpression() instanceof MondrianDef.Column) {
MondrianDef.Column columnExpr =
(MondrianDef.Column) column.getExpression();
if (columnExpr.name.equals(columnName)) {
l.add(column);
}
}
}
return (Column[]) l.toArray(new Column[0]);
}
public Column lookupColumn(String columnName) {
for (Iterator it = getColumns(); it.hasNext(); ) {
Column column = (Column) it.next();
if (column.getExpression() instanceof MondrianDef.Column) {
MondrianDef.Column columnExpr =
(MondrianDef.Column) column.getExpression();
if (columnExpr.name.equals(columnName)) {
return column;
}
}
}
return null;
}
/**
* Given a MondrianDef.Expression return a column with that expression
* or null.
*
* @param xmlExpr
* @return
*/
public Column lookupColumnByExpression(MondrianDef.Expression xmlExpr) {
for (Iterator it = getColumns(); it.hasNext(); ) {
Column column = (Column) it.next();
if (column.getExpression().equals(xmlExpr)) {
return column;
}
}
return null;
}
public boolean containsColumn(Column column) {
for (Iterator it = getColumns(); it.hasNext(); ) {
Column other = (Column) it.next();
if (column.equals(other)) {
return true;
}
}
return false;
}
/**
* Look up a RolapStar.Measure by its name returning null if none are
* found.
*
* @param name
* @return
*/
public Measure lookupMeasureByName(String name) {
for (Iterator it = getColumns(); it.hasNext(); ) {
Column column = (Column) it.next();
if (column instanceof Measure) {
Measure measure = (Measure) column;
if (measure.getName().equals(name)) {
return measure;
}
}
}
return null;
}
RolapStar getStar() {
return star;
}
private SqlQuery getSqlQuery() {
return getStar().getSqlQuery();
}
public MondrianDef.Relation getRelation() {
return relation;
}
/** Chooses an alias which is unique within the star. */
private String chooseAlias() {
List aliasList = star.getAliasList();
for (int i = 0;; ++i) {
String candidateAlias = relation.getAlias();
if (i > 0) {
candidateAlias += "_" + i;
}
if (!aliasList.contains(candidateAlias)) {
return candidateAlias;
}
}
}
public String getAlias() {
return alias;
}
/**
* Sometimes one need to get to the "real" name when the table has
* been given an alias.
*
* @return
*/
public String getTableName() {
if (relation instanceof MondrianDef.Table) {
MondrianDef.Table t = (MondrianDef.Table) relation;
return t.name;
} else {
return null;
}
}
synchronized void makeMeasure(RolapStoredMeasure storedMeasure) {
RolapStar.Measure measure = new RolapStar.Measure(
storedMeasure.getName(),
storedMeasure.getAggregator(),
this,
storedMeasure.getMondrianDefExpression(),
true);
storedMeasure.setStarMeasure(measure); // reverse mapping
if (containsColumn(measure)) {
star.decrementColumnCount();
} else {
addColumn(measure);
}
}
/**
* This is only called by RolapCube. If the RolapLevel has a non-null
* name expression then two columns will be made, otherwise only one.
*
* @param cube
* @param level
* @param parentColumn
*/
synchronized Column makeColumns(
RolapCube cube,
RolapLevel level,
Column parentColumn,
String usagePrefix) {
Column nameColumn = null;
if (level.getNameExp() != null) {
// make a column for the name expression
nameColumn = makeColumnForLevelExpr(
cube,
level,
level.getName(),
level.getNameExp(),
false,
null,
null,
null);
}
// select the column's name depending upon whether or not a
// "named" column, above, has been created.
String name = (level.getNameExp() == null)
? level.getName()
: level.getName() + " (Key)";
// If the nameColumn is not null, then it is associated with this
// column.
Column column = makeColumnForLevelExpr(
cube,
level,
name,
level.getKeyExp(),
(level.getFlags() & RolapLevel.NUMERIC) != 0,
nameColumn,
parentColumn,
usagePrefix);
if (column != null) {
Map map = star.getMapLevelToColumn(cube);
map.put(level, column);
}
return column;
}
private Column makeColumnForLevelExpr(
RolapCube cube,
RolapLevel level,
String name,
MondrianDef.Expression xmlExpr,
boolean isNumeric,
Column nameColumn,
Column parentColumn,
String usagePrefix) {
Table table = this;
if (xmlExpr instanceof MondrianDef.Column) {
final MondrianDef.Column xmlColumn =
(MondrianDef.Column) xmlExpr;
String tableName = xmlColumn.table;
table = findAncestor(tableName);
if (table == null) {
throw Util.newError(
"Level '" + level.getUniqueName()
+ "' of cube '"
+ this
+ "' is invalid: table '" + tableName
+ "' is not found in current scope"
+ Util.nl
+ ", star:"
+ Util.nl
+ getStar());
}
RolapStar.AliasReplacer aliasReplacer =
new RolapStar.AliasReplacer(tableName, table.getAlias());
xmlExpr = aliasReplacer.visit(xmlExpr);
}
// does the column already exist??
Column c = lookupColumnByExpression(xmlExpr);
RolapStar.Column column = null;
if (c != null) {
// Yes, well just reuse it
// You might wonder why the column need be returned if it
// already exists. Well, it might have been created for one
// cube, but for another cube using the same fact table, it
// still needs to be put into the cube level to column map.
// Trust me, return null and a junit test fails.
column = c;
} else {
// Make a new column and add it
column = new RolapStar.Column(name,
table,
xmlExpr,
isNumeric,
nameColumn,
parentColumn,
usagePrefix);
addColumn(column);
}
return column;
}
/**
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?