@Override
 public void setFetchSize(int rows) throws SQLException {
   try {
     _res.setFetchSize(rows);
   } catch (SQLException e) {
     handleException(e);
   }
 }
 private void testFetchSize() throws SQLException {
   if (!config.networked || config.memory) {
     return;
   }
   ResultSet rs = stat.executeQuery("SELECT * FROM SYSTEM_RANGE(1, 100)");
   int a = stat.getFetchSize();
   int b = rs.getFetchSize();
   assertEquals(a, b);
   rs.setFetchSize(b + 1);
   b = rs.getFetchSize();
   assertEquals(a + 1, b);
 }
  private void testInt() throws SQLException {
    trace("Test INT");
    ResultSet rs;
    Object o;

    stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY,VALUE INT)");
    stat.execute("INSERT INTO TEST VALUES(1,-1)");
    stat.execute("INSERT INTO TEST VALUES(2,0)");
    stat.execute("INSERT INTO TEST VALUES(3,1)");
    stat.execute("INSERT INTO TEST VALUES(4," + Integer.MAX_VALUE + ")");
    stat.execute("INSERT INTO TEST VALUES(5," + Integer.MIN_VALUE + ")");
    stat.execute("INSERT INTO TEST VALUES(6,NULL)");
    // this should not be read - maxrows=6
    stat.execute("INSERT INTO TEST VALUES(7,NULL)");

    // MySQL compatibility (is this required?)
    // rs=stat.executeQuery("SELECT * FROM TEST T ORDER BY ID");
    // check(rs.findColumn("T.ID"), 1);
    // check(rs.findColumn("T.NAME"), 2);

    rs = stat.executeQuery("SELECT *, NULL AS N FROM TEST ORDER BY ID");

    // MySQL compatibility
    assertEquals(1, rs.findColumn("TEST.ID"));
    assertEquals(2, rs.findColumn("TEST.VALUE"));

    ResultSetMetaData meta = rs.getMetaData();
    assertEquals(3, meta.getColumnCount());
    assertEquals("resultSet".toUpperCase(), meta.getCatalogName(1));
    assertTrue("PUBLIC".equals(meta.getSchemaName(2)));
    assertTrue("TEST".equals(meta.getTableName(1)));
    assertTrue("ID".equals(meta.getColumnName(1)));
    assertTrue("VALUE".equals(meta.getColumnName(2)));
    assertTrue(!meta.isAutoIncrement(1));
    assertTrue(meta.isCaseSensitive(1));
    assertTrue(meta.isSearchable(1));
    assertFalse(meta.isCurrency(1));
    assertTrue(meta.getColumnDisplaySize(1) > 0);
    assertTrue(meta.isSigned(1));
    assertTrue(meta.isSearchable(2));
    assertEquals(ResultSetMetaData.columnNoNulls, meta.isNullable(1));
    assertFalse(meta.isReadOnly(1));
    assertTrue(meta.isWritable(1));
    assertFalse(meta.isDefinitelyWritable(1));
    assertTrue(meta.getColumnDisplaySize(1) > 0);
    assertTrue(meta.getColumnDisplaySize(2) > 0);
    assertEquals(null, meta.getColumnClassName(3));

    assertTrue(rs.getRow() == 0);
    assertResultSetMeta(
        rs,
        3,
        new String[] {"ID", "VALUE", "N"},
        new int[] {Types.INTEGER, Types.INTEGER, Types.NULL},
        new int[] {10, 10, 1},
        new int[] {0, 0, 0});
    rs.next();
    assertEquals(ResultSet.CONCUR_READ_ONLY, rs.getConcurrency());
    assertEquals(ResultSet.FETCH_FORWARD, rs.getFetchDirection());
    trace("default fetch size=" + rs.getFetchSize());
    // 0 should be an allowed value (but it's not defined what is actually
    // means)
    rs.setFetchSize(0);
    assertThrows(ErrorCode.INVALID_VALUE_2, rs).setFetchSize(-1);
    // fetch size 100 is bigger than maxrows - not allowed
    assertThrows(ErrorCode.INVALID_VALUE_2, rs).setFetchSize(100);
    rs.setFetchSize(6);

    assertTrue(rs.getRow() == 1);
    assertEquals(2, rs.findColumn("VALUE"));
    assertEquals(2, rs.findColumn("value"));
    assertEquals(2, rs.findColumn("Value"));
    assertEquals(2, rs.findColumn("Value"));
    assertEquals(1, rs.findColumn("ID"));
    assertEquals(1, rs.findColumn("id"));
    assertEquals(1, rs.findColumn("Id"));
    assertEquals(1, rs.findColumn("iD"));
    assertTrue(rs.getInt(2) == -1 && !rs.wasNull());
    assertTrue(rs.getInt("VALUE") == -1 && !rs.wasNull());
    assertTrue(rs.getInt("value") == -1 && !rs.wasNull());
    assertTrue(rs.getInt("Value") == -1 && !rs.wasNull());
    assertTrue(rs.getString("Value").equals("-1") && !rs.wasNull());

    o = rs.getObject("value");
    trace(o.getClass().getName());
    assertTrue(o instanceof Integer);
    assertTrue(((Integer) o).intValue() == -1);
    o = rs.getObject(2);
    trace(o.getClass().getName());
    assertTrue(o instanceof Integer);
    assertTrue(((Integer) o).intValue() == -1);
    assertTrue(rs.getBoolean("Value"));
    assertTrue(rs.getByte("Value") == (byte) -1);
    assertTrue(rs.getShort("Value") == (short) -1);
    assertTrue(rs.getLong("Value") == -1);
    assertTrue(rs.getFloat("Value") == -1.0);
    assertTrue(rs.getDouble("Value") == -1.0);

    assertTrue(rs.getString("Value").equals("-1") && !rs.wasNull());
    assertTrue(rs.getInt("ID") == 1 && !rs.wasNull());
    assertTrue(rs.getInt("id") == 1 && !rs.wasNull());
    assertTrue(rs.getInt("Id") == 1 && !rs.wasNull());
    assertTrue(rs.getInt(1) == 1 && !rs.wasNull());
    rs.next();
    assertTrue(rs.getRow() == 2);
    assertTrue(rs.getInt(2) == 0 && !rs.wasNull());
    assertTrue(!rs.getBoolean(2));
    assertTrue(rs.getByte(2) == 0);
    assertTrue(rs.getShort(2) == 0);
    assertTrue(rs.getLong(2) == 0);
    assertTrue(rs.getFloat(2) == 0.0);
    assertTrue(rs.getDouble(2) == 0.0);
    assertTrue(rs.getString(2).equals("0") && !rs.wasNull());
    assertTrue(rs.getInt(1) == 2 && !rs.wasNull());
    rs.next();
    assertTrue(rs.getRow() == 3);
    assertTrue(rs.getInt("ID") == 3 && !rs.wasNull());
    assertTrue(rs.getInt("VALUE") == 1 && !rs.wasNull());
    rs.next();
    assertTrue(rs.getRow() == 4);
    assertTrue(rs.getInt("ID") == 4 && !rs.wasNull());
    assertTrue(rs.getInt("VALUE") == Integer.MAX_VALUE && !rs.wasNull());
    rs.next();
    assertTrue(rs.getRow() == 5);
    assertTrue(rs.getInt("id") == 5 && !rs.wasNull());
    assertTrue(rs.getInt("value") == Integer.MIN_VALUE && !rs.wasNull());
    assertTrue(rs.getString(1).equals("5") && !rs.wasNull());
    rs.next();
    assertTrue(rs.getRow() == 6);
    assertTrue(rs.getInt("id") == 6 && !rs.wasNull());
    assertTrue(rs.getInt("value") == 0 && rs.wasNull());
    assertTrue(rs.getInt(2) == 0 && rs.wasNull());
    assertTrue(rs.getInt(1) == 6 && !rs.wasNull());
    assertTrue(rs.getString(1).equals("6") && !rs.wasNull());
    assertTrue(rs.getString(2) == null && rs.wasNull());
    o = rs.getObject(2);
    assertTrue(o == null);
    assertTrue(rs.wasNull());
    assertFalse(rs.next());
    assertEquals(0, rs.getRow());
    // there is one more row, but because of setMaxRows we don't get it

    stat.execute("DROP TABLE TEST");
    stat.setMaxRows(0);
  }
  public void doLoop(ResultSet rs, SqlContext context) throws SQLException {
    Pager pager = context.getPager();
    if (null == rs) return;
    int warnSize =
        (context.attr(KEY_WARN_SIZE) == null
            ? WARN_BIG_SIZE
            : ((Number) (context.attr(KEY_WARN_SIZE))).intValue());
    int errorSize =
        (context.attr(KEY_ERROR_SIZE) == null
            ? ERROR_BIG_SIZE
            : ((Number) (context.attr(KEY_ERROR_SIZE))).intValue());
    boolean warnBigResult = log.isWarnEnabled() && warnSize > 0;
    boolean errorBigResult = errorSize > 0;
    /**
     * 如果没有设置 Pager 或者 rs 的类型是 ResultSet.TYPE_FORWARD_ONLY,那么<br>
     * 无法利用 游标的滚动 来计算结果集合大小。这比较高效,但是如果使用者希望得到页数量,<br>
     * 需要为 Pager 另行计算 总体的结果集大小。
     *
     * <p>一般的,为特殊数据建立的 Pager,生成的 ResultSet 类型应该是 TYPE_FORWARD_ONLY
     */
    if (null == pager
        || ResultSet.TYPE_FORWARD_ONLY == rs.getType()
        || pager.getPageNumber() <= 0) {
      // 根据 Pager 设定 Fetch Size
      // by wendal: 设置与否,影响不大的,而且旧版本的Oracle会出问题,故,注释掉了
      // if (null != pager && pager.getPageSize() > 0)
      //    rs.setFetchSize(pager.getPageSize());

      // 循环调用
      while (rs.next()) {
        createObject(++index, rs, context, -1);
        if (warnBigResult && index > warnSize) {
          warnBigResult = false;
          this.warnBig(rs, context, index, warnSize);
        }
        if (errorBigResult && index > errorSize) {
          errorBigResult = false;
          this.errorBig(rs, context, index, errorSize);
        }
      }
    }
    /**
     * 如果进行到了这个分支,则表示,整个查询的 Pager 是不区分数据库类型的。 <br>
     * 并且 ResultSet 的游标是可以来回滚动的。
     *
     * <p>所以我就会利用游标的滚动,为你计算整个结果集的大小。比较低效,在很小<br>
     * 数据量的时候 还是比较有用的
     */
    else if (rs.last()) {
      // 设置结果集合的 FetchSize
      if (pager.getPageSize() <= 0) rs.setFetchSize(Pager.DEFAULT_PAGE_SIZE);
      else if (pager.getPageSize() > Pager.MAX_FETCH_SIZE) rs.setFetchSize(Pager.MAX_FETCH_SIZE);
      else rs.setFetchSize(pager.getPageSize());

      // 开始循环
      int rowCount = rs.getRow();
      LoopScope ls = LoopScope.eval(pager, rowCount);
      if (rs.absolute(ls.start + 1))
        for (int i = ls.start; i < ls.max; i++) {
          createObject(++index, rs, context, rowCount);
          if (!rs.next()) break;
          if (warnBigResult && index > warnSize) {
            warnBigResult = false;
            this.warnBig(rs, context, index, warnSize);
          }
          if (errorBigResult && index > errorSize) {
            errorBigResult = false;
            this.errorBig(rs, context, index, errorSize);
          }
        }
    }
  }
	public void setFetchSize(int rows) throws SQLException {
		rs.setFetchSize(rows);
	}
 public void setFetchSize(int arg0) throws SQLException {
   for (ResultSet rs : comps) rs.setFetchSize(arg0);
 }