[Mondrian] AggTableManager: Two levels share the same foreign key column

Alexander Korsukov akorsukov at gmail.com
Tue Jun 2 21:09:22 EDT 2009


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




More information about the Mondrian mailing list