Search in sources :

Example 16 with AggStar

use of mondrian.rolap.aggmatcher.AggStar in project mondrian by pentaho.

the class SqlConstraintUtils method getColumnString.

/**
 * Returns the column expression for the level, assuring
 * appropriate tables are added to the from clause of
 * sqlQuery if required.
 * Determines the correct table and field based on the cube
 * and whether an AggStar is present.
 */
private static String getColumnString(SqlQuery sqlQuery, AggStar aggStar, RolapLevel level, RolapCube baseCube) {
    String columnString;
    RolapStar.Column column = null;
    if (level instanceof RolapCubeLevel) {
        // this method can be called within the context of shared members,
        // outside of the normal rolap star, therefore we need to
        // check the level to see if it is a shared or cube level.
        column = ((RolapCubeLevel) level).getBaseStarKeyColumn(baseCube);
    }
    // REVIEW: The following code mostly uses the name column (or name
    // expression) of the level. Shouldn't it use the key column (or key
    // expression)?
    RolapHierarchy hierarchy = level.getHierarchy();
    if (column != null) {
        if (aggStar != null) {
            // this assumes that the name column is identical to the
            // id column
            int bitPos = column.getBitPosition();
            AggStar.Table.Column aggColumn = aggStar.lookupColumn(bitPos);
            AggStar.Table table = aggColumn.getTable();
            table.addToFrom(sqlQuery, false, true);
            columnString = aggColumn.generateExprString(sqlQuery);
        } else {
            RolapStar.Table targetTable = column.getTable();
            hierarchy.addToFrom(sqlQuery, targetTable);
            columnString = column.generateExprString(sqlQuery);
        }
    } else {
        assert (aggStar == null);
        hierarchy.addToFrom(sqlQuery, level.getKeyExp());
        MondrianDef.Expression nameExp = level.getNameExp();
        if (nameExp == null) {
            nameExp = level.getKeyExp();
        }
        columnString = nameExp.getExpression(sqlQuery);
    }
    return columnString;
}
Also used : Table(mondrian.rolap.RolapStar.Table) MondrianDef(mondrian.olap.MondrianDef) AggStar(mondrian.rolap.aggmatcher.AggStar) Column(mondrian.rolap.RolapStar.Column) Table(mondrian.rolap.RolapStar.Table)

Example 17 with AggStar

use of mondrian.rolap.aggmatcher.AggStar in project mondrian by pentaho.

the class SqlMemberSource method makeChildMemberSql.

/**
 * Generates the SQL statement to access the children of
 * <code>member</code>. For example, <blockquote>
 *
 * <pre>SELECT "city"
 * FROM "customer"
 * WHERE "country" = 'USA'
 * AND "state_province" = 'BC'
 * GROUP BY "city"</pre>
 * </blockquote> retrieves the children of the member
 * <code>[Canada].[BC]</code>.
 * <p>Note that this method is never called in the context of
 * virtual cubes, it is only called on regular cubes.
 *
 * <p>See also {@link SqlTupleReader#makeLevelMembersSql}.
 */
