Program: 50877
Project: 50877
Buggy source:
/** 
 * Generates the SQL statement to access members of <code>level</code>. For example, <blockquote> <pre>SELECT "country", "state_province", "city" FROM "customer" GROUP BY "country", "state_province", "city", "init", "bar" ORDER BY "country", "state_province", "city"</pre> </blockquote> accesses the "City" level of the "Customers" hierarchy. Note that:<ul> <li><code>"country", "state_province"</code> are the parent keys;</li> <li><code>"city"</code> is the level key;</li> <li><code>"init", "bar"</code> are member properties.</li> </ul>
 * @param sqlQuery the query object being constructed
 * @param level level to be added to the sql query
 * @param baseCube this is the cube object for regular cubes, and theunderlying base cube for virtual cubes
 * @param whichSelect describes whether this select belongs to a larger
 * @param aggStar aggregate star if available
 */
protected void addLevelMemberSql(SqlQuery sqlQuery,RolapLevel level,RolapCube baseCube,WhichSelect whichSelect,AggStar aggStar){
  RolapHierarchy hierarchy=level.getHierarchy();
  if (hierarchy instanceof RolapCubeHierarchy) {
    RolapCubeHierarchy cubeHierarchy=(RolapCubeHierarchy)hierarchy;
    if (baseCube != null && !cubeHierarchy.getCube().equals(baseCube)) {
      hierarchy=baseCube.findBaseCubeHierarchy(hierarchy);
    }
  }
  RolapLevel[] levels=(RolapLevel[])hierarchy.getLevels();
  int levelDepth=level.getDepth();
  boolean needsGroupBy=isGroupByNeeded(sqlQuery,hierarchy,levels,levelDepth);
  for (int i=0; i <= levelDepth; i++) {
    RolapLevel currLevel=levels[i];
    if (currLevel.isAll()) {
      continue;
    }
    boolean levelCollapsed=(aggStar != null) && SqlMemberSource.isLevelCollapsed(aggStar,(RolapCubeLevel)currLevel);
    boolean multipleCols=SqlMemberSource.levelContainsMultipleColumns(currLevel);
    if (levelCollapsed && !multipleCols) {
      RolapStar.Column starColumn=((RolapCubeLevel)currLevel).getStarKeyColumn();
      int bitPos=starColumn.getBitPosition();
      AggStar.Table.Column aggColumn=aggStar.lookupColumn(bitPos);
      String q=aggColumn.generateExprString(sqlQuery);
      sqlQuery.addSelectGroupBy(q,starColumn.getInternalType());
      if (whichSelect == WhichSelect.ONLY) {
        sqlQuery.addOrderBy(q,true,false,true);
      }
      aggColumn.getTable().addToFrom(sqlQuery,false,true);
      continue;
    }
    MondrianDef.Expression keyExp=currLevel.getKeyExp();
    MondrianDef.Expression ordinalExp=currLevel.getOrdinalExp();
    MondrianDef.Expression captionExp=currLevel.getCaptionExp();
    MondrianDef.Expression parentExp=currLevel.getParentExp();
    if (parentExp != null) {
      if (!levelCollapsed) {
        hierarchy.addToFrom(sqlQuery,parentExp);
      }
      String parentSql=parentExp.getExpression(sqlQuery);
      sqlQuery.addSelectGroupBy(parentSql,currLevel.getInternalType());
      if (whichSelect == WhichSelect.LAST || whichSelect == WhichSelect.ONLY) {
        sqlQuery.addOrderBy(parentSql,true,false,true,false);
      }
    }
    String keySql=keyExp.getExpression(sqlQuery);
    String ordinalSql=ordinalExp.getExpression(sqlQuery);
    if (!levelCollapsed) {
      hierarchy.addToFrom(sqlQuery,keyExp);
      hierarchy.addToFrom(sqlQuery,ordinalExp);
    }
    String captionSql=null;
    if (captionExp != null) {
      captionSql=captionExp.getExpression(sqlQuery);
      if (!levelCollapsed) {
        hierarchy.addToFrom(sqlQuery,captionExp);
      }
    }
    String alias=sqlQuery.addSelect(keySql,currLevel.getInternalType());
    if (needsGroupBy) {
      sqlQuery.addGroupBy(keySql,alias);
    }
    if (captionSql != null) {
      alias=sqlQuery.addSelect(captionSql,null);
      if (needsGroupBy) {
        sqlQuery.addGroupBy(captionSql,alias);
      }
    }
    if (!ordinalSql.equals(keySql)) {
      alias=sqlQuery.addSelect(ordinalSql,null);
      if (needsGroupBy) {
        sqlQuery.addGroupBy(ordinalSql,alias);
      }
    }
    constraint.addLevelConstraint(sqlQuery,baseCube,aggStar,currLevel);
    if (levelCollapsed) {
      hierarchy.addToFromInverse(sqlQuery,keyExp);
      RolapStar.Column starColumn=((RolapCubeLevel)currLevel).getStarKeyColumn();
      int bitPos=starColumn.getBitPosition();
      AggStar.Table.Column aggColumn=aggStar.lookupColumn(bitPos);
      RolapStar.Condition condition=new RolapStar.Condition(keyExp,aggColumn.getExpression());
      sqlQuery.addWhere(condition.toString(sqlQuery));
    }
    if (whichSelect == WhichSelect.ONLY) {
      sqlQuery.addOrderBy(ordinalSql,true,false,true);
    }
    RolapProperty[] properties=currLevel.getProperties();
    for (    RolapProperty property : properties) {
      final MondrianDef.Expression propExp=property.getExp();
      final String propSql;
      if (propExp instanceof MondrianDef.Column) {
        propSql=sqlQuery.getDialect().quoteIdentifier(currLevel.getTableAlias(),((MondrianDef.Column)propExp).name);
      }
 else {
        propSql=property.getExp().getExpression(sqlQuery);
      }
      alias=sqlQuery.addSelect(propSql,null);
      if (needsGroupBy) {
        if (!sqlQuery.getDialect().allowsSelectNotInGroupBy() || !property.dependsOnLevelValue()) {
          sqlQuery.addGroupBy(propSql,alias);
        }
      }
    }
  }
}

