[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