Pair<String, List<SqlStatement.Type>> makeChildMemberSql(RolapMember member, DataSource dataSource, MemberChildrenConstraint constraint) {
    SqlQuery sqlQuery = SqlQuery.newQuery(dataSource, "while generating query to retrieve children of member " + member);
    // If this is a non-empty constraint, it is more efficient to join to
    // an aggregate table than to the fact table. See whether a suitable
    // aggregate table exists.
    AggStar aggStar = chooseAggStar(constraint, member);
    // Create the condition, which is either the parent member or
    // the full context (non empty).
    constraint.addMemberConstraint(sqlQuery, null, aggStar, member);
    RolapLevel level = (RolapLevel) member.getLevel().getChildLevel();
    boolean levelCollapsed = (aggStar != null) && isLevelCollapsed(aggStar, (RolapCubeLevel) level);
    boolean multipleCols = SqlMemberSource.levelContainsMultipleColumns(level);
    if (levelCollapsed && !multipleCols) {
        // if this is a single column collapsed level, there is
        // no need to join it with dimension tables
        RolapStar.Column starColumn = ((RolapCubeLevel) level).getStarKeyColumn();
        int bitPos = starColumn.getBitPosition();
        AggStar.Table.Column aggColumn = aggStar.lookupColumn(bitPos);
        String q = aggColumn.generateExprString(sqlQuery);
        final String qAlias = sqlQuery.addSelectGroupBy(q, starColumn.getInternalType());
        sqlQuery.addOrderBy(q, qAlias, true, false, true, true);
        aggColumn.getTable().addToFrom(sqlQuery, false, true);
        return sqlQuery.toSqlAndTypes();
    }
    hierarchy.addToFrom(sqlQuery, level.getKeyExp());
    String q = level.getKeyExp().getExpression(sqlQuery);
    String idAlias = sqlQuery.addSelectGroupBy(q, level.getInternalType());
    // in non empty mode the level table must be joined to the fact
    // table
    constraint.addLevelConstraint(sqlQuery, null, aggStar, level);
    if (levelCollapsed) {
        // if this is a collapsed level, add a join between key and aggstar
        RolapStar.Column starColumn = ((RolapCubeLevel) level).getStarKeyColumn();
        int bitPos = starColumn.getBitPosition();
        AggStar.Table.Column aggColumn = aggStar.lookupColumn(bitPos);
        RolapStar.Condition condition = new RolapStar.Condition(level.getKeyExp(), aggColumn.getExpression());
        sqlQuery.addWhere(condition.toString(sqlQuery));
        hierarchy.addToFromInverse(sqlQuery, level.getKeyExp());
        // also may need to join parent levels to make selection unique
        RolapCubeLevel parentLevel = (RolapCubeLevel) level.getParentLevel();
        boolean isUnique = level.isUnique();
        while (parentLevel != null && !parentLevel.isAll() && !isUnique) {
            hierarchy.addToFromInverse(sqlQuery, parentLevel.getKeyExp());
            starColumn = parentLevel.getStarKeyColumn();
            bitPos = starColumn.getBitPosition();
            aggColumn = aggStar.lookupColumn(bitPos);
            condition = new RolapStar.Condition(parentLevel.getKeyExp(), aggColumn.getExpression());
            sqlQuery.addWhere(condition.toString(sqlQuery));
            parentLevel = parentLevel.getParentLevel();
        }
    }
    if (level.hasCaptionColumn()) {
        MondrianDef.Expression captionExp = level.getCaptionExp();
        if (!levelCollapsed) {
            hierarchy.addToFrom(sqlQuery, captionExp);
        }
        String captionSql = captionExp.getExpression(sqlQuery);
        sqlQuery.addSelectGroupBy(captionSql, null);
    }
    if (!levelCollapsed) {
        hierarchy.addToFrom(sqlQuery, level.getOrdinalExp());
    }
    final String orderBy = level.getOrdinalExp().getExpression(sqlQuery);
    if (!orderBy.equals(q)) {
        String orderAlias = sqlQuery.addSelectGroupBy(orderBy, null);
        sqlQuery.addOrderBy(orderBy, orderAlias, true, false, true, true);
    } else {
        sqlQuery.addOrderBy(q, idAlias, true, false, true, true);
    }
    RolapProperty[] properties = level.getProperties();
    for (RolapProperty property : properties) {
        final MondrianDef.Expression exp = property.getExp();
        if (!levelCollapsed) {
            hierarchy.addToFrom(sqlQuery, exp);
        }
        final String s = exp.getExpression(sqlQuery);
        String alias = sqlQuery.addSelect(s, null);
        // group by that are functionally dependent on the level value
        if (!sqlQuery.getDialect().allowsSelectNotInGroupBy() || !property.dependsOnLevelValue()) {
            sqlQuery.addGroupBy(s, alias);
        }
    }
    return sqlQuery.toSqlAndTypes();
}
Also used : AggStar(mondrian.rolap.aggmatcher.AggStar)

Aggregations

AggStar (mondrian.rolap.aggmatcher.AggStar)17 Table (mondrian.rolap.RolapStar.Table)6 Column (mondrian.rolap.RolapStar.Column)5 SqlPattern (mondrian.test.SqlPattern)3 TestContext (mondrian.test.TestContext)3 HashMap (java.util.HashMap)2 MondrianDef (mondrian.olap.MondrianDef)2 SqlQuery (mondrian.rolap.sql.SqlQuery)2 ArrayList (java.util.ArrayList)1 Iterator (java.util.Iterator)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 TupleList (mondrian.calc.TupleList)1 ListColumnPredicate (mondrian.rolap.agg.ListColumnPredicate)1 JdbcSchema (mondrian.rolap.aggmatcher.JdbcSchema)1 TupleConstraint (mondrian.rolap.sql.TupleConstraint)1 Dialect (mondrian.spi.Dialect)1 FilteredIterableList (mondrian.util.FilteredIterableList)1