Program: 74020
Project: 74020
Buggy source:
/** 
 * Execute the SQL query given in the specified string and return an array of record tokens containing the results. Note that if there is no connection to the database, this will open one. The caller is responsible for calling closeConnection() after this.
 * @param sql The query.
 * @return An array of record tokens containing the results,which may be empty (zero length), or null if the connection fails or is canceled.
 * @exception IllegalActionException If the query fails.
 */
public ArrayToken executeQuery(String sql) throws IllegalActionException {
  PreparedStatement statement=null;
  ArrayList<RecordToken> matches=new ArrayList<RecordToken>();
  try {
    Connection connection=getConnection();
    if (connection == null) {
      return null;
    }
    statement=connection.prepareStatement(sql);
    ResultSet rset=statement.executeQuery();
    ResultSetMetaData metaData=rset.getMetaData();
    int columnCount=metaData.getColumnCount();
    while (rset.next()) {
      HashMap<String,Token> map=new HashMap<String,Token>();
      for (int c=1; c <= columnCount; c++) {
        String columnName=StringUtilities.sanitizeName(metaData.getColumnName(c));
        String value=rset.getString(c);
        if (value == null) {
          value="String_Node_Str";
        }
        map.put(columnName,new StringToken(value));
      }
      matches.add(new RecordToken(map));
    }
  }
 catch (  SQLException e) {
    throw new IllegalActionException(this,e,"String_Node_Str");
  }
  int numberOfMatches=matches.size();
  ArrayToken result;
  if (numberOfMatches == 0) {
    result=new ArrayToken(BaseType.RECORD);
  }
 else {
    RecordToken[] array=new RecordToken[numberOfMatches];
    int k=0;
    for (    RecordToken recordToken : matches) {
      array[k++]=recordToken;
    }
    result=new ArrayToken(array);
  }
  return result;
}

Fixed version (ground truth):
/** 
 * Execute the SQL query given in the specified string and return an array of record tokens containing the results. Note that if there is no connection to the database, this will open one. The caller is responsible for calling closeConnection() after this.
 * @param sql The query.
 * @return An array of record tokens containing the results,which may be empty (zero length), or null if the connection fails or is canceled.
 * @exception IllegalActionException If the query fails.
 */
public ArrayToken executeQuery(String sql) throws IllegalActionException {
  PreparedStatement statement=null;
  ArrayList<RecordToken> matches=new ArrayList<RecordToken>();
  try {
    Connection connection=getConnection();
    if (connection == null) {
      return null;
    }
    statement=connection.prepareStatement(sql);
    ResultSet rset=statement.executeQuery();
    ResultSetMetaData metaData=rset.getMetaData();
    int columnCount=metaData.getColumnCount();
    while (rset.next()) {
      HashMap<String,Token> map=new HashMap<String,Token>();
      for (int c=1; c <= columnCount; c++) {
        String columnName=StringUtilities.sanitizeName(metaData.getColumnName(c));
        String value=rset.getString(c);
        if (value == null) {
          value="String_Node_Str";
        }
        map.put(columnName,new StringToken(value));
      }
      matches.add(new RecordToken(map));
    }
  }
 catch (  SQLException e) {
    throw new IllegalActionException(this,e,"String_Node_Str");
  }
 finally {
    if (statement != null) {
      try {
        statement.close();
      }
 catch (      SQLException e1) {
      }
    }
  }
  int numberOfMatches=matches.size();
  ArrayToken result;
  if (numberOfMatches == 0) {
    result=new ArrayToken(BaseType.RECORD);
  }
 else {
    RecordToken[] array=new RecordToken[numberOfMatches];
    int k=0;
    for (    RecordToken recordToken : matches) {
      array[k++]=recordToken;
    }
    result=new ArrayToken(array);
  }
  return result;
}