Program: 15949
Project: 15949
Buggy source:
/** 
 * Calculate the cost for the given mask as if this index was a typical b-tree range index. This is the estimated cost required to search one row, and then iterate over the given number of rows.
 * @param masks the search mask
 * @param rowCount the number of rows in the index
 * @param sortOrder the sort order
 * @return the estimated cost
 */
protected long getCostRangeIndex(int[] masks,long rowCount,SortOrder sortOrder){
  rowCount+=Constants.COST_ROW_OFFSET;
  long cost=rowCount;
  long rows=rowCount;
  int totalSelectivity=0;
  if (masks == null) {
    return cost;
  }
  for (int i=0, len=columns.length; i < len; i++) {
    Column column=columns[i];
    int index=column.getColumnId();
    int mask=masks[index];
    if ((mask & IndexCondition.EQUALITY) == IndexCondition.EQUALITY) {
      if (i == columns.length - 1 && getIndexType().isUnique()) {
        cost=3;
        break;
      }
      totalSelectivity=100 - ((100 - totalSelectivity) * (100 - column.getSelectivity()) / 100);
      long distinctRows=rowCount * totalSelectivity / 100;
      if (distinctRows <= 0) {
        distinctRows=1;
      }
      rows=Math.max(rowCount / distinctRows,1);
      cost=2 + rows;
    }
 else     if ((mask & IndexCondition.RANGE) == IndexCondition.RANGE) {
      cost=2 + rows / 4;
      break;
    }
 else     if ((mask & IndexCondition.START) == IndexCondition.START) {
      cost=2 + rows / 3;
      break;
    }
 else     if ((mask & IndexCondition.END) == IndexCondition.END) {
      cost=rows / 3;
      break;
    }
 else {
      break;
    }
  }
  if (sortOrder != null) {
    int[] columnIndexes=new int[indexColumns.length];
    int[] columnSortTypes=new int[indexColumns.length];
    for (int i=0, len=indexColumns.length; i < len; i++) {
      columnIndexes[i]=indexColumns[i].column.getColumnId();
      columnSortTypes[i]=indexColumns[i].sortType;
    }
    boolean sortOrderMatches=true;
    int[] sortOrderIndexes=sortOrder.getIndexes();
    int coveringCount=0;
    for (int i=0, len=sortOrderIndexes.length; i < len; i++) {
      if (i >= columnIndexes.length) {
        break;
      }
      if (columnIndexes[i] != sortOrderIndexes[i] || columnSortTypes[i] != sortOrder.getSortTypes()[i]) {
        sortOrderMatches=false;
        break;
      }
      coveringCount++;
    }
    if (sortOrderMatches) {
      cost-=coveringCount;
    }
  }
  return cost;
}

Fixed version (ground truth):
/** 
 * Calculate the cost for the given mask as if this index was a typical b-tree range index. This is the estimated cost required to search one row, and then iterate over the given number of rows.
 * @param masks the search mask
 * @param rowCount the number of rows in the index
 * @param sortOrder the sort order
 * @return the estimated cost
 */
protected long getCostRangeIndex(int[] masks,long rowCount,SortOrder sortOrder){
  rowCount+=Constants.COST_ROW_OFFSET;
  long cost=rowCount;
  long rows=rowCount;
  int totalSelectivity=0;
  if (masks == null) {
    return cost;
  }
  for (int i=0, len=columns.length; i < len; i++) {
    Column column=columns[i];
    int index=column.getColumnId();
    int mask=masks[index];
    if ((mask & IndexCondition.EQUALITY) == IndexCondition.EQUALITY) {
      if (i == columns.length - 1 && getIndexType().isUnique()) {
        cost=3;
        break;
      }
      totalSelectivity=100 - ((100 - totalSelectivity) * (100 - column.getSelectivity()) / 100);
      long distinctRows=rowCount * totalSelectivity / 100;
      if (distinctRows <= 0) {
        distinctRows=1;
      }
      rows=Math.max(rowCount / distinctRows,1);
      cost=2 + rows;
    }
 else     if ((mask & IndexCondition.RANGE) == IndexCondition.RANGE) {
      cost=2 + rows / 4;
      break;
    }
 else     if ((mask & IndexCondition.START) == IndexCondition.START) {
      cost=2 + rows / 3;
      break;
    }
 else     if ((mask & IndexCondition.END) == IndexCondition.END) {
      cost=rows / 3;
      break;
    }
 else {
      break;
    }
  }
  if (sortOrder != null) {
    int[] columnIndexes=new int[indexColumns.length];
    int[] columnSortTypes=new int[indexColumns.length];
    for (int i=0, len=indexColumns.length; i < len; i++) {
      columnIndexes[i]=indexColumns[i].column.getColumnId();
      columnSortTypes[i]=indexColumns[i].sortType;
    }
    boolean sortOrderMatches=true;
    int[] sortOrderQueryColumnIndexes=sortOrder.getQueryColumnIndexes();
    int coveringCount=0;
    int theFollowingNeedsToBeFixedAndTested;
    for (int i=0, len=sortOrderQueryColumnIndexes.length; i < len; i++) {
      if (i >= columnIndexes.length) {
        break;
      }
      if (columnIndexes[i] != sortOrderQueryColumnIndexes[i] || columnSortTypes[i] != sortOrder.getSortTypes()[i]) {
        sortOrderMatches=false;
        break;
      }
      coveringCount++;
    }
    if (sortOrderMatches) {
      cost-=coveringCount;
    }
  }
  return cost;
}