You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2015/09/03 00:16:18 UTC

[30/50] incubator-calcite git commit: [CALCITE-813] Upgrade updateCount, maxRows from int to long

[CALCITE-813] Upgrade updateCount, maxRows from int to long


Project: http://git-wip-us.apache.org/repos/asf/incubator-calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-calcite/commit/c818d50b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-calcite/tree/c818d50b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-calcite/diff/c818d50b

Branch: refs/heads/branch-release
Commit: c818d50bb6a07be251ce4b395e9a9e60ae58743a
Parents: e03dafc
Author: Julian Hyde <jh...@apache.org>
Authored: Thu Jul 23 18:02:30 2015 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Thu Jul 23 21:02:14 2015 -0700

----------------------------------------------------------------------
 .../apache/calcite/avatica/jdbc/JdbcMeta.java   |  82 ++++++++-----
 .../calcite/avatica/jdbc/JdbcResultSet.java     |  10 +-
 .../calcite/avatica/remote/RemoteMetaTest.java  |   5 +-
 .../calcite/avatica/AvaticaConnection.java      |   4 +-
 .../avatica/AvaticaPreparedStatement.java       |   6 +-
 .../calcite/avatica/AvaticaStatement.java       |  28 ++++-
 .../apache/calcite/avatica/AvaticaUtils.java    |  86 +++++++++++++
 .../java/org/apache/calcite/avatica/Meta.java   |  26 ++--
 .../org/apache/calcite/avatica/MetaImpl.java    |   2 +-
 .../calcite/avatica/UnregisteredDriver.java     |   2 +-
 .../calcite/avatica/remote/LocalService.java    |   2 +-
 .../calcite/avatica/remote/RemoteMeta.java      |   6 +-
 .../apache/calcite/avatica/remote/Service.java  |  22 ++--
 .../calcite/jdbc/CalciteConnectionImpl.java     |   2 +-
 .../apache/calcite/jdbc/CalciteMetaImpl.java    |  12 +-
 .../org/apache/calcite/jdbc/CalcitePrepare.java |   6 +-
 .../calcite/prepare/CalcitePrepareImpl.java     |   8 +-
 .../calcite/linq4j/EnumerableDefaults.java      | 122 +++++++++++++++++--
 18 files changed, 330 insertions(+), 101 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c818d50b/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java b/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java
index d1a2049..18a0554 100644
--- a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java
+++ b/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java
@@ -17,6 +17,7 @@
 package org.apache.calcite.avatica.jdbc;
 
 import org.apache.calcite.avatica.AvaticaParameter;
+import org.apache.calcite.avatica.AvaticaUtils;
 import org.apache.calcite.avatica.ColumnMetaData;
 import org.apache.calcite.avatica.ConnectionPropertiesImpl;
 import org.apache.calcite.avatica.Meta;
@@ -377,11 +378,10 @@ public class JdbcMeta implements Meta {
   public MetaResultSet getTables(String catalog, Pat schemaPattern,
       Pat tableNamePattern, List<String> typeList) {
     try {
-      String[] types = new String[typeList == null ? 0 : typeList.size()];
-      return JdbcResultSet.create(DEFAULT_CONN_ID, -1,
+      final ResultSet rs =
           connection.getMetaData().getTables(catalog, schemaPattern.s,
-              tableNamePattern.s,
-              typeList == null ? types : typeList.toArray(types)));
+              tableNamePattern.s, toArray(typeList));
+      return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs);
     } catch (SQLException e) {
       throw new RuntimeException(e);
     }
@@ -390,9 +390,10 @@ public class JdbcMeta implements Meta {
   public MetaResultSet getColumns(String catalog, Pat schemaPattern,
       Pat tableNamePattern, Pat columnNamePattern) {
     try {
-      return JdbcResultSet.create(DEFAULT_CONN_ID, -1,
+      final ResultSet rs =
           connection.getMetaData().getColumns(catalog, schemaPattern.s,
-              tableNamePattern.s, columnNamePattern.s));
+              tableNamePattern.s, columnNamePattern.s);
+      return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs);
     } catch (SQLException e) {
       throw new RuntimeException(e);
     }
