[Mondrian] AggTableManager: Two levels share the same foreign key column
Pedro Alves
pedro at neraka.no-ip.org
Wed Jun 3 05:15:07 EDT 2009
yay! Thanks!
Tell me, is there a jira issue on this? Seems to be a very interesting
functionality, will this be merged in the main code line?
-pedro
On Wed, Jun 03, 2009 at 10:09:22AM +0900, Alexander Korsukov wrote:
> Hello Pedro.
>
> Possible, but required some changes of mondrian. I made the following
> changes, and AggTableManager work fine with more then one hierarchies
> mapped to the same column of aggregation table (by AggLevel and
> AggForeignKey).
>
> mondrian-3.1.1.12687\src\main\mondrian\rolap\aggmatcher\Recognizer.java
> line 62:
> if (aggColumn.hasUsage(JdbcSchema.UsageType.LEVEL)) {
> // The column has at least one usage of level type
> // make sure we are looking at the
> // same table and column
> for (Iterator<JdbcSchema.Table.Column.Usage> uit =
> aggColumn.getUsages(JdbcSchema.UsageType.LEVEL);
> uit.hasNext();) {
> JdbcSchema.Table.Column.Usage aggUsage = 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 {
> << BLOCK OF CODE >>
> }
>
> changed to:
>
> if (aggColumn.hasUsage(JdbcSchema.UsageType.LEVEL)) {
> // The column has at least one usage of level type
> // make sure we are looking at the
> // same table and column
> for (Iterator<JdbcSchema.Table.Column.Usage> uit =
> aggColumn.getUsages(JdbcSchema.UsageType.LEVEL);
> uit.hasNext(); ) {
> JdbcSchema.Table.Column.Usage aggUsage = uit.next();
>
> MondrianDef.Relation rel = hierarchyUsage.getJoinTable();
> String cName = levelColumnName;
>
> if (aggUsage.relation.equals(rel) &&
> aggColumn.column.name.equals(cName)) {
> return;
> }
> }
> }
>
> << BLOCK OF CODE >>
>
> mondrian-3.1.1.12687\src\main\mondrian\rolap\aggmatcher\AggTableManager.java
> line 475:
> RolapStar.Table rTable =
> star.getFactTable().findTableWithLeftJoinCondition(cname);
> if (rTable != null) {
> JdbcSchema.Table.Column.Usage usage =
> factColumn.newUsage(JdbcSchema.UsageType.FOREIGN_KEY);
> usage.setSymbolicName("FOREIGN_KEY");
> usage.rTable = rTable;
> } else {
>
> changed to:
>
> List<RolapStar.Table> rTables =
> star.getFactTable().findTablesWithLeftJoinCondition(cname);
> if (rTables != null) {
> for (RolapStar.Table rTable : rTables) {
> JdbcSchema.Table.Column.Usage usage =
>
> factColumn.newUsage(JdbcSchema.UsageType.FOREIGN_KEY);
> usage.setSymbolicName("FOREIGN_KEY");
> usage.rTable = rTable;
> }
> } else {
>
> mondrian-3.1.1.12687\src\main\mondrian\rolap\aggmatcher\ExplicitRules.java
> line 1055:
> // Is the level foreign key name a duplicate
> if (columnsToObjects.containsKey(level.getColumnName())) {
> Level l = (Level)
> columnsToObjects.get(level.getColumnName());
> msgRecorder.reportError(
> mres.DuplicateLevelColumnNames.str(
> msgRecorder.getContext(),
> level.getName(),
> l.getName(),
> level.getColumnName()));
> } else {
> columnsToObjects.put(level.getColumnName(), level);
> }
>
> removed
>
> mondrian-3.1.1.12687\src\main\mondrian\rolap\RolapStar.java
> added
>
> * Finds the child tables 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.
> */
> public List<RolapStar.Table> findTablesWithLeftJoinCondition(
> final String columnName)
> {
> List<RolapStar.Table> children = null;
>
> for (Table child : getChildren()) {
> 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)) {
> if (null == children) {
> children = new ArrayList<RolapStar.Table>();
> }
> children.add(child);
> }
> }
> }
> }
> return children;
> }
>
>
>
> On Wed, Jun 3, 2009 at 03:30, Pedro Alves <pedro at neraka.no-ip.org> wrote:
> >
> > I'm defining an aggregate table; I have 2 hierarchies in the same
> > dimension.
> >
> > Mondrian is throwing this error:
> >
> > 2009-06-02 19:24:07,837 ERROR [mondrian.rolap.aggmatcher.AggTableManager] BlockList Analysis:PatternTableDef:TableDef: Context 'BlockList Analysis:PatternTableDef:TableDef': Two levels, '[Locations.Countries].[Country name]' and '[Locations].[Country name]', share the same foreign column name 'locations_Country_name'
> >
> >
> > Isn't this possible?
>
> --
> Alexander Korsukov
> _____________________________________________________
> mailto:akorsukov at gmail.com icq:8572488
> (2E0A2052) xmpp:shko at jabber.ru
--
Pedro Alves
pmgalves-at-gmail.com
More information about the Mondrian
mailing list