Program: 63283
Project: 63283
Buggy source:
/** 
 * For the new segment, we need to create dictionaries for it, too. For those dictionaries on fact table, create it by merging underlying dictionaries For those dictionaries on lookup table, just copy it from any one of the merging segments, it's guaranteed to be consistent(checked in CubeSegmentValidator)
 * @param cube
 * @param newSeg
 * @throws IOException
 */
private void makeDictForNewSegment(CubeInstance cube,CubeSegment newSeg,List<CubeSegment> mergingSegments) throws IOException {
  HashSet<TblColRef> colsNeedMeringDict=new HashSet<TblColRef>();
  HashSet<TblColRef> colsNeedCopyDict=new HashSet<TblColRef>();
  DictionaryManager dictMgr=this.getDictionaryManager();
  CubeDesc descriptor=cube.getDescriptor();
  for (  DimensionDesc dim : descriptor.getDimensions()) {
    for (    TblColRef col : dim.getColumnRefs()) {
      if (newSeg.getCubeDesc().getRowkey().isUseDictionary(col)) {
        if (descriptor.getFactTable().equalsIgnoreCase((String)dictMgr.decideSourceData(descriptor,col,null)[0])) {
          colsNeedMeringDict.add(col);
        }
 else {
          colsNeedCopyDict.add(col);
        }
      }
    }
  }
  for (  TblColRef col : colsNeedMeringDict) {
    logger.info("String_Node_Str" + col);
    List<DictionaryInfo> dictInfos=new ArrayList<DictionaryInfo>();
    for (    CubeSegment segment : mergingSegments) {
      logger.info("String_Node_Str" + segment);
      DictionaryInfo dictInfo=dictMgr.getDictionaryInfo(segment.getDictResPath(col));
      dictInfos.add(dictInfo);
    }
    this.mergeDictionaries(newSeg,dictInfos,col);
  }
  for (  TblColRef col : colsNeedCopyDict) {
    String path=mergingSegments.get(0).getDictResPath(col);
    newSeg.putDictResPath(col,path);
  }
}

Fixed version (ground truth):
/** 
 * For the new segment, we need to create dictionaries for it, too. For those dictionaries on fact table, create it by merging underlying dictionaries For those dictionaries on lookup table, just copy it from any one of the merging segments, it's guaranteed to be consistent(checked in CubeSegmentValidator)
 * @param cube
 * @param newSeg
 * @throws IOException
 */
private void makeDictForNewSegment(CubeInstance cube,CubeSegment newSeg) throws IOException {
  List<CubeSegment> mergingSegments=cube.getMergingSegments(newSeg);
  HashSet<TblColRef> colsNeedMeringDict=new HashSet<TblColRef>();
  HashSet<TblColRef> colsNeedCopyDict=new HashSet<TblColRef>();
  DictionaryManager dictMgr=this.getDictionaryManager();
  for (  DimensionDesc dim : cube.getDescriptor().getDimensions()) {
    for (    TblColRef col : dim.getColumnRefs()) {
      if (newSeg.getCubeDesc().getRowkey().isUseDictionary(col)) {
        if (cube.getDescriptor().getFactTable().equalsIgnoreCase((String)dictMgr.decideSourceData(cube.getDescriptor(),col,null)[0])) {
          colsNeedMeringDict.add(col);
        }
 else {
          colsNeedCopyDict.add(col);
        }
      }
    }
  }
  for (  TblColRef col : colsNeedMeringDict) {
    logger.info("String_Node_Str" + col);
    List<DictionaryInfo> dictInfos=new ArrayList<DictionaryInfo>();
    for (    CubeSegment segment : mergingSegments) {
      logger.info("String_Node_Str" + segment);
      DictionaryInfo dictInfo=dictMgr.getDictionaryInfo(segment.getDictResPath(col));
      dictInfos.add(dictInfo);
    }
    this.mergeDictionaries(newSeg,dictInfos,col);
  }
  for (  TblColRef col : colsNeedCopyDict) {
    String path=mergingSegments.get(0).getDictResPath(col);
    newSeg.putDictResPath(col,path);
  }
}