+ " rows affected.");
        close();
        return null;
      }
    }
    ResultSet rs = getResultSet();
    if (m_Debug) 
      System.err.println("Getting metadata...");
    ResultSetMetaData md = rs.getMetaData();
    if (m_Debug) 
      System.err.println("Completed getting metadata...");
    
    
    // Determine structure of the instances
    int numAttributes = md.getColumnCount();
    int [] attributeTypes = new int [numAttributes];
    Hashtable [] nominalIndexes = new Hashtable [numAttributes];
    FastVector [] nominalStrings = new FastVector [numAttributes];
    for (int i = 1; i <= numAttributes; i++) {
      /* switch (md.getColumnType(i)) {
      case Types.CHAR:
      case Types.VARCHAR:
      case Types.LONGVARCHAR:
      case Types.BINARY:
      case Types.VARBINARY:
      case Types.LONGVARBINARY:*/
      
      switch (translateDBColumnType(md.getColumnTypeName(i))) {
  
      case STRING :
  //System.err.println("String --> nominal");
  attributeTypes[i - 1] = Attribute.NOMINAL;
  nominalIndexes[i - 1] = new Hashtable();
  nominalStrings[i - 1] = new FastVector();
  break;
      case TEXT:
  //System.err.println("Text --> string");
  attributeTypes[i - 1] = Attribute.STRING;
  nominalIndexes[i - 1] = new Hashtable();
  nominalStrings[i - 1] = new FastVector();
  break;
      case BOOL:
  //System.err.println("boolean --> nominal");
  attributeTypes[i - 1] = Attribute.NOMINAL;
  nominalIndexes[i - 1] = new Hashtable();
  nominalIndexes[i - 1].put("false", new Double(0));
  nominalIndexes[i - 1].put("true", new Double(1));
  nominalStrings[i - 1] = new FastVector();
  nominalStrings[i - 1].addElement("false");
  nominalStrings[i - 1].addElement("true");
  break;
      case DOUBLE:
  //System.err.println("BigDecimal --> numeric");
  attributeTypes[i - 1] = Attribute.NUMERIC;
  break;
      case BYTE:
  //System.err.println("byte --> numeric");
  attributeTypes[i - 1] = Attribute.NUMERIC;
  break;
      case SHORT:
  //System.err.println("short --> numeric");
  attributeTypes[i - 1] = Attribute.NUMERIC;
  break;
      case INTEGER:
  //System.err.println("int --> numeric");
  attributeTypes[i - 1] = Attribute.NUMERIC;
  break;
      case LONG:
  //System.err.println("long --> numeric");
  attributeTypes[i - 1] = Attribute.NUMERIC;
  break;
      case FLOAT:
  //System.err.println("float --> numeric");
  attributeTypes[i - 1] = Attribute.NUMERIC;
  break;
      case DATE:
  attributeTypes[i - 1] = Attribute.DATE;
  break;
      case TIME:
  attributeTypes[i - 1] = Attribute.DATE;
  break;
      default:
  //System.err.println("Unknown column type");
  attributeTypes[i - 1] = Attribute.STRING;
      }
    }
    // For sqlite
    // cache column names because the last while(rs.next()) { iteration for
    // the tuples below will close the md object:  
    Vector<String> columnNames = new Vector<String>(); 
    for (int i = 0; i < numAttributes; i++) {
      columnNames.add(md.getColumnLabel(i + 1));
    }
    // Step through the tuples
    if (m_Debug) 
      System.err.println("Creating instances...");
    FastVector instances = new FastVector();
    int rowCount = 0;
    while(rs.next()) {
      if (rowCount % 100 == 0) {
        if (m_Debug)  {
    System.err.print("read " + rowCount + " instances \r");
    System.err.flush();
        }
      }
      double[] vals = new double[numAttributes];
      for(int i = 1; i <= numAttributes; i++) {
  /*switch (md.getColumnType(i)) {
  case Types.CHAR:
  case Types.VARCHAR:
  case Types.LONGVARCHAR:
  case Types.BINARY:
  case Types.VARBINARY:
  case Types.LONGVARBINARY:*/
  switch (translateDBColumnType(md.getColumnTypeName(i))) {
  case STRING :
    String str = rs.getString(i);
    
    if (rs.wasNull()) {
      vals[i - 1] = Utils.missingValue();
    } else {
      Double index = (Double)nominalIndexes[i - 1].get(str);
      if (index == null) {
        index = new Double(nominalStrings[i - 1].size());
        nominalIndexes[i - 1].put(str, index);
        nominalStrings[i - 1].addElement(str);
      }
      vals[i - 1] = index.doubleValue();
    }
    break;
  case TEXT:
    String txt = rs.getString(i);
    
    if (rs.wasNull()) {
      vals[i - 1] = Utils.missingValue();
    } else {
      Double index = (Double)nominalIndexes[i - 1].get(txt);
      if (index == null) {
        index = new Double(nominalStrings[i - 1].size());
        nominalIndexes[i - 1].put(txt, index);
        nominalStrings[i - 1].addElement(txt);
      }
      vals[i - 1] = index.doubleValue();
    }
    break;
  case BOOL:
    boolean boo = rs.getBoolean(i);
    if (rs.wasNull()) {
      vals[i - 1] = Utils.missingValue();
    } else {
      vals[i - 1] = (boo ? 1.0 : 0.0);
    }
    break;
  case DOUBLE:
    //    BigDecimal bd = rs.getBigDecimal(i, 4); 
    double dd = rs.getDouble(i);
    // Use the column precision instead of 4?
    if (rs.wasNull()) {
      vals[i - 1] = Utils.missingValue();
    } else {
      //      newInst.setValue(i - 1, bd.doubleValue());
      vals[i - 1] =  dd;
    }
    break;
  case BYTE:
    byte by = rs.getByte(i);
    if (rs.wasNull()) {
      vals[i - 1] = Utils.missingValue();
    } else {
      vals[i - 1] = (double)by;
    }
    break;
  case SHORT:
    short sh = rs.getShort(i);
    if (rs.wasNull()) {
      vals[i - 1] = Utils.missingValue();
    } else {
      vals[i - 1] = (double)sh;
    }
    break;
  case INTEGER:
    int in = rs.getInt(i);
    if (rs.wasNull()) {
      vals[i - 1] = Utils.missingValue();
    } else {
      vals[i - 1] = (double)in;
    }
    break;
  case LONG:
    long lo = rs.getLong(i);
    if (rs.wasNull()) {
      vals[i - 1] = Utils.missingValue();
    } else {
      vals[i - 1] = (double)lo;
    }
    break;
  case FLOAT:
    float fl = rs.getFloat(i);
    if (rs.wasNull()) {
      vals[i - 1] = Utils.missingValue();
    } else {
      vals[i - 1] = (double)fl;
    }
    break;
  case DATE:
          Date date = rs.getDate(i);
          if (rs.wasNull()) {
      vals[i - 1] = Utils.missingValue();
    } else {
            // TODO: Do a value check here.
            vals[i - 1] = (double)date.getTime();
          }
          break;
  case TIME:
          Time time = rs.getTime(i);
          if (rs.wasNull()) {
      vals[i - 1] = Utils.missingValue();
    } else {
            // TODO: Do a value check here.
            vals[i - 1] = (double) time.getTime();
          }