@@ -400,8 +401,9 @@ public class JdbcMeta implements Meta {
 
   public MetaResultSet getSchemas(String catalog, Pat schemaPattern) {
     try {
-      return JdbcResultSet.create(DEFAULT_CONN_ID, -1,
-          connection.getMetaData().getSchemas(catalog, schemaPattern.s));
+      final ResultSet rs =
+          connection.getMetaData().getSchemas(catalog, schemaPattern.s);
+      return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs);
     } catch (SQLException e) {
       throw new RuntimeException(e);
     }
@@ -409,8 +411,8 @@ public class JdbcMeta implements Meta {
 
   public MetaResultSet getCatalogs() {
     try {
-      return JdbcResultSet.create(DEFAULT_CONN_ID, -1,
-          connection.getMetaData().getCatalogs());
+      final ResultSet rs = connection.getMetaData().getCatalogs();
+      return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs);
     } catch (SQLException e) {
       throw new RuntimeException(e);
     }
@@ -418,8 +420,8 @@ public class JdbcMeta implements Meta {
 
   public MetaResultSet getTableTypes() {
     try {
-      return JdbcResultSet.create(DEFAULT_CONN_ID, -1,
-          connection.getMetaData().getTableTypes());
+      final ResultSet rs = connection.getMetaData().getTableTypes();
+      return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs);
     } catch (SQLException e) {
       throw new RuntimeException(e);
     }
@@ -428,9 +430,10 @@ public class JdbcMeta implements Meta {
   public MetaResultSet getProcedures(String catalog, Pat schemaPattern,
       Pat procedureNamePattern) {
     try {
-      return JdbcResultSet.create(DEFAULT_CONN_ID, -1,
+      final ResultSet rs =
           connection.getMetaData().getProcedures(catalog, schemaPattern.s,
-              procedureNamePattern.s));
+              procedureNamePattern.s);
+      return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs);
     } catch (SQLException e) {
       throw new RuntimeException(e);
     }
@@ -439,9 +442,10 @@ public class JdbcMeta implements Meta {
   public MetaResultSet getProcedureColumns(String catalog, Pat schemaPattern,
       Pat procedureNamePattern, Pat columnNamePattern) {
     try {
-      return JdbcResultSet.create(DEFAULT_CONN_ID, -1,
+      final ResultSet rs =
           connection.getMetaData().getProcedureColumns(catalog,
-              schemaPattern.s, procedureNamePattern.s, columnNamePattern.s));
+              schemaPattern.s, procedureNamePattern.s, columnNamePattern.s);
+      return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs);
     } catch (SQLException e) {
       throw new RuntimeException(e);
     }
@@ -450,9 +454,10 @@ public class JdbcMeta implements Meta {
   public MetaResultSet getColumnPrivileges(String catalog, String schema,
       String table, Pat columnNamePattern) {
     try {
-      return JdbcResultSet.create(DEFAULT_CONN_ID, -1,
+      final ResultSet rs =
           connection.getMetaData().getColumnPrivileges(catalog, schema,
-              table, columnNamePattern.s));
+              table, columnNamePattern.s);
+      return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs);
     } catch (SQLException e) {
       throw new RuntimeException(e);
     }
@@ -461,9 +466,10 @@ public class JdbcMeta implements Meta {
   public MetaResultSet getTablePrivileges(String catalog, Pat schemaPattern,
       Pat tableNamePattern) {
     try {
-      return JdbcResultSet.create(DEFAULT_CONN_ID, -1,
+      final ResultSet rs =
           connection.getMetaData().getTablePrivileges(catalog,
-              schemaPattern.s, tableNamePattern.s));
+              schemaPattern.s, tableNamePattern.s);
+      return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs);
     } catch (SQLException e) {
       throw new RuntimeException(e);
     }
@@ -476,9 +482,10 @@ public class JdbcMeta implements Meta {
           + " table:" + table + " scope:" + scope + " nullable:" + nullable);
     }
     try {
-      return JdbcResultSet.create(DEFAULT_CONN_ID, -1,
+      final ResultSet rs =
           connection.getMetaData().getBestRowIdentifier(catalog, schema,
-              table, scope, nullable));
+              table, scope, nullable);
+      return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs);
     } catch (SQLException e) {
       throw new RuntimeException(e);
     }
@@ -490,8 +497,9 @@ public class JdbcMeta implements Meta {
       LOG.trace("getVersionColumns catalog:" + catalog + " schema:" + schema + " table:" + table);
     }
     try {
-      return JdbcResultSet.create(DEFAULT_CONN_ID, -1,
-          connection.getMetaData().getVersionColumns(catalog, schema, table));
+      final ResultSet rs =
+          connection.getMetaData().getVersionColumns(catalog, schema, table);
+      return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs);
     } catch (SQLException e) {
       throw new RuntimeException(e);
     }
@@ -503,8 +511,9 @@ public class JdbcMeta implements Meta {
       LOG.trace("getPrimaryKeys catalog:" + catalog + " schema:" + schema + " table:" + table);
     }
     try {
-      return JdbcResultSet.create(DEFAULT_CONN_ID, -1,
-          connection.getMetaData().getPrimaryKeys(catalog, schema, table));
+      final ResultSet rs =
+          connection.getMetaData().getPrimaryKeys(catalog, schema, table);
+      return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs);
     } catch (SQLException e) {
       throw new RuntimeException(e);
     }