Fixed version (ground truth):
/** 
 * Generates the SQL statement to access members of <code>level</code>. For example, <blockquote> <pre>SELECT "country", "state_province", "city" FROM "customer" GROUP BY "country", "state_province", "city", "init", "bar" ORDER BY "country", "state_province", "city"</pre> </blockquote> accesses the "City" level of the "Customers" hierarchy. Note that:<ul> <li><code>"country", "state_province"</code> are the parent keys;</li> <li><code>"city"</code> is the level key;</li> <li><code>"init", "bar"</code> are member properties.</li> </ul>
 * @param sqlQuery the query object being constructed
 * @param level level to be added to the sql query
 * @param baseCube this is the cube object for regular cubes, and theunderlying base cube for virtual cubes
 * @param whichSelect describes whether this select belongs to a larger
 * @param aggStar aggregate star if available
 */
protected void addLevelMemberSql(SqlQuery sqlQuery,RolapLevel level,RolapCube baseCube,WhichSelect whichSelect,AggStar aggStar){
  RolapHierarchy hierarchy=level.getHierarchy();
  if (hierarchy instanceof RolapCubeHierarchy) {
    RolapCubeHierarchy cubeHierarchy=(RolapCubeHierarchy)hierarchy;
    if (baseCube != null && !cubeHierarchy.getCube().equals(baseCube)) {
      hierarchy=baseCube.findBaseCubeHierarchy(hierarchy);
    }
  }
  RolapLevel[] levels=(RolapLevel[])hierarchy.getLevels();
  int levelDepth=level.getDepth();
  boolean needsGroupBy=isGroupByNeeded(sqlQuery,hierarchy,levels,levelDepth);
  for (int i=0; i <= levelDepth; i++) {
    RolapLevel currLevel=levels[i];
    if (currLevel.isAll()) {
      continue;
    }
    boolean levelCollapsed=(aggStar != null) && SqlMemberSource.isLevelCollapsed(aggStar,(RolapCubeLevel)currLevel);
    boolean multipleCols=SqlMemberSource.levelContainsMultipleColumns(currLevel);
    if (levelCollapsed && !multipleCols) {
      RolapStar.Column starColumn=((RolapCubeLevel)currLevel).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());
      if (whichSelect == WhichSelect.ONLY) {
        sqlQuery.addOrderBy(q,qAlias,true,false,true,true);
      }
      aggColumn.getTable().addToFrom(sqlQuery,false,true);
      continue;
    }
    MondrianDef.Expression keyExp=currLevel.getKeyExp();
    MondrianDef.Expression ordinalExp=currLevel.getOrdinalExp();
    MondrianDef.Expression captionExp=currLevel.getCaptionExp();
    MondrianDef.Expression parentExp=currLevel.getParentExp();
    if (parentExp != null) {
      if (!levelCollapsed) {
        hierarchy.addToFrom(sqlQuery,parentExp);
      }
      if (whichSelect == WhichSelect.LAST || whichSelect == WhichSelect.ONLY) {
        final String parentSql=parentExp.getExpression(sqlQuery);
        final String parentAlias=sqlQuery.addSelectGroupBy(parentSql,currLevel.getInternalType());
        sqlQuery.addOrderBy(parentSql,parentAlias,true,false,true,false);
      }
    }
    String keySql=keyExp.getExpression(sqlQuery);
    String ordinalSql=ordinalExp.getExpression(sqlQuery);
    if (!levelCollapsed) {
      hierarchy.addToFrom(sqlQuery,keyExp);
      hierarchy.addToFrom(sqlQuery,ordinalExp);
    }
    String captionSql=null;
    if (captionExp != null) {
      captionSql=captionExp.getExpression(sqlQuery);
      if (!levelCollapsed) {
        hierarchy.addToFrom(sqlQuery,captionExp);
      }
    }
    final String keyAlias=sqlQuery.addSelect(keySql,currLevel.getInternalType());
    if (needsGroupBy) {
      sqlQuery.addGroupBy(keySql,keyAlias);
    }
    if (captionSql != null) {
      final String captionAlias=sqlQuery.addSelect(captionSql,null);
      if (needsGroupBy) {
        sqlQuery.addGroupBy(captionSql,captionAlias);
      }
    }
    final String orderByAlias;
    if (!ordinalSql.equals(keySql)) {
      orderByAlias=sqlQuery.addSelect(ordinalSql,null);
      if (needsGroupBy) {
        sqlQuery.addGroupBy(ordinalSql,orderByAlias);
      }
      if (whichSelect == WhichSelect.ONLY) {
        sqlQuery.addOrderBy(ordinalSql,orderByAlias,true,false,true,true);
      }
    }
 else {
      if (whichSelect == WhichSelect.ONLY) {
        sqlQuery.addOrderBy(keySql,keyAlias,true,false,true,true);
      }
    }
    constraint.addLevelConstraint(sqlQuery,baseCube,aggStar,currLevel);
    if (levelCollapsed) {
      hierarchy.addToFromInverse(sqlQuery,keyExp);
      RolapStar.Column starColumn=((RolapCubeLevel)currLevel).getStarKeyColumn();
      int bitPos=starColumn.getBitPosition();
      AggStar.Table.Column aggColumn=aggStar.lookupColumn(bitPos);
      RolapStar.Condition condition=new RolapStar.Condition(keyExp,aggColumn.getExpression());
      sqlQuery.addWhere(condition.toString(sqlQuery));
    }
    RolapProperty[] properties=currLevel.getProperties();
    for (    RolapProperty property : properties) {
      final MondrianDef.Expression propExp=property.getExp();
      final String propSql;
      if (propExp instanceof MondrianDef.Column) {
        propSql=sqlQuery.getDialect().quoteIdentifier(currLevel.getTableAlias(),((MondrianDef.Column)propExp).name);
      }
 else {
        propSql=property.getExp().getExpression(sqlQuery);
      }
      final String propAlias=sqlQuery.addSelect(propSql,null);
      if (needsGroupBy) {
        if (!sqlQuery.getDialect().allowsSelectNotInGroupBy() || !property.dependsOnLevelValue()) {
          sqlQuery.addGroupBy(propSql,propAlias);
        }
      }
    }
  }
}