Program: 30767
Project: 30767
Buggy source:
/** 
 * Adds new column to table, which can be either empty or can have data already. When existing columns already have data this function will create ".top" file in addition to column files. ".top" file contains size of partition at the moment of column creation. It must be used to accurately position inside new column when either appending or reading. <p> <b>Failures</b> Adding new column can fail in many different situations. None of the failures affect integrity of data that is already in the table but can leave instance of TableWriter in inconsistent state. When this happens function will throw CairoError. Calling code must close TableWriter instance and open another when problems are rectified. Those problems would be either with disk or memory or both. <p> Whenever function throws CairoException application code can continue using TableWriter instance and may attempt to add columns again. <p> <b>Transactions</b> <p> Pending transaction will be committed before function attempts to add column. Even when function is unsuccessful it may still have committed transaction.
 * @param name            of column either ASCII or UTF8 encoded.
 * @param symbolCapacity  when column type is SYMBOL this parameter specifies approximate capacity for symbol map.It should be equal to number of unique symbol values stored in the table and getting this value badly wrong will cause performance degradation.
 * @param symbolCacheFlag when set to true, symbol values will be cached on Java heap.
 * @param type            {@link ColumnType}
 */
public void addColumn(CharSequence name,int type,int symbolCapacity,boolean symbolCacheFlag){
  if (getColumnIndexQuiet(metaMem,name,columnCount) != -1) {
    throw CairoException.instance(0).put("String_Node_Str").put(name);
  }
  LOG.info().$("String_Node_Str").utf8(name).$('[').$(ColumnType.nameOf(type)).$("String_Node_Str").$(path).$();
  commit();
  if (type == ColumnType.SYMBOL) {
    removeSymbolMapFilesLoud(name);
  }
  removeColumnFiles(name,REMOVE_OR_EXCEPTION);
  this.metaSwapIndex=addColumnToMeta(name,type);
  metaMem.close();
  renameMetaToMetaPrev(name);
  writeRestoreMetaTodo(name);
  renameSwapMetaToMeta(name);
  if (type == ColumnType.SYMBOL) {
    try {
      createSymbolMapWriter(name,symbolCapacity,symbolCacheFlag);
    }
 catch (    CairoException e) {
      runFragile(RECOVER_FROM_SYMBOL_MAP_WRITER_FAILURE,name,e);
    }
  }
  configureColumn(type);
  columnCount++;
  columnTops.extendAndSet(columnCount - 1,transientRowCount);
  if (transientRowCount > 0 || partitionBy == PartitionBy.NONE) {
    try {
      openNewColumnFiles(name);
    }
 catch (    CairoException e) {
      runFragile(RECOVER_FROM_COLUMN_OPEN_FAILURE,name,e);
    }
  }
  try {
    openMetaFile();
    removeTodoFile();
  }
 catch (  CairoException err) {
    throw new CairoError(err);
  }
  bumpStructureVersion();
  metadata.addColumn(name,type);
  LOG.info().$("String_Node_Str").utf8(name).$('[').$(ColumnType.nameOf(type)).$("String_Node_Str").$(path).$();
}

Fixed version (ground truth):
/** 
 * Adds new column to table, which can be either empty or can have data already. When existing columns already have data this function will create ".top" file in addition to column files. ".top" file contains size of partition at the moment of column creation. It must be used to accurately position inside new column when either appending or reading. <p> <b>Failures</b> Adding new column can fail in many different situations. None of the failures affect integrity of data that is already in the table but can leave instance of TableWriter in inconsistent state. When this happens function will throw CairoError. Calling code must close TableWriter instance and open another when problems are rectified. Those problems would be either with disk or memory or both. <p> Whenever function throws CairoException application code can continue using TableWriter instance and may attempt to add columns again. <p> <b>Transactions</b> <p> Pending transaction will be committed before function attempts to add column. Even when function is unsuccessful it may still have committed transaction.
 * @param name            of column either ASCII or UTF8 encoded.
 * @param symbolCapacity  when column type is SYMBOL this parameter specifies approximate capacity for symbol map.It should be equal to number of unique symbol values stored in the table and getting this value badly wrong will cause performance degradation.
 * @param symbolCacheFlag when set to true, symbol values will be cached on Java heap.
 * @param type            {@link ColumnType}
 */
public void addColumn(CharSequence name,int type,int symbolCapacity,boolean symbolCacheFlag){
  if (getColumnIndexQuiet(metaMem,name,columnCount) != -1) {
    throw CairoException.instance(0).put("String_Node_Str").put(name);
  }
  LOG.info().$("String_Node_Str").utf8(name).$('[').$(ColumnType.nameOf(type)).$("String_Node_Str").$(path).$();
  commit();
  removeColumnFiles(name,type,REMOVE_OR_EXCEPTION);
  this.metaSwapIndex=addColumnToMeta(name,type);
  metaMem.close();
  renameMetaToMetaPrev(name);
  writeRestoreMetaTodo(name);
  renameSwapMetaToMeta(name);
  if (type == ColumnType.SYMBOL) {
    try {
      createSymbolMapWriter(name,symbolCapacity,symbolCacheFlag);
    }
 catch (    CairoException e) {
      runFragile(RECOVER_FROM_SYMBOL_MAP_WRITER_FAILURE,name,e);
    }
  }
  configureColumn(type);
  columnCount++;
  columnTops.extendAndSet(columnCount - 1,transientRowCount);
  if (transientRowCount > 0 || partitionBy == PartitionBy.NONE) {
    try {
      openNewColumnFiles(name);
    }
 catch (    CairoException e) {
      runFragile(RECOVER_FROM_COLUMN_OPEN_FAILURE,name,e);
    }
  }
  try {
    openMetaFile();
    removeTodoFile();
  }
 catch (  CairoException err) {
    throw new CairoError(err);
  }
  bumpStructureVersion();
  metadata.addColumn(name,type);
  LOG.info().$("String_Node_Str").utf8(name).$('[').$(ColumnType.nameOf(type)).$("String_Node_Str").$(path).$();
}