rolapstar.java
来自「数据仓库展示程序」· Java 代码 · 共 1,660 行 · 第 1/4 页
JAVA
1,660 行
* Extends this 'leg' of the star by adding <code>relation</code>
* joined by <code>joinCondition</code>. If the same expression is
* already present, does not create it again.
*/
synchronized Table addJoin(MondrianDef.Relation relation,
RolapStar.Condition joinCondition) {
if (relation instanceof MondrianDef.Table ||
relation instanceof MondrianDef.View) {
RolapStar.Table starTable = findChild(relation, joinCondition);
if (starTable == null) {
starTable = new RolapStar.Table(star, relation, this,
joinCondition);
if (this.children == Collections.EMPTY_LIST) {
this.children = new ArrayList();
}
this.children.add(starTable);
}
return starTable;
} else if (relation instanceof MondrianDef.Join) {
MondrianDef.Join join = (MondrianDef.Join) relation;
RolapStar.Table leftTable = addJoin(join.left, joinCondition);
String leftAlias = join.leftAlias;
if (leftAlias == null) {
leftAlias = join.left.getAlias();
if (leftAlias == null) {
throw Util.newError(
"missing leftKeyAlias in " + relation);
}
}
assert leftTable.findAncestor(leftAlias) == leftTable;
// switch to uniquified alias
leftAlias = leftTable.getAlias();
String rightAlias = join.rightAlias;
if (rightAlias == null) {
rightAlias = join.right.getAlias();
if (rightAlias == null) {
throw Util.newError(
"missing rightKeyAlias in " + relation);
}
}
joinCondition = new RolapStar.Condition(
new MondrianDef.Column(leftAlias, join.leftKey),
new MondrianDef.Column(rightAlias, join.rightKey));
RolapStar.Table rightTable = leftTable.addJoin(
join.right, joinCondition);
return rightTable;
} else {
throw Util.newInternal("bad relation type " + relation);
}
}
/**
* Returns a child relation which maps onto a given relation, or null if
* there is none.
*/
public Table findChild(MondrianDef.Relation relation,
Condition joinCondition) {
for (Iterator it = getChildren(); it.hasNext(); ) {
Table child = (Table) it.next();
if (child.relation.equals(relation)) {
Condition condition = joinCondition;
if (!Util.equals(relation.getAlias(), child.alias)) {
// Make the two conditions comparable, by replacing
// occurrence of this table's alias with occurrences
// of the child's alias.
AliasReplacer aliasReplacer = new AliasReplacer(
relation.getAlias(), child.alias);
condition = aliasReplacer.visit(joinCondition);
}
if (child.joinCondition.equals(condition)) {
return child;
}
}
}
return null;
}
/**
* Returns a descendant with a given alias, or null if none found.
*/
public Table findDescendant(String seekAlias) {
if (getAlias().equals(seekAlias)) {
return this;
}
for (Iterator it = getChildren(); it.hasNext(); ) {
Table child = (Table) it.next();
Table found = child.findDescendant(seekAlias);
if (found != null) {
return found;
}
}
return null;
}
/**
* Returns an ancestor with a given alias, or null if not found.
*/
public Table findAncestor(String tableName) {
for (Table t = this; t != null; t = t.parent) {
if (t.relation.getAlias().equals(tableName)) {
return t;
}
}
return null;
}
public boolean equalsTableName(String tableName) {
if (this.relation instanceof MondrianDef.Table) {
MondrianDef.Table mt = (MondrianDef.Table) this.relation;
if (mt.name.equals(tableName)) {
return true;
}
}
return false;
}
/**
* Adds this table to the from clause of a query.
*
* @param query Query to add to
* @param failIfExists Pass in false if you might have already added
* the table before and if that happens you want to do nothing.
* @param joinToParent Pass in true if you are constraining a cell
* calculcation, false if you are retrieving members.
*/
public void addToFrom(SqlQuery query,
boolean failIfExists,
boolean joinToParent) {
query.addFrom(relation, alias, failIfExists);
Util.assertTrue((parent == null) == (joinCondition == null));
if (joinToParent) {
if (parent != null) {
parent.addToFrom(query, failIfExists, joinToParent);
}
if (joinCondition != null) {
query.addWhere(joinCondition.toString(query));
}
}
}
/**
* Return an Iterator over all child tables.
*
* @return
*/
public Iterator getChildren() {
return children.iterator();
}
/**
* Return an Iterator over all of the table's columns.
*
* @return
*/
public Iterator getColumns() {
return columnList.iterator();
}
/**
* Find the child table of the fact table with the given columnname
* used in its left join condition. This is used by the
* AggTableManager while characterizing the fact table columns.
*
* @param columnName
* @return
*/
public RolapStar.Table findTableWithLeftJoinCondition(
final String columnName) {
for (Iterator it = getChildren(); it.hasNext(); ) {
Table child = (Table) it.next();
Condition condition = child.joinCondition;
if (condition != null) {
if (condition.left instanceof MondrianDef.Column) {
MondrianDef.Column mcolumn =
(MondrianDef.Column) condition.left;
if (mcolumn.name.equals(columnName)) {
return child;
}
}
}
}
return null;
}
/**
* This is used during aggregate table validation to make sure that the
* mapping from for the aggregate join condition is valid. It returns
* the child table with the matching left join condition.
*
* @param left
* @return
*/
public RolapStar.Table findTableWithLeftCondition(
final MondrianDef.Expression left) {
for (Iterator it = getChildren(); it.hasNext(); ) {
Table child = (Table) it.next();
Condition condition = child.joinCondition;
if (condition != null) {
if (condition.left instanceof MondrianDef.Column) {
MondrianDef.Column mcolumn =
(MondrianDef.Column) condition.left;
if (mcolumn.equals(left)) {
return child;
}
}
}
}
return null;
}
/**
* Note: I do not think that this is ever true.
*
* @return
*/
public boolean isFunky() {
return (relation == null);
}
public boolean equals(Object obj) {
if (!(obj instanceof Table)) {
return false;
}
Table other = (Table) obj;
return getAlias().equals(other.getAlias());
}
public int hashCode() {
return getAlias().hashCode();
}
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) {
pw.print(prefix);
pw.println("Table:");
String subprefix = prefix + " ";
pw.print(subprefix);
pw.print("alias=");
pw.println(getAlias());
if (this.relation != null) {
pw.print(subprefix);
pw.print("relation=");
pw.println(relation);
}
pw.print(subprefix);
pw.println("Columns:");
String subsubprefix = subprefix + " ";
for (Iterator it = getColumns(); it.hasNext(); ) {
Column column = (Column) it.next();
column.print(pw, subsubprefix);
pw.println();
}
if (this.joinCondition != null) {
this.joinCondition.print(pw, subprefix);
}
for (Iterator it = getChildren(); it.hasNext(); ) {
Table child = (Table) it.next();
child.print(pw, subprefix);
}
}
/**
* Does this table have a column with the given name.
*
* @param columnName
* @return
*/
public boolean containsColumn(String columnName) {
if (relation instanceof MondrianDef.Table) {
return star.containsColumn(((MondrianDef.Table) relation).name,
columnName);
} else {
// todo: Deal with join and view.
return false;
}
}
}
public static class Condition {
private static final Logger LOGGER = Logger.getLogger(Condition.class);
private final MondrianDef.Expression left;
private final MondrianDef.Expression right;
// set in Table constructor
Table table;
Condition(MondrianDef.Expression left,
MondrianDef.Expression right) {
Util.assertPrecondition(left != null);
Util.assertPrecondition(right != null);
if (!(left instanceof MondrianDef.Column)) {
// TODO: Will this ever print?? if not then left should be
// of type MondrianDef.Column.
LOGGER.debug("Condition.left NOT Column: "
+left.getClass().getName());
}
this.left = left;
this.right = right;
}
public MondrianDef.Expression getLeft() {
return left;
}
public MondrianDef.Expression getRight() {
return right;
}
public String toString(SqlQuery query) {
return left.getExpression(query) + " = " + right.getExpression(query);
}
public int hashCode() {
return left.hashCode() ^ right.hashCode();
}
public boolean equals(Object obj) {
if (!(obj instanceof Condition)) {
return false;
}
Condition that = (Condition) obj;
return (this.left.equals(that.left) &&
this.right.equals(that.right));
}
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 sqlQueuy = table.getSqlQuery();
pw.print(prefix);
pw.println("Condition:");
String subprefix = prefix + " ";
pw.print(subprefix);
pw.print("left=");
pw.println(left.getExpression(sqlQueuy));
pw.print(subprefix);
pw.print("right=");
pw.println(right.getExpression(sqlQueuy));
}
}
/**
* Creates a copy of an expression, everywhere replacing one alias
* with another.
*/
public static class AliasReplacer {
private final String oldAlias;
private final String newAlias;
public AliasReplacer(String oldAlias, String newAlias) {
this.oldAlias = oldAlias;
this.newAlias = newAlias;
}
private Condition visit(Condition condition) {
if (condition == null) {
return null;
}
if (newAlias.equals(oldAlias)) {
return condition;
}
return new Condition(
visit(condition.left),
visit(condition.right));
}
public MondrianDef.Expression visit(MondrianDef.Expression expression) {
if (expression == null) {
return null;
}
if (newAlias.equals(oldAlias)) {
return expression;
}
if (expression instanceof MondrianDef.Column) {
MondrianDef.Column column = (MondrianDef.Column) expression;
return new MondrianDef.Column(visit(column.table), column.name);
} else {
throw Util.newInternal("need to implement " + expression);
}
}
private String visit(String table) {
return table.equals(oldAlias)
? newAlias
: table;
}
}
}
// End RolapStar.java
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?