@@ -528,8 +537,8 @@ public class JdbcMeta implements Meta {
 
   public MetaResultSet getTypeInfo() {
     try {
-      return JdbcResultSet.create(DEFAULT_CONN_ID, -1,
-          connection.getMetaData().getTypeInfo());
+      final ResultSet rs = connection.getMetaData().getTypeInfo();
+      return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs);
     } catch (SQLException e) {
       throw new RuntimeException(e);
     }
@@ -696,7 +705,7 @@ public class JdbcMeta implements Meta {
   }
 
   public StatementHandle prepare(ConnectionHandle ch, String sql,
-      int maxRowCount) {
+      long maxRowCount) {
     try {
       final Connection conn = getConnection(ch.id);
       final PreparedStatement statement = conn.prepareStatement(sql);
@@ -715,7 +724,7 @@ public class JdbcMeta implements Meta {
   }
 
   public ExecuteResult prepareAndExecute(StatementHandle h, String sql,
-      int maxRowCount, PrepareCallback callback) {
+      long maxRowCount, PrepareCallback callback) {
     try {
       final StatementInfo info = statementCache.getIfPresent(h.id);
       if (info == null) {
@@ -725,7 +734,7 @@ public class JdbcMeta implements Meta {
       final Statement statement = info.statement;
       // Special handling of maxRowCount as JDBC 0 is unlimited, our meta 0 row
       if (maxRowCount > 0) {
-        statement.setMaxRows(maxRowCount);
+        AvaticaUtils.setLargeMaxRows(statement, maxRowCount);
       } else if (maxRowCount < 0) {
         statement.setMaxRows(0);
       }
@@ -737,7 +746,7 @@ public class JdbcMeta implements Meta {
         // Create a special result set that just carries update count
         resultSets.add(
             MetaResultSet.count(h.connectionId, h.id,
-                statement.getUpdateCount()));
+                AvaticaUtils.getLargeUpdateCount(statement)));
       } else {
         resultSets.add(
             JdbcResultSet.create(h.connectionId, h.id, info.resultSet,
@@ -754,7 +763,7 @@ public class JdbcMeta implements Meta {
   }
 
   public Frame fetch(StatementHandle h, List<TypedValue> parameterValues,
-      int offset, int fetchMaxRowCount) {
+      long offset, int fetchMaxRowCount) {
     if (LOG.isTraceEnabled()) {
       LOG.trace("fetching " + h + " offset:" + offset + " fetchMaxRowCount:"
           + fetchMaxRowCount);
@@ -789,6 +798,13 @@ public class JdbcMeta implements Meta {
     }
   }
 
+  private static String[] toArray(List<String> typeList) {
+    if (typeList == null) {
+      return new String[0];
+    }
+    return typeList.toArray(new String[typeList.size()]);
+  }
+
   /** All we know about a statement. */
   private static class StatementInfo {
     final Statement statement; // sometimes a PreparedStatement

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c818d50b/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcResultSet.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcResultSet.java b/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcResultSet.java
index ae67b50..dc50405 100644
--- a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcResultSet.java
+++ b/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcResultSet.java
@@ -37,7 +37,7 @@ import java.util.List;
 class JdbcResultSet extends Meta.MetaResultSet {
   protected JdbcResultSet(String connectionId, int statementId,
       boolean ownStatement, Meta.Signature signature, Meta.Frame firstFrame) {
-    super(connectionId, statementId, ownStatement, signature, firstFrame, -1);
+    super(connectionId, statementId, ownStatement, signature, firstFrame, -1L);
   }
 
   /** Creates a result set. */
@@ -48,12 +48,12 @@ class JdbcResultSet extends Meta.MetaResultSet {
 
   /** Creates a result set with maxRowCount. */
   public static JdbcResultSet create(String connectionId, int statementId,
-      ResultSet resultSet, int maxRowCount) {
+      ResultSet resultSet, long maxRowCount) {
     try {
       Meta.Signature sig = JdbcMeta.signature(resultSet.getMetaData());
       final Calendar calendar = Calendar.getInstance(DateTimeUtils.GMT_ZONE);
       final int fetchRowCount =
-        (maxRowCount == -1 || maxRowCount > 100) ? 100 : maxRowCount;
+        (maxRowCount == -1 || maxRowCount > 100) ? 100 : (int) maxRowCount;
       final Meta.Frame firstFrame = frame(resultSet, 0, fetchRowCount, calendar);
       if (firstFrame.done) {
         resultSet.close();
@@ -67,7 +67,7 @@ class JdbcResultSet extends Meta.MetaResultSet {
 
   /** Creates a frame containing a given number or unlimited number of rows
    * from a result set. */
-  static Meta.Frame frame(ResultSet resultSet, int offset,
+  static Meta.Frame frame(ResultSet resultSet, long offset,
       int fetchMaxRowCount, Calendar calendar) throws SQLException {
     final ResultSetMetaData metaData = resultSet.getMetaData();
     final int columnCount = metaData.getColumnCount();
@@ -77,7 +77,7 @@ class JdbcResultSet extends Meta.MetaResultSet {
     }
     final List<Object> rows = new ArrayList<>();
     // Meta prepare/prepareAndExecute 0 return 0 row and done
-    boolean done = fetchMaxRowCount == 0 ? true : false;
+    boolean done = fetchMaxRowCount == 0;
     for (int i = 0; fetchMaxRowCount < 0 || i < fetchMaxRowCount; i++) {
       if (!resultSet.next()) {
         done = true;

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c818d50b/avatica-server/src/test/java/org/apache/calcite/avatica/remote/RemoteMetaTest.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/test/java/org/apache/calcite/avatica/remote/RemoteMetaTest.java b/avatica-server/src/test/java/org/apache/calcite/avatica/remote/RemoteMetaTest.java
index 27dcfa4..2a9e846 100644
--- a/avatica-server/src/test/java/org/apache/calcite/avatica/remote/RemoteMetaTest.java
+++ b/avatica-server/src/test/java/org/apache/calcite/avatica/remote/RemoteMetaTest.java
@@ -97,8 +97,9 @@ public class RemoteMetaTest {
 
   private static Meta.ExecuteResult prepareAndExecuteInternal(AvaticaConnection conn,
     final AvaticaStatement statement, String sql, int maxRowCount) throws Exception {
-    Method m = AvaticaConnection.class.getDeclaredMethod("prepareAndExecuteInternal",
-      AvaticaStatement.class, String.class, int.class);
+    Method m =
+        AvaticaConnection.class.getDeclaredMethod("prepareAndExecuteInternal",
+            AvaticaStatement.class, String.class, long.class);
     m.setAccessible(true);
     return (Meta.ExecuteResult) m.invoke(conn, statement, sql, maxRowCount);
   }

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c818d50b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java
index 1ed561c..e602ed7 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java
@@ -436,7 +436,7 @@ public abstract class AvaticaConnection implements Connection {
   }
 
   protected Meta.ExecuteResult prepareAndExecuteInternal(
-      final AvaticaStatement statement, String sql, int maxRowCount)
+      final AvaticaStatement statement, String sql, long maxRowCount)
       throws SQLException {
     final Meta.PrepareCallback callback =
         new Meta.PrepareCallback() {
@@ -458,7 +458,7 @@ public abstract class AvaticaConnection implements Connection {
           }
 
           public void assign(Meta.Signature signature, Meta.Frame firstFrame,
-              int updateCount) throws SQLException {
+              long updateCount) throws SQLException {
             if (updateCount != -1) {
               statement.updateCount = updateCount;
             } else {

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c818d50b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java
index e489c07..af00378 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java
@@ -114,7 +114,11 @@ public abstract class AvaticaPreparedStatement
     return this;
   }
 
-  public int executeUpdate() throws SQLException {
+  public final int executeUpdate() throws SQLException {
+    return (int) executeLargeUpdate();
+  }
+
+  public long executeLargeUpdate() throws SQLException {
     getConnection().executeQueryInternal(this, signature, null);
     return updateCount;
   }

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c818d50b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java
index 78ec1cc..bed506d 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java
@@ -52,7 +52,7 @@ public abstract class AvaticaStatement
   protected AvaticaResultSet openResultSet;
 
   /** Current update count. Same lifecycle as {@link #openResultSet}. */
-  protected int updateCount;
+  protected long updateCount;
 
   private int queryTimeoutMillis;
   final int resultSetType;
@@ -60,7 +60,7 @@ public abstract class AvaticaStatement
   final int resultSetHoldability;
   private int fetchSize;
   private int fetchDirection;
-  protected int maxRowCount = 0;
+  protected long maxRowCount = 0;
 
   /**
    * Creates an AvaticaStatement.
@@ -105,7 +105,7 @@ public abstract class AvaticaStatement
     this.updateCount = -1;
     try {
       // In JDBC, maxRowCount = 0 means no limit; in prepare it means LIMIT 0
-      final int maxRowCount1 = maxRowCount <= 0 ? -1 : maxRowCount;
+      final long maxRowCount1 = maxRowCount <= 0 ? -1 : maxRowCount;
       Meta.ExecuteResult x =
           connection.prepareAndExecuteInternal(this, sql, maxRowCount1);
     } catch (RuntimeException e) {
@@ -139,7 +139,11 @@ public abstract class AvaticaStatement
     }
   }
 
-  public int executeUpdate(String sql) throws SQLException {
+  public final int executeUpdate(String sql) throws SQLException {
+    return (int) executeLargeUpdate(sql);
+  }
+
+  public long executeLargeUpdate(String sql) throws SQLException {
     checkNotPreparedOrCallable("executeUpdate(String)");
     executeInternal(sql);
     return updateCount;
@@ -182,11 +186,19 @@ public abstract class AvaticaStatement
     throw connection.helper.unsupported();
   }
 
-  public int getMaxRows() {
+  public final int getMaxRows() {
+    return (int) getLargeMaxRows();
+  }
+
+  public long getLargeMaxRows() {
     return maxRowCount;
   }
 
-  public void setMaxRows(int maxRowCount) throws SQLException {
+  public final void setMaxRows(int maxRowCount) throws SQLException {
+    setLargeMaxRows(maxRowCount);
+  }
+
+  public void setLargeMaxRows(long maxRowCount) throws SQLException {
     if (maxRowCount < 0) {
       throw connection.helper.createException(
           "illegal maxRows value: " + maxRowCount);
@@ -255,6 +267,10 @@ public abstract class AvaticaStatement
   }
 
   public int getUpdateCount() throws SQLException {
+    return (int) updateCount;
+  }
+
+  public long getLargeUpdateCount() throws SQLException {
     return updateCount;
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c818d50b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java
index 0ee030d..a9975e0 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java
@@ -19,7 +19,12 @@ package org.apache.calcite.avatica;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
 import java.lang.reflect.Field;
+import java.sql.SQLException;
+import java.sql.Statement;
 import java.util.AbstractList;
 import java.util.HashMap;
 import java.util.List;
@@ -29,6 +34,13 @@ import java.util.Map;
 public class AvaticaUtils {
   private static final Map<Class, Class> BOX;
 
+  private static final MethodHandle SET_LARGE_MAX_ROWS =
+      method(void.class, Statement.class, "setLargeMaxRows", long.class);
+  private static final MethodHandle GET_LARGE_MAX_ROWS =
+      method(long.class, Statement.class, "getLargeMaxRows");
+  private static final MethodHandle GET_LARGE_UPDATE_COUNT =
+      method(void.class, Statement.class, "getLargeUpdateCount");
+
   private AvaticaUtils() {}
 
   static {
@@ -43,6 +55,19 @@ public class AvaticaUtils {
     BOX.put(double.class, Double.class);
   }
 
+  private static MethodHandle method(Class returnType, Class targetType,
+      String name, Class... argTypes) {
+    final MethodHandles.Lookup lookup = MethodHandles.lookup();
+    try {
+      return lookup.findVirtual(targetType, name,
+          MethodType.methodType(returnType, targetType, argTypes));
+    } catch (NoSuchMethodException e) {
+      return null;
+    } catch (IllegalAccessException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
   /**
    * Does nothing with its argument. Call this method when you have a value
    * you are not interested in, but you don't want the compiler to warn that
@@ -182,6 +207,67 @@ public class AvaticaUtils {
     }
     return baos.toString();
   }
+
+  /** Invokes {@code Statement#setLargeMaxRows}, falling back on
+   * {@link Statement#setMaxRows(int)} if the method does not exist (before
+   * JDK 1.8) or throws {@link UnsupportedOperationException}. */
+  public static void setLargeMaxRows(Statement statement, long n)
+      throws SQLException {
+    if (SET_LARGE_MAX_ROWS != null) {
+      try {
+        // Call Statement.setLargeMaxRows
+        SET_LARGE_MAX_ROWS.invokeExact(n);
+        return;
+      } catch (UnsupportedOperationException e) {
+        // ignore, and fall through to call Statement.setMaxRows
+      } catch (Error | RuntimeException | SQLException e) {
+        throw e;
+      } catch (Throwable e) {
+        throw new RuntimeException(e);
+      }
+    }
+    int i = (int) Math.max(Math.min(n, Integer.MAX_VALUE), Integer.MIN_VALUE);
+    statement.setMaxRows(i);
+  }
+
+  /** Invokes {@code Statement#getLargeMaxRows}, falling back on
+   * {@link Statement#getMaxRows()} if the method does not exist (before
+   * JDK 1.8) or throws {@link UnsupportedOperationException}. */
+  public static long getLargeMaxRows(Statement statement) throws SQLException {
+    if (GET_LARGE_MAX_ROWS != null) {
+      try {
+        // Call Statement.getLargeMaxRows
+        return (long) GET_LARGE_MAX_ROWS.invokeExact();
+      } catch (UnsupportedOperationException e) {
+        // ignore, and fall through to call Statement.getMaxRows
+      } catch (Error | RuntimeException | SQLException e) {
+        throw e;
+      } catch (Throwable e) {
+        throw new RuntimeException(e);
+      }
+    }
+    return statement.getMaxRows();
+  }
+
+  /** Invokes {@code Statement#getLargeUpdateCount}, falling back on
+   * {@link Statement#getUpdateCount()} if the method does not exist (before
+   * JDK 1.8) or throws {@link UnsupportedOperationException}. */
+  public static long getLargeUpdateCount(Statement statement)
+      throws SQLException {
+    if (GET_LARGE_UPDATE_COUNT != null) {
+      try {
+        // Call Statement.getLargeUpdateCount
+        return (long) GET_LARGE_UPDATE_COUNT.invokeExact();
+      } catch (UnsupportedOperationException e) {
+        // ignore, and fall through to call Statement.getUpdateCount
+      } catch (Error | RuntimeException | SQLException e) {
+        throw e;
+      } catch (Throwable e) {
+        throw new RuntimeException(e);
+      }
+    }
+    return statement.getUpdateCount();
+  }
 }
 
 // End AvaticaUtils.java

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c818d50b/avatica/src/main/java/org/apache/calcite/avatica/Meta.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/Meta.java b/avatica/src/main/java/org/apache/calcite/avatica/Meta.java
index a15a769..d9fab4d 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/Meta.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/Meta.java
@@ -190,7 +190,7 @@ public interface Meta {
    * @param maxRowCount Negative for no limit (different meaning than JDBC)
    * @return Signature of prepared statement
    */
-  StatementHandle prepare(ConnectionHandle ch, String sql, int maxRowCount);
+  StatementHandle prepare(ConnectionHandle ch, String sql, long maxRowCount);
 
   /** Prepares and executes a statement.
    *
@@ -203,7 +203,7 @@ public interface Meta {
    *     first frame of data
    */
   ExecuteResult prepareAndExecute(StatementHandle h, String sql,
-      int maxRowCount, PrepareCallback callback);
+      long maxRowCount, PrepareCallback callback);
 
   /** Returns a frame of rows.
    *
@@ -221,7 +221,7 @@ public interface Meta {
    * no limit
    * @return Frame, or null if there are no more
    */
-  Frame fetch(StatementHandle h, List<TypedValue> parameterValues, int offset,
+  Frame fetch(StatementHandle h, List<TypedValue> parameterValues, long offset,
       int fetchMaxRowCount);
 
   /** Called during the creation of a statement to allocate a new handle.
@@ -356,11 +356,19 @@ public interface Meta {
     public final boolean ownStatement;
     public final Frame firstFrame;
     public final Signature signature;
-    public final int updateCount;
+    public final long updateCount;
 
+    @Deprecated // to be removed before 2.0
     protected MetaResultSet(String connectionId, int statementId,
         boolean ownStatement, Signature signature, Frame firstFrame,
         int updateCount) {
+      this(connectionId, statementId, ownStatement, signature, firstFrame,
+          (long) updateCount);
+    }
+
+    protected MetaResultSet(String connectionId, int statementId,
+        boolean ownStatement, Signature signature, Frame firstFrame,
+        long updateCount) {
       this.signature = signature;
       this.connectionId = connectionId;
       this.statementId = statementId;
@@ -372,11 +380,11 @@ public interface Meta {
     public static MetaResultSet create(String connectionId, int statementId,
         boolean ownStatement, Signature signature, Frame firstFrame) {
       return new MetaResultSet(connectionId, statementId, ownStatement,
-          Objects.requireNonNull(signature), firstFrame, -1);
+          Objects.requireNonNull(signature), firstFrame, -1L);
     }
 
     public static MetaResultSet count(String connectionId, int statementId,
-        int updateCount) {
+        long updateCount) {
       assert updateCount >= 0;
       return new MetaResultSet(connectionId, statementId, false, null, null,
           updateCount);
@@ -549,7 +557,7 @@ public interface Meta {
         new Frame(0, false, Collections.emptyList());
 
     /** Zero-based offset of first row. */
-    public final int offset;
+    public final long offset;
     /** Whether this is definitely the last frame of rows.
      * If true, there are no more rows.
      * If false, there may or may not be more rows. */
@@ -557,7 +565,7 @@ public interface Meta {
     /** The rows. */
     public final Iterable<Object> rows;
 
-    public Frame(int offset, boolean done, Iterable<Object> rows) {
+    public Frame(long offset, boolean done, Iterable<Object> rows) {
       this.offset = offset;
       this.done = done;
       this.rows = rows;
@@ -686,7 +694,7 @@ public interface Meta {
   interface PrepareCallback {
     Object getMonitor();
     void clear() throws SQLException;
-    void assign(Signature signature, Frame firstFrame, int updateCount)
+    void assign(Signature signature, Frame firstFrame, long updateCount)
         throws SQLException;
     void execute() throws SQLException;
   }

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c818d50b/avatica/src/main/java/org/apache/calcite/avatica/MetaImpl.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/MetaImpl.java b/avatica/src/main/java/org/apache/calcite/avatica/MetaImpl.java
index 504c929..e67b64c 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/MetaImpl.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/MetaImpl.java
@@ -737,7 +737,7 @@ public abstract class MetaImpl implements Meta {
   }
 
   public Frame fetch(StatementHandle h, List<TypedValue> parameterValues,
-      int offset, int fetchMaxRowCount) {
+      long offset, int fetchMaxRowCount) {
     return null;
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c818d50b/avatica/src/main/java/org/apache/calcite/avatica/UnregisteredDriver.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/UnregisteredDriver.java b/avatica/src/main/java/org/apache/calcite/avatica/UnregisteredDriver.java
index 5f8d492..96d2459 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/UnregisteredDriver.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/UnregisteredDriver.java
@@ -42,7 +42,7 @@ import java.util.logging.Logger;
  *
  * <p>The provider must implement:</p>
  * <ul>
- *   <li>{@link Meta#prepare(Meta.ConnectionHandle, String, int)}
+ *   <li>{@link Meta#prepare(Meta.ConnectionHandle, String, long)}
  *   <li>{@link Meta#createIterable(org.apache.calcite.avatica.Meta.StatementHandle, org.apache.calcite.avatica.Meta.Signature, java.util.List, Meta.Frame)}
  * </ul>
  */

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c818d50b/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalService.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalService.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalService.java
index f03d55b..f6e23b8 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalService.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalService.java
@@ -148,7 +148,7 @@ public class LocalService implements Service {
               }
 
               @Override public void assign(Meta.Signature signature,
-                  Meta.Frame firstFrame, int updateCount) {
+                  Meta.Frame firstFrame, long updateCount) {
               }
 
               @Override public void execute() {

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c818d50b/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
index f0abe2d..b5404dc 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
@@ -158,7 +158,7 @@ class RemoteMeta extends MetaImpl {
   }
 
   @Override public StatementHandle prepare(ConnectionHandle ch, String sql,
-      int maxRowCount) {
+      long maxRowCount) {
     connectionSync(ch, new ConnectionPropertiesImpl()); // sync connection state if necessary
     final Service.PrepareResponse response = service.apply(
         new Service.PrepareRequest(ch.id, sql, maxRowCount));
@@ -166,7 +166,7 @@ class RemoteMeta extends MetaImpl {
   }
 
   @Override public ExecuteResult prepareAndExecute(StatementHandle h,
-      String sql, int maxRowCount, PrepareCallback callback) {
+      String sql, long maxRowCount, PrepareCallback callback) {
     // sync connection state if necessary
     connectionSync(new ConnectionHandle(h.connectionId),
       new ConnectionPropertiesImpl());
@@ -195,7 +195,7 @@ class RemoteMeta extends MetaImpl {
   }
 
   @Override public Frame fetch(StatementHandle h,
-      List<TypedValue> parameterValues, int offset, int fetchMaxRowCount) {
+      List<TypedValue> parameterValues, long offset, int fetchMaxRowCount) {
     final Service.FetchResponse response =
         service.apply(
             new Service.FetchRequest(h.connectionId, h.id, parameterValues,

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c818d50b/avatica/src/main/java/org/apache/calcite/avatica/remote/Service.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/Service.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/Service.java
index 9a8b5da..1171d76 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/Service.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/remote/Service.java
@@ -221,7 +221,7 @@ public interface Service {
     public final boolean ownStatement;
     public final Meta.Signature signature;
     public final Meta.Frame firstFrame;
-    public final int updateCount;
+    public final long updateCount;
 
     @JsonCreator
     public ResultSetResponse(
@@ -230,7 +230,7 @@ public interface Service {
         @JsonProperty("ownStatement") boolean ownStatement,
         @JsonProperty("signature") Meta.Signature signature,
         @JsonProperty("firstFrame") Meta.Frame firstFrame,
-        @JsonProperty("updateCount") int updateCount) {
+        @JsonProperty("updateCount") long updateCount) {
       this.connectionId = connectionId;
       this.statementId = statementId;
       this.ownStatement = ownStatement;
@@ -241,11 +241,11 @@ public interface Service {
   }
 
   /** Request for
-   * {@link org.apache.calcite.avatica.Meta#prepareAndExecute(Meta.StatementHandle, String, int, Meta.PrepareCallback)}. */
+   * {@link Meta#prepareAndExecute(Meta.StatementHandle, String, long, Meta.PrepareCallback)}. */
   class PrepareAndExecuteRequest extends Request {
     public final String connectionId;
     public final String sql;
-    public final int maxRowCount;
+    public final long maxRowCount;
     public final int statementId;
 
     @JsonCreator
@@ -253,7 +253,7 @@ public interface Service {
         @JsonProperty("connectionId") String connectionId,
         @JsonProperty("statementId") int statementId,
         @JsonProperty("sql") String sql,
-        @JsonProperty("maxRowCount") int maxRowCount) {
+        @JsonProperty("maxRowCount") long maxRowCount) {
       this.connectionId = connectionId;
       this.statementId = statementId;
       this.sql = sql;
@@ -278,17 +278,17 @@ public interface Service {
   }
 
   /** Request for
-   * {@link org.apache.calcite.avatica.Meta#prepare(org.apache.calcite.avatica.Meta.ConnectionHandle, String, int)}. */
+   * {@link Meta#prepare(Meta.ConnectionHandle, String, long)}. */
   class PrepareRequest extends Request {
     public final String connectionId;
     public final String sql;
-    public final int maxRowCount;
+    public final long maxRowCount;
 
     @JsonCreator
     public PrepareRequest(
         @JsonProperty("connectionId") String connectionId,
         @JsonProperty("sql") String sql,
-        @JsonProperty("maxRowCount") int maxRowCount) {
+        @JsonProperty("maxRowCount") long maxRowCount) {
       this.connectionId = connectionId;
       this.sql = sql;
       this.maxRowCount = maxRowCount;
@@ -312,11 +312,11 @@ public interface Service {
   }
 
   /** Request for
-   * {@link org.apache.calcite.avatica.Meta#fetch(Meta.StatementHandle, List, int, int)}. */
+   * {@link Meta#fetch(Meta.StatementHandle, List, long, int)}. */
   class FetchRequest extends Request {
     public final String connectionId;
     public final int statementId;
-    public final int offset;
+    public final long offset;
     /** Maximum number of rows to be returned in the frame. Negative means no
      * limit. */
     public final int fetchMaxRowCount;
@@ -329,7 +329,7 @@ public interface Service {
         @JsonProperty("connectionId") String connectionId,
         @JsonProperty("statementId") int statementId,
         @JsonProperty("parameterValues") List<TypedValue> parameterValues,
-        @JsonProperty("offset") int offset,
+        @JsonProperty("offset") long offset,
         @JsonProperty("fetchMaxRowCount") int fetchMaxRowCount) {
       this.connectionId = connectionId;
       this.statementId = statementId;

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c818d50b/core/src/main/java/org/apache/calcite/jdbc/CalciteConnectionImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/jdbc/CalciteConnectionImpl.java b/core/src/main/java/org/apache/calcite/jdbc/CalciteConnectionImpl.java
index f3819fe..d69971d 100644
--- a/core/src/main/java/org/apache/calcite/jdbc/CalciteConnectionImpl.java
+++ b/core/src/main/java/org/apache/calcite/jdbc/CalciteConnectionImpl.java
@@ -166,7 +166,7 @@ abstract class CalciteConnectionImpl
   }
 
   <T> CalcitePrepare.CalciteSignature<T> parseQuery(String sql,
-      CalcitePrepare.Context prepareContext, int maxRowCount) {
+      CalcitePrepare.Context prepareContext, long maxRowCount) {
     CalcitePrepare.Dummy.push(prepareContext);
     try {
       final CalcitePrepare prepare = prepareFactory.apply();

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c818d50b/core/src/main/java/org/apache/calcite/jdbc/CalciteMetaImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/jdbc/CalciteMetaImpl.java b/core/src/main/java/org/apache/calcite/jdbc/CalciteMetaImpl.java
index cd3df50..9f8ade3 100644
--- a/core/src/main/java/org/apache/calcite/jdbc/CalciteMetaImpl.java
+++ b/core/src/main/java/org/apache/calcite/jdbc/CalciteMetaImpl.java
@@ -537,7 +537,7 @@ public class CalciteMetaImpl extends MetaImpl {
   }
 
   @Override public StatementHandle prepare(ConnectionHandle ch, String sql,
-      int maxRowCount) {
+      long maxRowCount) {
     final StatementHandle h = createStatement(ch);
     final CalciteConnectionImpl calciteConnection = getConnection();
 
@@ -550,7 +550,7 @@ public class CalciteMetaImpl extends MetaImpl {
   }
 
   @Override public ExecuteResult prepareAndExecute(StatementHandle h,
-      String sql, int maxRowCount, PrepareCallback callback) {
+      String sql, long maxRowCount, PrepareCallback callback) {
     final CalcitePrepare.CalciteSignature<Object> signature;
     try {
       synchronized (callback.getMonitor()) {
@@ -574,7 +574,7 @@ public class CalciteMetaImpl extends MetaImpl {
   }
 
   @Override public Frame fetch(StatementHandle h, List<TypedValue> parameterValues,
-      int offset, int fetchMaxRowCount) {
+      long offset, int fetchMaxRowCount) {
     final CalciteConnectionImpl calciteConnection = getConnection();
     CalciteServerStatement stmt = calciteConnection.server.getStatement(h);
     final Signature signature = stmt.getSignature();
@@ -670,15 +670,15 @@ public class CalciteMetaImpl extends MetaImpl {
    * {@link Iterator}. */
   private static class LimitIterator<E> implements Iterator<E> {
     private final Iterator<E> iterator;
-    private final int limit;
+    private final long limit;
     int i = 0;
 
-    private LimitIterator(Iterator<E> iterator, int limit) {
+    private LimitIterator(Iterator<E> iterator, long limit) {
       this.iterator = iterator;
       this.limit = limit;
     }
 
-    static <E> Iterator<E> of(Iterator<E> iterator, int limit) {
+    static <E> Iterator<E> of(Iterator<E> iterator, long limit) {
       if (limit <= 0) {
         return iterator;
       }

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c818d50b/core/src/main/java/org/apache/calcite/jdbc/CalcitePrepare.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/jdbc/CalcitePrepare.java b/core/src/main/java/org/apache/calcite/jdbc/CalcitePrepare.java
index c792ed2..2453f98 100644
--- a/core/src/main/java/org/apache/calcite/jdbc/CalcitePrepare.java
+++ b/core/src/main/java/org/apache/calcite/jdbc/CalcitePrepare.java
@@ -89,7 +89,7 @@ public interface CalcitePrepare {
       String sql,
       Queryable<T> expression,
       Type elementType,
-      int maxRowCount);
+      long maxRowCount);
 
   <T> CalciteSignature<T> prepareQueryable(
       Context context,
@@ -260,7 +260,7 @@ public interface CalcitePrepare {
    * statement directly, without an explicit prepare step. */
   class CalciteSignature<T> extends Meta.Signature {
     @JsonIgnore public final RelDataType rowType;
-    private final int maxRowCount;
+    private final long maxRowCount;
     private final Bindable<T> bindable;
 
     public CalciteSignature(String sql,
@@ -269,7 +269,7 @@ public interface CalcitePrepare {
         RelDataType rowType,
         List<ColumnMetaData> columns,
         Meta.CursorFactory cursorFactory,
-        int maxRowCount,
+        long maxRowCount,
         Bindable<T> bindable) {
       super(columns, sql, parameterList, internalParameters, cursorFactory);
       this.rowType = rowType;

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c818d50b/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java b/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
index d78f160..674f093 100644
--- a/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
+++ b/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
@@ -535,7 +535,7 @@ public class CalcitePrepareImpl implements CalcitePrepare {
       String sql,
       Queryable<T> expression,
       Type elementType,
-      int maxRowCount) {
+      long maxRowCount) {
     return prepare_(context, sql, expression, elementType, maxRowCount);
   }
 
@@ -544,7 +544,7 @@ public class CalcitePrepareImpl implements CalcitePrepare {
       String sql,
       Queryable<T> queryable,
       Type elementType,
-      int maxRowCount) {
+      long maxRowCount) {
     if (SIMPLE_SQLS.contains(sql)) {
       return simplePrepare(context, sql);
     }
@@ -612,7 +612,7 @@ public class CalcitePrepareImpl implements CalcitePrepare {
       String sql,
       Queryable<T> queryable,
       Type elementType,
-      int maxRowCount,
+      long maxRowCount,
       CalciteCatalogReader catalogReader,
       RelOptPlanner planner) {
     final JavaTypeFactory typeFactory = context.getTypeFactory();
@@ -709,7 +709,7 @@ public class CalcitePrepareImpl implements CalcitePrepare {
     }
     //noinspection unchecked
     final Bindable<T> bindable = preparedResult.getBindable();
-    return new CalciteSignature<T>(
+    return new CalciteSignature<>(
         sql,
         parameters,
         preparingStmt.internalParameters,

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/c818d50b/linq4j/src/main/java/org/apache/calcite/linq4j/EnumerableDefaults.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/EnumerableDefaults.java b/linq4j/src/main/java/org/apache/calcite/linq4j/EnumerableDefaults.java
index e470032..57f9372 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/EnumerableDefaults.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/EnumerableDefaults.java
@@ -694,7 +694,8 @@ public abstract class EnumerableDefaults {
       Function0<TAccumulate> accumulatorInitializer,
       Function2<TAccumulate, TSource, TAccumulate> accumulatorAdder,
       final Function2<TKey, TAccumulate, TResult> resultSelector) {
-    return groupByMultiple_(new HashMap<TKey, TAccumulate>(),
+    return groupByMultiple_(
+        new HashMap<TKey, TAccumulate>(),
         enumerable,
         keySelectors,
         accumulatorInitializer,
@@ -716,8 +717,13 @@ public abstract class EnumerableDefaults {
       Function2<TAccumulate, TSource, TAccumulate> accumulatorAdder,
       Function2<TKey, TAccumulate, TResult> resultSelector,
       EqualityComparer<TKey> comparer) {
-    return groupBy_(new WrapMap<TKey, TAccumulate>(comparer), enumerable,
-        keySelector, accumulatorInitializer, accumulatorAdder, resultSelector);
+    return groupBy_(
+        new WrapMap<TKey, TAccumulate>(comparer),
+        enumerable,
+        keySelector,
+        accumulatorInitializer,
+        accumulatorAdder,
+        resultSelector);
   }
 
   private static <TSource, TKey, TAccumulate, TResult> Enumerable<TResult>
@@ -918,8 +924,15 @@ public abstract class EnumerableDefaults {
       final Function1<TSource, TKey> outerKeySelector,
       final Function1<TInner, TKey> innerKeySelector,
       final Function2<TSource, TInner, TResult> resultSelector) {
-    return join(outer, inner, outerKeySelector, innerKeySelector,
-        resultSelector, null, false, false);
+    return join(
+        outer,
+        inner,
+        outerKeySelector,
+        innerKeySelector,
+        resultSelector,
+        null,
+        false,
+        false);
   }
 
   /**
@@ -933,8 +946,15 @@ public abstract class EnumerableDefaults {
       Function1<TInner, TKey> innerKeySelector,
       Function2<TSource, TInner, TResult> resultSelector,
       EqualityComparer<TKey> comparer) {
-    return join(outer, inner, outerKeySelector, innerKeySelector,
-        resultSelector, comparer, false, false);
+    return join(
+        outer,
+        inner,
+        outerKeySelector,
+        innerKeySelector,
+        resultSelector,
+        comparer,
+        false,
+        false);
   }
 
   /**
@@ -949,8 +969,15 @@ public abstract class EnumerableDefaults {
       Function2<TSource, TInner, TResult> resultSelector,
       EqualityComparer<TKey> comparer, boolean generateNullsOnLeft,
       boolean generateNullsOnRight) {
-    return join_(outer, inner, outerKeySelector, innerKeySelector,
-        resultSelector, comparer, generateNullsOnLeft, generateNullsOnRight);
+    return join_(
+        outer,
+        inner,
+        outerKeySelector,
+        innerKeySelector,
+        resultSelector,
+        comparer,
+        generateNullsOnLeft,
+        generateNullsOnRight);
   }
 
   /** Implementation of join that builds the right input and probes with the
@@ -1985,6 +2012,21 @@ public abstract class EnumerableDefaults {
   }
 
   /**
+   * Returns a specified number of contiguous elements
+   * from the start of a sequence.
+   */
+  public static <TSource> Enumerable<TSource> take(Enumerable<TSource> source,
+      final long count) {
+    return takeWhileLong(
+        source, new Predicate2<TSource, Long>() {
+          public boolean apply(TSource v1, Long v2) {
+            // Count is 1-based
+            return v2 < count;
+          }
+        });
+  }
+
+  /**
    * Returns elements from a sequence as long as a
    * specified condition is true.
    */
@@ -2004,7 +2046,22 @@ public abstract class EnumerableDefaults {
       final Predicate2<TSource, Integer> predicate) {
     return new AbstractEnumerable<TSource>() {
       public Enumerator<TSource> enumerator() {
-        return new TakeWhileEnumerator<TSource>(source.enumerator(), predicate);
+        return new TakeWhileEnumerator<>(source.enumerator(), predicate);
+      }
+    };
+  }
+
+  /**
+   * Returns elements from a sequence as long as a
+   * specified condition is true. The element's index is used in the
+   * logic of the predicate function.
+   */
+  public static <TSource> Enumerable<TSource> takeWhileLong(
+      final Enumerable<TSource> source,
+      final Predicate2<TSource, Long> predicate) {
+    return new AbstractEnumerable<TSource>() {
+      public Enumerator<TSource> enumerator() {
+        return new TakeWhileLongEnumerator<>(source.enumerator(), predicate);
       }
     };
   }
@@ -2392,8 +2449,49 @@ public abstract class EnumerableDefaults {
 
     public boolean moveNext() {
       if (!done) {
-        if (enumerator.moveNext() && predicate.apply(enumerator.current(),
-            ++n)) {
+        if (enumerator.moveNext()
+            && predicate.apply(enumerator.current(), ++n)) {
+          return true;
+        } else {
+          done = true;
+        }
+      }
+      return false;
+    }
+
+    public void reset() {
+      enumerator.reset();
+      done = false;
+      n = -1;
+    }
+
+    public void close() {
+      enumerator.close();
+    }
+  }
+
+  /** Enumerable that implements take-while. */
+  static class TakeWhileLongEnumerator<TSource> implements Enumerator<TSource> {
+    private final Enumerator<TSource> enumerator;
+    private final Predicate2<TSource, Long> predicate;
+
+    boolean done = false;
+    long n = -1;
+
+    public TakeWhileLongEnumerator(Enumerator<TSource> enumerator,
+        Predicate2<TSource, Long> predicate) {
+      this.enumerator = enumerator;
+      this.predicate = predicate;
+    }
+
+    public TSource current() {
+      return enumerator.current();
+    }
+
+    public boolean moveNext() {
+      if (!done) {
+        if (enumerator.moveNext()
+            && predicate.apply(enumerator.current(), ++n)) {
           return true;
         } else {
           done = true;