Program: 15880
Project: 15880
Buggy source:
@Override public Index addIndex(Session session,String indexName,int indexId,IndexColumn[] cols,IndexType indexType,boolean create,String indexComment){
  if (indexType.isPrimaryKey()) {
    for (    IndexColumn c : cols) {
      Column column=c.column;
      if (column.isNullable()) {
        throw DbException.get(ErrorCode.COLUMN_MUST_NOT_BE_NULLABLE_1,column.getName());
      }
      column.setPrimaryKey(true);
    }
  }
  boolean isSessionTemporary=isTemporary() && !isGlobalTemporary();
  if (!isSessionTemporary) {
    database.lockMeta(session);
  }
  Index index;
  int mainIndexColumn;
  mainIndexColumn=getMainIndexColumn(indexType,cols);
  if (database.isStarting()) {
    if (store.store.hasMap("String_Node_Str" + indexId)) {
      mainIndexColumn=-1;
    }
  }
 else   if (primaryIndex.getRowCount(session) != 0) {
    mainIndexColumn=-1;
  }
  if (mainIndexColumn != -1) {
    primaryIndex.setMainIndexColumn(mainIndexColumn);
    index=new MVDelegateIndex(this,indexId,indexName,primaryIndex,indexType);
  }
 else   if (indexType.isSpatial()) {
    index=new SpatialTreeIndex(this,indexId,indexName,cols,indexType,true,create,session);
  }
 else {
    index=new MVSecondaryIndex(session.getDatabase(),this,indexId,indexName,cols,indexType);
  }
  if (index.needRebuild() && rowCount > 0) {
    try {
      Index scan=getScanIndex(session);
      long remaining=scan.getRowCount(session);
      long total=remaining;
      Cursor cursor=scan.find(session,null,null);
      long i=0;
      int bufferSize=(int)Math.min(rowCount,Constants.DEFAULT_MAX_MEMORY_ROWS);
      ArrayList<Row> buffer=New.arrayList(bufferSize);
      String n=getName() + "String_Node_Str" + index.getName();
      int t=MathUtils.convertLongToInt(total);
      while (cursor.next()) {
        Row row=cursor.get();
        buffer.add(row);
        database.setProgress(DatabaseEventListener.STATE_CREATE_INDEX,n,MathUtils.convertLongToInt(i++),t);
        if (buffer.size() >= bufferSize) {
          addRowsToIndex(session,buffer,index);
        }
        remaining--;
      }
      addRowsToIndex(session,buffer,index);
      if (SysProperties.CHECK && remaining != 0) {
        DbException.throwInternalError("String_Node_Str" + remaining + "String_Node_Str"+ getName());
      }
    }
 catch (    DbException e) {
      getSchema().freeUniqueName(indexName);
      try {
        index.remove(session);
      }
 catch (      DbException e2) {
        trace.error(e2,"String_Node_Str");
        throw e2;
      }
      throw e;
    }
  }
  index.setTemporary(isTemporary());
  if (index.getCreateSQL() != null) {
    index.setComment(indexComment);
    if (isSessionTemporary) {
      session.addLocalTempTableIndex(index);
    }
 else {
      database.addSchemaObject(session,index);
    }
  }
  indexes.add(index);
  setModified();
  return index;
}

Fixed version (ground truth):
@Override public Index addIndex(Session session,String indexName,int indexId,IndexColumn[] cols,IndexType indexType,boolean create,String indexComment){
  if (indexType.isPrimaryKey()) {
    for (    IndexColumn c : cols) {
      Column column=c.column;
      if (column.isNullable()) {
        throw DbException.get(ErrorCode.COLUMN_MUST_NOT_BE_NULLABLE_1,column.getName());
      }
      column.setPrimaryKey(true);
    }
  }
  boolean isSessionTemporary=isTemporary() && !isGlobalTemporary();
  if (!isSessionTemporary) {
    database.lockMeta(session);
  }
  Index index;
  int mainIndexColumn;
  mainIndexColumn=getMainIndexColumn(indexType,cols);
  if (database.isStarting()) {
    if (store.store.hasMap("String_Node_Str" + indexId)) {
      mainIndexColumn=-1;
    }
  }
 else   if (primaryIndex.getRowCount(session) != 0) {
    mainIndexColumn=-1;
  }
  if (mainIndexColumn != -1) {
    primaryIndex.setMainIndexColumn(mainIndexColumn);
    index=new MVDelegateIndex(this,indexId,indexName,primaryIndex,indexType);
  }
 else   if (indexType.isSpatial()) {
    int todo;
    index=new SpatialTreeIndex(this,indexId,indexName,cols,indexType,true,create,session);
  }
 else {
    index=new MVSecondaryIndex(session.getDatabase(),this,indexId,indexName,cols,indexType);
  }
  if (index.needRebuild() && rowCount > 0) {
    try {
      Index scan=getScanIndex(session);
      long remaining=scan.getRowCount(session);
      long total=remaining;
      Cursor cursor=scan.find(session,null,null);
      long i=0;
      int bufferSize=(int)Math.min(rowCount,Constants.DEFAULT_MAX_MEMORY_ROWS);
      ArrayList<Row> buffer=New.arrayList(bufferSize);
      String n=getName() + "String_Node_Str" + index.getName();
      int t=MathUtils.convertLongToInt(total);
      while (cursor.next()) {
        Row row=cursor.get();
        buffer.add(row);
        database.setProgress(DatabaseEventListener.STATE_CREATE_INDEX,n,MathUtils.convertLongToInt(i++),t);
        if (buffer.size() >= bufferSize) {
          addRowsToIndex(session,buffer,index);
        }
        remaining--;
      }
      addRowsToIndex(session,buffer,index);
      if (SysProperties.CHECK && remaining != 0) {
        DbException.throwInternalError("String_Node_Str" + remaining + "String_Node_Str"+ getName());
      }
    }
 catch (    DbException e) {
      getSchema().freeUniqueName(indexName);
      try {
        index.remove(session);
      }
 catch (      DbException e2) {
        trace.error(e2,"String_Node_Str");
        throw e2;
      }
      throw e;
    }
  }
  index.setTemporary(isTemporary());
  if (index.getCreateSQL() != null) {
    index.setComment(indexComment);
    if (isSessionTemporary) {
      session.addLocalTempTableIndex(index);
    }
 else {
      database.addSchemaObject(session,index);
    }
  }
  indexes.add(index);
  setModified();
  return index;
}