You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by el...@apache.org on 2016/05/19 18:14:32 UTC

calcite git commit: [CALCITE-1243] Ensure signed fields are used in protobuf for specifying rows to return

Repository: calcite
Updated Branches:
  refs/heads/master 9bd7d7550 -> 987a257ae


[CALCITE-1243] Ensure signed fields are used in protobuf for specifying rows to return

It was found that the protobuf definitions where specifying some fields in some
messages as unsigned integers where Avatica was expecting negative values
to be meaningful. We failed to notice this in Avatica because the Java bindings
for protobuf are equivalent for signed and unsigned typed. This breaks clients
in other languages though.

Some confusing logic surrounding `maxRowCount` being used for two different
meanings (both maximum number of rows for the statement and the maximum number
of rows returned in the first frame) was also corrected since the values in
the protocol buffers were being changed.

The incorrect fields were deprecated, documented, and backwards-compatibally modified
so that older clients can continue to operate without change. Clients in languages
which do have differentiation between signedness in types will have to use the
newer version of the client and server to get this fix.


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

Branch: refs/heads/master
Commit: 987a257ae7cff588ac2f63518a7f75263a9bddb9
Parents: 9bd7d75
Author: Josh Elser <el...@apache.org>
Authored: Thu May 19 11:17:11 2016 -0400
Committer: Josh Elser <el...@apache.org>
Committed: Thu May 19 13:58:07 2016 -0400

----------------------------------------------------------------------
 .../java/org/apache/calcite/avatica/Meta.java   |  32 +-
 .../apache/calcite/avatica/proto/Requests.java  | 497 ++++++++++++++++---
 .../calcite/avatica/remote/RemoteMeta.java      |  17 +-
 .../apache/calcite/avatica/remote/Service.java  |  75 ++-
 avatica/core/src/main/protobuf/requests.proto   |  13 +-
 .../remote/ProtobufSerializationTest.java       | 174 +++++++
 .../apache/calcite/avatica/jdbc/JdbcMeta.java   |  18 +-
 .../calcite/avatica/jdbc/JdbcResultSet.java     |   6 +-
 avatica/site/_docs/protobuf_reference.md        |  28 +-
 9 files changed, 755 insertions(+), 105 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/987a257a/avatica/core/src/main/java/org/apache/calcite/avatica/Meta.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/Meta.java b/avatica/core/src/main/java/org/apache/calcite/avatica/Meta.java
index a562429..8afeda9 100644
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/Meta.java
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/Meta.java
@@ -223,10 +223,27 @@ public interface Meta {
    *
    * @return Result containing statement ID, and if a query, a result set and
    *     first frame of data
+   * @deprecated See {@link #prepareAndExecute(StatementHandle, String, long, int, PrepareCallback)}
    */
-  ExecuteResult prepareAndExecute(StatementHandle h, String sql,
+  @Deprecated ExecuteResult prepareAndExecute(StatementHandle h, String sql,
       long maxRowCount, PrepareCallback callback) throws NoSuchStatementException;
 
+  /** Prepares and executes a statement.
+   *
+   * @param h Statement handle
+   * @param sql SQL query
+   * @param maxRowCount Maximum number of rows for the entire query. Negative for no limit
+   *    (different meaning than JDBC).
+   * @param maxRowsInFirstFrame Maximum number of rows for the first frame.
+   * @param callback Callback to lock, clear and assign cursor
+   *
+   * @return Result containing statement ID, and if a query, a result set and
+   *     first frame of data
+   */
+  ExecuteResult prepareAndExecute(StatementHandle h, String sql,
+      long maxRowCount, int maxRowsInFirstFrame, PrepareCallback callback)
+      throws NoSuchStatementException;
+
   /** Prepares a statement and then executes a number of SQL commands in one pass.
    *
    * @param h Statement handle
@@ -269,10 +286,21 @@ public interface Meta {
    * @param maxRowCount Maximum number of rows to return; negative means
    * no limit
    * @return Execute result
+   * @deprecated See {@link #execute(StatementHandle, List, int)}
    */
-  ExecuteResult execute(StatementHandle h, List<TypedValue> parameterValues,
+  @Deprecated ExecuteResult execute(StatementHandle h, List<TypedValue> parameterValues,
       long maxRowCount) throws NoSuchStatementException;
 
+  /** Executes a prepared statement.
+   *
+   * @param h Statement handle
+   * @param parameterValues A list of parameter values; may be empty, not null
+   * @param maxRowsInFirstFrame Maximum number of rows to return in the Frame.
+   * @return Execute result
+   */
+  ExecuteResult execute(StatementHandle h, List<TypedValue> parameterValues,
+      int maxRowsInFirstFrame) throws NoSuchStatementException;
+
   /** Called during the creation of a statement to allocate a new handle.
    *
    * @param ch Connection handle

http://git-wip-us.apache.org/repos/asf/calcite/blob/987a257a/avatica/core/src/main/java/org/apache/calcite/avatica/proto/Requests.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/proto/Requests.java b/avatica/core/src/main/java/org/apache/calcite/avatica/proto/Requests.java
index 00c317d..ad9278e 100644
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/proto/Requests.java
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/proto/Requests.java
@@ -4717,6 +4717,10 @@ package org.apache.calcite.avatica.proto;
 
     /**
      * <code>optional uint64 max_row_count = 3;</code>
+     *
+     * <pre>
+     * Deprecated
+     * </pre>
      */
     long getMaxRowCount();
 
@@ -4724,6 +4728,24 @@ package org.apache.calcite.avatica.proto;
      * <code>optional uint32 statement_id = 4;</code>
      */
     int getStatementId();
+
+    /**
+     * <code>optional int64 max_rows_total = 5;</code>
+     *
+     * <pre>
+     * The maximum number of rows that will be allowed for this query
+     * </pre>
+     */
+    long getMaxRowsTotal();
+
+    /**
+     * <code>optional int32 first_frame_max_size = 6;</code>
+     *
+     * <pre>
+     * The maximum number of rows that will be returned in the
+     * </pre>
+     */
+    int getFirstFrameMaxSize();
   }
   /**
    * Protobuf type {@code PrepareAndExecuteRequest}
@@ -4745,6 +4767,8 @@ package org.apache.calcite.avatica.proto;
       sql_ = "";
       maxRowCount_ = 0L;
       statementId_ = 0;
+      maxRowsTotal_ = 0L;
+      firstFrameMaxSize_ = 0;
     }
 
     @java.lang.Override
@@ -4793,6 +4817,16 @@ package org.apache.calcite.avatica.proto;
               statementId_ = input.readUInt32();
               break;
             }
+            case 40: {
+
+              maxRowsTotal_ = input.readInt64();
+              break;
+            }
+            case 48: {
+
+              firstFrameMaxSize_ = input.readInt32();
+              break;
+            }
           }
         }
       } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -4889,6 +4923,10 @@ package org.apache.calcite.avatica.proto;
     private long maxRowCount_;
     /**
      * <code>optional uint64 max_row_count = 3;</code>
+     *
+     * <pre>
+     * Deprecated
+     * </pre>
      */
     public long getMaxRowCount() {
       return maxRowCount_;
@@ -4903,6 +4941,32 @@ package org.apache.calcite.avatica.proto;
       return statementId_;
     }
 
+    public static final int MAX_ROWS_TOTAL_FIELD_NUMBER = 5;
+    private long maxRowsTotal_;
+    /**
+     * <code>optional int64 max_rows_total = 5;</code>
+     *
+     * <pre>
+     * The maximum number of rows that will be allowed for this query
+     * </pre>
+     */
+    public long getMaxRowsTotal() {
+      return maxRowsTotal_;
+    }
+
+    public static final int FIRST_FRAME_MAX_SIZE_FIELD_NUMBER = 6;
+    private int firstFrameMaxSize_;
+    /**
+     * <code>optional int32 first_frame_max_size = 6;</code>
+     *
+     * <pre>
+     * The maximum number of rows that will be returned in the
+     * </pre>
+     */
+    public int getFirstFrameMaxSize() {
+      return firstFrameMaxSize_;
+    }
+
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
       byte isInitialized = memoizedIsInitialized;
@@ -4927,6 +4991,12 @@ package org.apache.calcite.avatica.proto;
       if (statementId_ != 0) {
         output.writeUInt32(4, statementId_);
       }
+      if (maxRowsTotal_ != 0L) {
+        output.writeInt64(5, maxRowsTotal_);
+      }
+      if (firstFrameMaxSize_ != 0) {
+        output.writeInt32(6, firstFrameMaxSize_);
+      }
     }
 
     public int getSerializedSize() {
@@ -4948,6 +5018,14 @@ package org.apache.calcite.avatica.proto;
         size += com.google.protobuf.CodedOutputStream
           .computeUInt32Size(4, statementId_);
       }
+      if (maxRowsTotal_ != 0L) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(5, maxRowsTotal_);
+      }
+      if (firstFrameMaxSize_ != 0) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(6, firstFrameMaxSize_);
+      }
       memoizedSize = size;
       return size;
     }
@@ -5071,6 +5149,10 @@ package org.apache.calcite.avatica.proto;
 
         statementId_ = 0;
 
+        maxRowsTotal_ = 0L;
+
+        firstFrameMaxSize_ = 0;
+
         return this;
       }
 
@@ -5097,6 +5179,8 @@ package org.apache.calcite.avatica.proto;
         result.sql_ = sql_;
         result.maxRowCount_ = maxRowCount_;
         result.statementId_ = statementId_;
+        result.maxRowsTotal_ = maxRowsTotal_;
+        result.firstFrameMaxSize_ = firstFrameMaxSize_;
         onBuilt();
         return result;
       }
@@ -5126,6 +5210,12 @@ package org.apache.calcite.avatica.proto;
         if (other.getStatementId() != 0) {
           setStatementId(other.getStatementId());
         }
+        if (other.getMaxRowsTotal() != 0L) {
+          setMaxRowsTotal(other.getMaxRowsTotal());
+        }
+        if (other.getFirstFrameMaxSize() != 0) {
+          setFirstFrameMaxSize(other.getFirstFrameMaxSize());
+        }
         onChanged();
         return this;
       }
@@ -5293,12 +5383,20 @@ package org.apache.calcite.avatica.proto;
       private long maxRowCount_ ;
       /**
        * <code>optional uint64 max_row_count = 3;</code>
+       *
+       * <pre>
+       * Deprecated
+       * </pre>
        */
       public long getMaxRowCount() {
         return maxRowCount_;
       }
       /**
        * <code>optional uint64 max_row_count = 3;</code>
+       *
+       * <pre>
+       * Deprecated
+       * </pre>
        */
       public Builder setMaxRowCount(long value) {
 
@@ -5308,6 +5406,10 @@ package org.apache.calcite.avatica.proto;
       }
       /**
        * <code>optional uint64 max_row_count = 3;</code>
+       *
+       * <pre>
+       * Deprecated
+       * </pre>
        */
       public Builder clearMaxRowCount() {
 
@@ -5341,6 +5443,82 @@ package org.apache.calcite.avatica.proto;
         onChanged();
         return this;
       }
+
+      private long maxRowsTotal_ ;
+      /**
+       * <code>optional int64 max_rows_total = 5;</code>
+       *
+       * <pre>
+       * The maximum number of rows that will be allowed for this query
+       * </pre>
+       */
+      public long getMaxRowsTotal() {
+        return maxRowsTotal_;
+      }
+      /**
+       * <code>optional int64 max_rows_total = 5;</code>
+       *
+       * <pre>
+       * The maximum number of rows that will be allowed for this query
+       * </pre>
+       */
+      public Builder setMaxRowsTotal(long value) {
+
+        maxRowsTotal_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int64 max_rows_total = 5;</code>
+       *
+       * <pre>
+       * The maximum number of rows that will be allowed for this query
+       * </pre>
+       */
+      public Builder clearMaxRowsTotal() {
+
+        maxRowsTotal_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      private int firstFrameMaxSize_ ;
+      /**
+       * <code>optional int32 first_frame_max_size = 6;</code>
+       *
+       * <pre>
+       * The maximum number of rows that will be returned in the
+       * </pre>
+       */
+      public int getFirstFrameMaxSize() {
+        return firstFrameMaxSize_;
+      }
+      /**
+       * <code>optional int32 first_frame_max_size = 6;</code>
+       *
+       * <pre>
+       * The maximum number of rows that will be returned in the
+       * </pre>
+       */
+      public Builder setFirstFrameMaxSize(int value) {
+
+        firstFrameMaxSize_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int32 first_frame_max_size = 6;</code>
+       *
+       * <pre>
+       * The maximum number of rows that will be returned in the
+       * </pre>
+       */
+      public Builder clearFirstFrameMaxSize() {
+
+        firstFrameMaxSize_ = 0;
+        onChanged();
+        return this;
+      }
       public final Builder setUnknownFields(
           final com.google.protobuf.UnknownFieldSet unknownFields) {
         return this;
@@ -5425,8 +5603,21 @@ package org.apache.calcite.avatica.proto;
 
     /**
      * <code>optional uint64 max_row_count = 3;</code>
+     *
+     * <pre>
+     * Deprecated
+     * </pre>
      */
     long getMaxRowCount();
+
+    /**
+     * <code>optional int64 max_rows_total = 4;</code>
+     *
+     * <pre>
+     * The maximum number of rows that will be allowed for this query
+     * </pre>
+     */
+    long getMaxRowsTotal();
   }
   /**
    * Protobuf type {@code PrepareRequest}
@@ -5447,6 +5638,7 @@ package org.apache.calcite.avatica.proto;
       connectionId_ = "";
       sql_ = "";
       maxRowCount_ = 0L;
+      maxRowsTotal_ = 0L;
     }
 
     @java.lang.Override
@@ -5490,6 +5682,11 @@ package org.apache.calcite.avatica.proto;
               maxRowCount_ = input.readUInt64();
               break;
             }
+            case 32: {
+
+              maxRowsTotal_ = input.readInt64();
+              break;
+            }
           }
         }
       } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -5586,11 +5783,28 @@ package org.apache.calcite.avatica.proto;
     private long maxRowCount_;
     /**
      * <code>optional uint64 max_row_count = 3;</code>
+     *
+     * <pre>
+     * Deprecated
+     * </pre>
      */
     public long getMaxRowCount() {
       return maxRowCount_;
     }
 
+    public static final int MAX_ROWS_TOTAL_FIELD_NUMBER = 4;
+    private long maxRowsTotal_;
+    /**
+     * <code>optional int64 max_rows_total = 4;</code>
+     *
+     * <pre>
+     * The maximum number of rows that will be allowed for this query
+     * </pre>
+     */
+    public long getMaxRowsTotal() {
+      return maxRowsTotal_;
+    }
+
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
       byte isInitialized = memoizedIsInitialized;
@@ -5612,6 +5826,9 @@ package org.apache.calcite.avatica.proto;
       if (maxRowCount_ != 0L) {
         output.writeUInt64(3, maxRowCount_);
       }
+      if (maxRowsTotal_ != 0L) {
+        output.writeInt64(4, maxRowsTotal_);
+      }
     }
 
     public int getSerializedSize() {
@@ -5629,6 +5846,10 @@ package org.apache.calcite.avatica.proto;
         size += com.google.protobuf.CodedOutputStream
           .computeUInt64Size(3, maxRowCount_);
       }
+      if (maxRowsTotal_ != 0L) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(4, maxRowsTotal_);
+      }
       memoizedSize = size;
       return size;
     }
@@ -5750,6 +5971,8 @@ package org.apache.calcite.avatica.proto;
 
         maxRowCount_ = 0L;
 
+        maxRowsTotal_ = 0L;
+
         return this;
       }
 
@@ -5775,6 +5998,7 @@ package org.apache.calcite.avatica.proto;
         result.connectionId_ = connectionId_;
         result.sql_ = sql_;
         result.maxRowCount_ = maxRowCount_;
+        result.maxRowsTotal_ = maxRowsTotal_;
         onBuilt();
         return result;
       }
@@ -5801,6 +6025,9 @@ package org.apache.calcite.avatica.proto;
         if (other.getMaxRowCount() != 0L) {
           setMaxRowCount(other.getMaxRowCount());
         }
+        if (other.getMaxRowsTotal() != 0L) {
+          setMaxRowsTotal(other.getMaxRowsTotal());
+        }
         onChanged();
         return this;
       }
@@ -5968,12 +6195,20 @@ package org.apache.calcite.avatica.proto;
       private long maxRowCount_ ;
       /**
        * <code>optional uint64 max_row_count = 3;</code>
+       *
+       * <pre>
+       * Deprecated
+       * </pre>
        */
       public long getMaxRowCount() {
         return maxRowCount_;
       }
       /**
        * <code>optional uint64 max_row_count = 3;</code>
+       *
+       * <pre>
+       * Deprecated
+       * </pre>
        */
       public Builder setMaxRowCount(long value) {
 
@@ -5983,6 +6218,10 @@ package org.apache.calcite.avatica.proto;
       }
       /**
        * <code>optional uint64 max_row_count = 3;</code>
+       *
+       * <pre>
+       * Deprecated
+       * </pre>
        */
       public Builder clearMaxRowCount() {
 
@@ -5990,6 +6229,44 @@ package org.apache.calcite.avatica.proto;
         onChanged();
         return this;
       }
+
+      private long maxRowsTotal_ ;
+      /**
+       * <code>optional int64 max_rows_total = 4;</code>
+       *
+       * <pre>
+       * The maximum number of rows that will be allowed for this query
+       * </pre>
+       */
+      public long getMaxRowsTotal() {
+        return maxRowsTotal_;
+      }
+      /**
+       * <code>optional int64 max_rows_total = 4;</code>
+       *
+       * <pre>
+       * The maximum number of rows that will be allowed for this query
+       * </pre>
+       */
+      public Builder setMaxRowsTotal(long value) {
+
+        maxRowsTotal_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int64 max_rows_total = 4;</code>
+       *
+       * <pre>
+       * The maximum number of rows that will be allowed for this query
+       * </pre>
+       */
+      public Builder clearMaxRowsTotal() {
+
+        maxRowsTotal_ = 0L;
+        onChanged();
+        return this;
+      }
       public final Builder setUnknownFields(
           final com.google.protobuf.UnknownFieldSet unknownFields) {
         return this;
@@ -6076,10 +6353,15 @@ package org.apache.calcite.avatica.proto;
      * <code>optional uint32 fetch_max_row_count = 4;</code>
      *
      * <pre>
-     * Maximum number of rows to be returned in the frame. Negative means no limit.
+     * Maximum number of rows to be returned in the frame. Negative means no limit. Deprecated!
      * </pre>
      */
     int getFetchMaxRowCount();
+
+    /**
+     * <code>optional int32 frame_max_size = 5;</code>
+     */
+    int getFrameMaxSize();
   }
   /**
    * Protobuf type {@code FetchRequest}
@@ -6101,6 +6383,7 @@ package org.apache.calcite.avatica.proto;
       statementId_ = 0;
       offset_ = 0L;
       fetchMaxRowCount_ = 0;
+      frameMaxSize_ = 0;
     }
 
     @java.lang.Override
@@ -6148,6 +6431,11 @@ package org.apache.calcite.avatica.proto;
               fetchMaxRowCount_ = input.readUInt32();
               break;
             }
+            case 40: {
+
+              frameMaxSize_ = input.readInt32();
+              break;
+            }
           }
         }
       } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -6230,13 +6518,22 @@ package org.apache.calcite.avatica.proto;
      * <code>optional uint32 fetch_max_row_count = 4;</code>
      *
      * <pre>
-     * Maximum number of rows to be returned in the frame. Negative means no limit.
+     * Maximum number of rows to be returned in the frame. Negative means no limit. Deprecated!
      * </pre>
      */
     public int getFetchMaxRowCount() {
       return fetchMaxRowCount_;
     }
 
+    public static final int FRAME_MAX_SIZE_FIELD_NUMBER = 5;
+    private int frameMaxSize_;
+    /**
+     * <code>optional int32 frame_max_size = 5;</code>
+     */
+    public int getFrameMaxSize() {
+      return frameMaxSize_;
+    }
+
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
       byte isInitialized = memoizedIsInitialized;
@@ -6261,6 +6558,9 @@ package org.apache.calcite.avatica.proto;
       if (fetchMaxRowCount_ != 0) {
         output.writeUInt32(4, fetchMaxRowCount_);
       }
+      if (frameMaxSize_ != 0) {
+        output.writeInt32(5, frameMaxSize_);
+      }
     }
 
     public int getSerializedSize() {
@@ -6283,6 +6583,10 @@ package org.apache.calcite.avatica.proto;
         size += com.google.protobuf.CodedOutputStream
           .computeUInt32Size(4, fetchMaxRowCount_);
       }
+      if (frameMaxSize_ != 0) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(5, frameMaxSize_);
+      }
       memoizedSize = size;
       return size;
     }
@@ -6406,6 +6710,8 @@ package org.apache.calcite.avatica.proto;
 
         fetchMaxRowCount_ = 0;
 
+        frameMaxSize_ = 0;
+
         return this;
       }
 
@@ -6432,6 +6738,7 @@ package org.apache.calcite.avatica.proto;
         result.statementId_ = statementId_;
         result.offset_ = offset_;
         result.fetchMaxRowCount_ = fetchMaxRowCount_;
+        result.frameMaxSize_ = frameMaxSize_;
         onBuilt();
         return result;
       }
@@ -6460,6 +6767,9 @@ package org.apache.calcite.avatica.proto;
         if (other.getFetchMaxRowCount() != 0) {
           setFetchMaxRowCount(other.getFetchMaxRowCount());
         }
+        if (other.getFrameMaxSize() != 0) {
+          setFrameMaxSize(other.getFrameMaxSize());
+        }
         onChanged();
         return this;
       }
@@ -6612,7 +6922,7 @@ package org.apache.calcite.avatica.proto;
        * <code>optional uint32 fetch_max_row_count = 4;</code>
        *
        * <pre>
-       * Maximum number of rows to be returned in the frame. Negative means no limit.
+       * Maximum number of rows to be returned in the frame. Negative means no limit. Deprecated!
        * </pre>
        */
       public int getFetchMaxRowCount() {
@@ -6622,7 +6932,7 @@ package org.apache.calcite.avatica.proto;
        * <code>optional uint32 fetch_max_row_count = 4;</code>
        *
        * <pre>
-       * Maximum number of rows to be returned in the frame. Negative means no limit.
+       * Maximum number of rows to be returned in the frame. Negative means no limit. Deprecated!
        * </pre>
        */
       public Builder setFetchMaxRowCount(int value) {
@@ -6635,7 +6945,7 @@ package org.apache.calcite.avatica.proto;
        * <code>optional uint32 fetch_max_row_count = 4;</code>
        *
        * <pre>
-       * Maximum number of rows to be returned in the frame. Negative means no limit.
+       * Maximum number of rows to be returned in the frame. Negative means no limit. Deprecated!
        * </pre>
        */
       public Builder clearFetchMaxRowCount() {
@@ -6644,6 +6954,32 @@ package org.apache.calcite.avatica.proto;
         onChanged();
         return this;
       }
+
+      private int frameMaxSize_ ;
+      /**
+       * <code>optional int32 frame_max_size = 5;</code>
+       */
+      public int getFrameMaxSize() {
+        return frameMaxSize_;
+      }
+      /**
+       * <code>optional int32 frame_max_size = 5;</code>
+       */
+      public Builder setFrameMaxSize(int value) {
+
+        frameMaxSize_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int32 frame_max_size = 5;</code>
+       */
+      public Builder clearFrameMaxSize() {
+
+        frameMaxSize_ = 0;
+        onChanged();
+        return this;
+      }
       public final Builder setUnknownFields(
           final com.google.protobuf.UnknownFieldSet unknownFields) {
         return this;
@@ -9419,9 +9755,13 @@ package org.apache.calcite.avatica.proto;
         int index);
 
     /**
-     * <code>optional uint64 max_row_count = 3;</code>
+     * <code>optional uint64 first_frame_max_size = 3;</code>
+     *
+     * <pre>
+     * The maximum number of rows to return in the first Frame
+     * </pre>
      */
-    long getMaxRowCount();
+    long getFirstFrameMaxSize();
 
     /**
      * <code>optional bool has_parameter_values = 4;</code>
@@ -9445,7 +9785,7 @@ package org.apache.calcite.avatica.proto;
     }
     private ExecuteRequest() {
       parameterValues_ = java.util.Collections.emptyList();
-      maxRowCount_ = 0L;
+      firstFrameMaxSize_ = 0L;
       hasParameterValues_ = false;
     }
 
@@ -9496,7 +9836,7 @@ package org.apache.calcite.avatica.proto;
             }
             case 24: {
 
-              maxRowCount_ = input.readUInt64();
+              firstFrameMaxSize_ = input.readUInt64();
               break;
             }
             case 32: {
@@ -9588,13 +9928,17 @@ package org.apache.calcite.avatica.proto;
       return parameterValues_.get(index);
     }
 
-    public static final int MAX_ROW_COUNT_FIELD_NUMBER = 3;
-    private long maxRowCount_;
+    public static final int FIRST_FRAME_MAX_SIZE_FIELD_NUMBER = 3;
+    private long firstFrameMaxSize_;
     /**
-     * <code>optional uint64 max_row_count = 3;</code>
+     * <code>optional uint64 first_frame_max_size = 3;</code>
+     *
+     * <pre>
+     * The maximum number of rows to return in the first Frame
+     * </pre>
      */
-    public long getMaxRowCount() {
-      return maxRowCount_;
+    public long getFirstFrameMaxSize() {
+      return firstFrameMaxSize_;
     }
 
     public static final int HAS_PARAMETER_VALUES_FIELD_NUMBER = 4;
@@ -9624,8 +9968,8 @@ package org.apache.calcite.avatica.proto;
       for (int i = 0; i < parameterValues_.size(); i++) {
         output.writeMessage(2, parameterValues_.get(i));
       }
-      if (maxRowCount_ != 0L) {
-        output.writeUInt64(3, maxRowCount_);
+      if (firstFrameMaxSize_ != 0L) {
+        output.writeUInt64(3, firstFrameMaxSize_);
       }
       if (hasParameterValues_ != false) {
         output.writeBool(4, hasParameterValues_);
@@ -9645,9 +9989,9 @@ package org.apache.calcite.avatica.proto;
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(2, parameterValues_.get(i));
       }
-      if (maxRowCount_ != 0L) {
+      if (firstFrameMaxSize_ != 0L) {
         size += com.google.protobuf.CodedOutputStream
-          .computeUInt64Size(3, maxRowCount_);
+          .computeUInt64Size(3, firstFrameMaxSize_);
       }
       if (hasParameterValues_ != false) {
         size += com.google.protobuf.CodedOutputStream
@@ -9781,7 +10125,7 @@ package org.apache.calcite.avatica.proto;
         } else {
           parameterValuesBuilder_.clear();
         }
-        maxRowCount_ = 0L;
+        firstFrameMaxSize_ = 0L;
 
         hasParameterValues_ = false;
 
@@ -9823,7 +10167,7 @@ package org.apache.calcite.avatica.proto;
         } else {
           result.parameterValues_ = parameterValuesBuilder_.build();
         }
-        result.maxRowCount_ = maxRowCount_;
+        result.firstFrameMaxSize_ = firstFrameMaxSize_;
         result.hasParameterValues_ = hasParameterValues_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
@@ -9870,8 +10214,8 @@ package org.apache.calcite.avatica.proto;
             }
           }
         }
-        if (other.getMaxRowCount() != 0L) {
-          setMaxRowCount(other.getMaxRowCount());
+        if (other.getFirstFrameMaxSize() != 0L) {
+          setFirstFrameMaxSize(other.getFirstFrameMaxSize());
         }
         if (other.getHasParameterValues() != false) {
           setHasParameterValues(other.getHasParameterValues());
@@ -10260,28 +10604,40 @@ package org.apache.calcite.avatica.proto;
         return parameterValuesBuilder_;
       }
 
-      private long maxRowCount_ ;
+      private long firstFrameMaxSize_ ;
       /**
-       * <code>optional uint64 max_row_count = 3;</code>
+       * <code>optional uint64 first_frame_max_size = 3;</code>
+       *
+       * <pre>
+       * The maximum number of rows to return in the first Frame
+       * </pre>
        */
-      public long getMaxRowCount() {
-        return maxRowCount_;
+      public long getFirstFrameMaxSize() {
+        return firstFrameMaxSize_;
       }
       /**
-       * <code>optional uint64 max_row_count = 3;</code>
+       * <code>optional uint64 first_frame_max_size = 3;</code>
+       *
+       * <pre>
+       * The maximum number of rows to return in the first Frame
+       * </pre>
        */
-      public Builder setMaxRowCount(long value) {
+      public Builder setFirstFrameMaxSize(long value) {
 
-        maxRowCount_ = value;
+        firstFrameMaxSize_ = value;
         onChanged();
         return this;
       }
       /**
-       * <code>optional uint64 max_row_count = 3;</code>
+       * <code>optional uint64 first_frame_max_size = 3;</code>
+       *
+       * <pre>
+       * The maximum number of rows to return in the first Frame
+       * </pre>
        */
-      public Builder clearMaxRowCount() {
+      public Builder clearFirstFrameMaxSize() {
 
-        maxRowCount_ = 0L;
+        firstFrameMaxSize_ = 0L;
         onChanged();
         return this;
       }
@@ -14548,40 +14904,43 @@ package org.apache.calcite.avatica.proto;
       "schema_pattern\030\002 \001(\t\022\032\n\022table_name_patte" +
       "rn\030\003 \001(\t\022\033\n\023column_name_pattern\030\004 \001(\t\022\025\n" +
       "\rconnection_id\030\005 \001(\t\"(\n\017TypeInfoRequest\022" +
-      "\025\n\rconnection_id\030\001 \001(\t\"k\n\030PrepareAndExec" +
-      "uteRequest\022\025\n\rconnection_id\030\001 \001(\t\022\013\n\003sql" +
-      "\030\002 \001(\t\022\025\n\rmax_row_count\030\003 \001(\004\022\024\n\014stateme" +
-      "nt_id\030\004 \001(\r\"K\n\016PrepareRequest\022\025\n\rconnect" +
-      "ion_id\030\001 \001(\t\022\013\n\003sql\030\002 \001(\t\022\025\n\rmax_row_cou" +
-      "nt\030\003 \001(\004\"h\n\014FetchRequest\022\025\n\rconnection_i",
+      "\025\n\rconnection_id\030\001 \001(\t\"\241\001\n\030PrepareAndExe" +
+      "cuteRequest\022\025\n\rconnection_id\030\001 \001(\t\022\013\n\003sq" +
+      "l\030\002 \001(\t\022\025\n\rmax_row_count\030\003 \001(\004\022\024\n\014statem" +
+      "ent_id\030\004 \001(\r\022\026\n\016max_rows_total\030\005 \001(\003\022\034\n\024" +
+      "first_frame_max_size\030\006 \001(\005\"c\n\016PrepareReq" +
+      "uest\022\025\n\rconnection_id\030\001 \001(\t\022\013\n\003sql\030\002 \001(\t",
+      "\022\025\n\rmax_row_count\030\003 \001(\004\022\026\n\016max_rows_tota" +
+      "l\030\004 \001(\003\"\200\001\n\014FetchRequest\022\025\n\rconnection_i" +
       "d\030\001 \001(\t\022\024\n\014statement_id\030\002 \001(\r\022\016\n\006offset\030" +
-      "\003 \001(\004\022\033\n\023fetch_max_row_count\030\004 \001(\r\"/\n\026Cr" +
-      "eateStatementRequest\022\025\n\rconnection_id\030\001 " +
-      "\001(\t\"D\n\025CloseStatementRequest\022\025\n\rconnecti" +
-      "on_id\030\001 \001(\t\022\024\n\014statement_id\030\002 \001(\r\"\213\001\n\025Op" +
-      "enConnectionRequest\022\025\n\rconnection_id\030\001 \001" +
-      "(\t\022.\n\004info\030\002 \003(\0132 .OpenConnectionRequest" +
-      ".InfoEntry\032+\n\tInfoEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005" +
-      "value\030\002 \001(\t:\0028\001\"/\n\026CloseConnectionReques" +
-      "t\022\025\n\rconnection_id\030\001 \001(\t\"Y\n\025ConnectionSy",
-      "ncRequest\022\025\n\rconnection_id\030\001 \001(\t\022)\n\nconn" +
-      "_props\030\002 \001(\0132\025.ConnectionProperties\"\227\001\n\016" +
-      "ExecuteRequest\022)\n\017statementHandle\030\001 \001(\0132" +
-      "\020.StatementHandle\022%\n\020parameter_values\030\002 " +
-      "\003(\0132\013.TypedValue\022\025\n\rmax_row_count\030\003 \001(\004\022" +
-      "\034\n\024has_parameter_values\030\004 \001(\010\"m\n\022SyncRes" +
-      "ultsRequest\022\025\n\rconnection_id\030\001 \001(\t\022\024\n\014st" +
-      "atement_id\030\002 \001(\r\022\032\n\005state\030\003 \001(\0132\013.QueryS" +
-      "tate\022\016\n\006offset\030\004 \001(\004\"&\n\rCommitRequest\022\025\n" +
-      "\rconnection_id\030\001 \001(\t\"(\n\017RollbackRequest\022",
-      "\025\n\rconnection_id\030\001 \001(\t\"b\n\035PrepareAndExec" +
-      "uteBatchRequest\022\025\n\rconnection_id\030\001 \001(\t\022\024" +
-      "\n\014statement_id\030\002 \001(\r\022\024\n\014sql_commands\030\003 \003" +
-      "(\t\"4\n\013UpdateBatch\022%\n\020parameter_values\030\001 " +
-      "\003(\0132\013.TypedValue\"a\n\023ExecuteBatchRequest\022" +
-      "\025\n\rconnection_id\030\001 \001(\t\022\024\n\014statement_id\030\002" +
-      " \001(\r\022\035\n\007updates\030\003 \003(\0132\014.UpdateBatchB\"\n o" +
-      "rg.apache.calcite.avatica.protob\006proto3"
+      "\003 \001(\004\022\033\n\023fetch_max_row_count\030\004 \001(\r\022\026\n\016fr" +
+      "ame_max_size\030\005 \001(\005\"/\n\026CreateStatementReq" +
+      "uest\022\025\n\rconnection_id\030\001 \001(\t\"D\n\025CloseStat" +
+      "ementRequest\022\025\n\rconnection_id\030\001 \001(\t\022\024\n\014s" +
+      "tatement_id\030\002 \001(\r\"\213\001\n\025OpenConnectionRequ" +
+      "est\022\025\n\rconnection_id\030\001 \001(\t\022.\n\004info\030\002 \003(\013" +
+      "2 .OpenConnectionRequest.InfoEntry\032+\n\tIn",
+      "foEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"" +
+      "/\n\026CloseConnectionRequest\022\025\n\rconnection_" +
+      "id\030\001 \001(\t\"Y\n\025ConnectionSyncRequest\022\025\n\rcon" +
+      "nection_id\030\001 \001(\t\022)\n\nconn_props\030\002 \001(\0132\025.C" +
+      "onnectionProperties\"\236\001\n\016ExecuteRequest\022)" +
+      "\n\017statementHandle\030\001 \001(\0132\020.StatementHandl" +
+      "e\022%\n\020parameter_values\030\002 \003(\0132\013.TypedValue" +
+      "\022\034\n\024first_frame_max_size\030\003 \001(\004\022\034\n\024has_pa" +
+      "rameter_values\030\004 \001(\010\"m\n\022SyncResultsReque" +
+      "st\022\025\n\rconnection_id\030\001 \001(\t\022\024\n\014statement_i",
+      "d\030\002 \001(\r\022\032\n\005state\030\003 \001(\0132\013.QueryState\022\016\n\006o" +
+      "ffset\030\004 \001(\004\"&\n\rCommitRequest\022\025\n\rconnecti" +
+      "on_id\030\001 \001(\t\"(\n\017RollbackRequest\022\025\n\rconnec" +
+      "tion_id\030\001 \001(\t\"b\n\035PrepareAndExecuteBatchR" +
+      "equest\022\025\n\rconnection_id\030\001 \001(\t\022\024\n\014stateme" +
+      "nt_id\030\002 \001(\r\022\024\n\014sql_commands\030\003 \003(\t\"4\n\013Upd" +
+      "ateBatch\022%\n\020parameter_values\030\001 \003(\0132\013.Typ" +
+      "edValue\"a\n\023ExecuteBatchRequest\022\025\n\rconnec" +
+      "tion_id\030\001 \001(\t\022\024\n\014statement_id\030\002 \001(\r\022\035\n\007u" +
+      "pdates\030\003 \003(\0132\014.UpdateBatchB\"\n org.apache",
+      ".calcite.avatica.protob\006proto3"
     };
     com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
         new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
@@ -14643,19 +15002,19 @@ package org.apache.calcite.avatica.proto;
     internal_static_PrepareAndExecuteRequest_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessage.FieldAccessorTable(
         internal_static_PrepareAndExecuteRequest_descriptor,
-        new java.lang.String[] { "ConnectionId", "Sql", "MaxRowCount", "StatementId", });
+        new java.lang.String[] { "ConnectionId", "Sql", "MaxRowCount", "StatementId", "MaxRowsTotal", "FirstFrameMaxSize", });
     internal_static_PrepareRequest_descriptor =
       getDescriptor().getMessageTypes().get(8);
     internal_static_PrepareRequest_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessage.FieldAccessorTable(
         internal_static_PrepareRequest_descriptor,
-        new java.lang.String[] { "ConnectionId", "Sql", "MaxRowCount", });
+        new java.lang.String[] { "ConnectionId", "Sql", "MaxRowCount", "MaxRowsTotal", });
     internal_static_FetchRequest_descriptor =
       getDescriptor().getMessageTypes().get(9);
     internal_static_FetchRequest_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessage.FieldAccessorTable(
         internal_static_FetchRequest_descriptor,
-        new java.lang.String[] { "ConnectionId", "StatementId", "Offset", "FetchMaxRowCount", });
+        new java.lang.String[] { "ConnectionId", "StatementId", "Offset", "FetchMaxRowCount", "FrameMaxSize", });
     internal_static_CreateStatementRequest_descriptor =
       getDescriptor().getMessageTypes().get(10);
     internal_static_CreateStatementRequest_fieldAccessorTable = new
@@ -14697,7 +15056,7 @@ package org.apache.calcite.avatica.proto;
     internal_static_ExecuteRequest_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessage.FieldAccessorTable(
         internal_static_ExecuteRequest_descriptor,
-        new java.lang.String[] { "StatementHandle", "ParameterValues", "MaxRowCount", "HasParameterValues", });
+        new java.lang.String[] { "StatementHandle", "ParameterValues", "FirstFrameMaxSize", "HasParameterValues", });
     internal_static_SyncResultsRequest_descriptor =
       getDescriptor().getMessageTypes().get(16);
     internal_static_SyncResultsRequest_fieldAccessorTable = new

http://git-wip-us.apache.org/repos/asf/calcite/blob/987a257a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
index 152e0ca..de6419a 100644
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
@@ -243,8 +243,14 @@ class RemoteMeta extends MetaImpl {
         });
   }
 
+  @Override public ExecuteResult prepareAndExecute(StatementHandle h, String sql, long maxRowCount,
+      PrepareCallback callback) throws NoSuchStatementException {
+    return prepareAndExecute(h, sql, maxRowCount, (int) maxRowCount, callback);
+  }
+
   @Override public ExecuteResult prepareAndExecute(final StatementHandle h, final String sql,
-      final long maxRowCount, final PrepareCallback callback) throws NoSuchStatementException {
+      final long maxRowCount, int maxRowsInFirstFrame, final PrepareCallback callback)
+      throws NoSuchStatementException {
     try {
       return connection.invokeWithRetries(
           new CallableWithoutException<ExecuteResult>() {
@@ -316,15 +322,20 @@ class RemoteMeta extends MetaImpl {
     }
   }
 
+  @Override public ExecuteResult execute(StatementHandle h, List<TypedValue> parameterValues,
+      long maxRowCount) throws NoSuchStatementException {
+    return execute(h, parameterValues, (int) maxRowCount);
+  }
+
   @Override public ExecuteResult execute(final StatementHandle h,
-      final List<TypedValue> parameterValues, final long maxRowCount)
+      final List<TypedValue> parameterValues, final int maxRowsInFirstFrame)
       throws NoSuchStatementException {
     try {
       return connection.invokeWithRetries(
           new CallableWithoutException<ExecuteResult>() {
             public ExecuteResult call() {
               final Service.ExecuteResponse response = service.apply(
-                  new Service.ExecuteRequest(h, parameterValues, maxRowCount));
+                  new Service.ExecuteRequest(h, parameterValues, maxRowsInFirstFrame));
 
               if (response.missingStatement) {
                 throw new RuntimeException(new NoSuchStatementException(h));

http://git-wip-us.apache.org/repos/asf/calcite/blob/987a257a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Service.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Service.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Service.java
index 1bf6353..b3accd9 100644
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Service.java
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Service.java
@@ -872,7 +872,8 @@ public interface Service {
   }
 
   /** Request for
-   * {@link Meta#prepareAndExecute(Meta.StatementHandle, String, long, Meta.PrepareCallback)}. */
+   * {@link Meta#prepareAndExecute(Meta.StatementHandle, String, long, int, Meta.PrepareCallback)}.
+   */
   class PrepareAndExecuteRequest extends Request {
     private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.
         PrepareAndExecuteRequest.getDescriptor().findFieldByNumber(
@@ -880,29 +881,44 @@ public interface Service {
     private static final FieldDescriptor SQL_DESCRIPTOR = Requests.
         PrepareAndExecuteRequest.getDescriptor().findFieldByNumber(
             Requests.PrepareAndExecuteRequest.SQL_FIELD_NUMBER);
+    private static final FieldDescriptor MAX_ROWS_TOTAL_DESCRIPTOR = Requests.
+        PrepareAndExecuteRequest.getDescriptor().findFieldByNumber(
+            Requests.PrepareAndExecuteRequest.MAX_ROWS_TOTAL_FIELD_NUMBER);
+    private static final FieldDescriptor FIRST_FRAME_MAX_SIZE_DESCRIPTOR = Requests.
+        PrepareAndExecuteRequest.getDescriptor().findFieldByNumber(
+            Requests.PrepareAndExecuteRequest.FIRST_FRAME_MAX_SIZE_FIELD_NUMBER);
 
     public final String connectionId;
     public final String sql;
     public final long maxRowCount;
+    public final int maxRowsInFirstFrame;
     public final int statementId;
 
     PrepareAndExecuteRequest() {
       connectionId = null;
       sql = null;
       maxRowCount = 0;
+      maxRowsInFirstFrame = 0;
       statementId = 0;
     }
 
+    public PrepareAndExecuteRequest(String connectionId, int statementId, String sql,
+        long maxRowCount) {
+      this(connectionId, statementId, sql, maxRowCount, (int) maxRowCount);
+    }
+
     @JsonCreator
     public PrepareAndExecuteRequest(
         @JsonProperty("connectionId") String connectionId,
         @JsonProperty("statementId") int statementId,
         @JsonProperty("sql") String sql,
-        @JsonProperty("maxRowCount") long maxRowCount) {
+        @JsonProperty("maxRowsTotal") long maxRowCount,
+        @JsonProperty("maxRowsInFirstFrame") int maxRowsInFirstFrame) {
       this.connectionId = connectionId;
       this.statementId = statementId;
       this.sql = sql;
       this.maxRowCount = maxRowCount;
+      this.maxRowsInFirstFrame = maxRowsInFirstFrame;
     }
 
     @Override ExecuteResponse accept(Service service) {
@@ -923,8 +939,20 @@ public interface Service {
         sql = msg.getSql();
       }
 
+      // Use the old attribute, unless the new is set
+      long maxRowsTotal = msg.getMaxRowCount();
+      if (msg.hasField(MAX_ROWS_TOTAL_DESCRIPTOR)) {
+        maxRowsTotal = msg.getMaxRowsTotal();
+      }
+
+      // Use maxRowCount (cast to an integer) if firstFrameMaxSize isn't set
+      int maxRowsInFirstFrame = (int) maxRowsTotal;
+      if (msg.hasField(FIRST_FRAME_MAX_SIZE_DESCRIPTOR)) {
+        maxRowsInFirstFrame = msg.getFirstFrameMaxSize();
+      }
+
       return new PrepareAndExecuteRequest(connectionId, msg.getStatementId(), sql,
-          msg.getMaxRowCount());
+          maxRowsTotal, maxRowsInFirstFrame);
     }
 
     @Override Requests.PrepareAndExecuteRequest serialize() {
@@ -938,7 +966,9 @@ public interface Service {
         builder.setSql(sql);
       }
       builder.setStatementId(statementId);
-      builder.setMaxRowCount(maxRowCount);
+      // Set both attributes for backwards compat
+      builder.setMaxRowCount(maxRowCount).setMaxRowsTotal(maxRowCount);
+      builder.setFirstFrameMaxSize(maxRowsInFirstFrame);
 
       return builder.build();
     }
@@ -947,6 +977,7 @@ public interface Service {
       int result = 1;
       result = p(result, connectionId);
       result = p(result, maxRowCount);
+      result = p(result, maxRowsInFirstFrame);
       result = p(result, sql);
       result = p(result, statementId);
       return result;
@@ -957,6 +988,7 @@ public interface Service {
           || o instanceof PrepareAndExecuteRequest
           && statementId == ((PrepareAndExecuteRequest) o).statementId
           && maxRowCount == ((PrepareAndExecuteRequest) o).maxRowCount
+          && maxRowsInFirstFrame == ((PrepareAndExecuteRequest) o).maxRowsInFirstFrame
           && Objects.equals(connectionId, ((PrepareAndExecuteRequest) o).connectionId)
           && Objects.equals(sql, ((PrepareAndExecuteRequest) o).sql);
     }
@@ -995,9 +1027,9 @@ public interface Service {
       final Requests.ExecuteRequest msg = ProtobufService.castProtobufMessage(genericMsg,
           Requests.ExecuteRequest.class);
 
-      Meta.StatementHandle statemetnHandle = null;
+      Meta.StatementHandle statementHandle = null;
       if (msg.hasField(STATEMENT_HANDLE_DESCRIPTOR)) {
-        statemetnHandle = Meta.StatementHandle.fromProto(msg.getStatementHandle());
+        statementHandle = Meta.StatementHandle.fromProto(msg.getStatementHandle());
       }
 
       List<TypedValue> values = null;
@@ -1008,7 +1040,7 @@ public interface Service {
         }
       }
 
-      return new ExecuteRequest(statemetnHandle, values, msg.getMaxRowCount());
+      return new ExecuteRequest(statementHandle, values, msg.getFirstFrameMaxSize());
     }
 
     @Override Requests.ExecuteRequest serialize() {
@@ -1031,7 +1063,7 @@ public interface Service {
         builder.setHasParameterValues(false);
       }
 
-      builder.setMaxRowCount(maxRowCount);
+      builder.setFirstFrameMaxSize(maxRowCount);
 
       return builder.build();
     }
@@ -1133,6 +1165,9 @@ public interface Service {
         getDescriptor().findFieldByNumber(Requests.PrepareRequest.CONNECTION_ID_FIELD_NUMBER);
     private static final FieldDescriptor SQL_DESCRIPTOR = Requests.PrepareRequest.
         getDescriptor().findFieldByNumber(Requests.PrepareRequest.SQL_FIELD_NUMBER);
+    private static final FieldDescriptor MAX_ROWS_TOTAL_DESCRIPTOR = Requests.PrepareRequest.
+        getDescriptor().findFieldByNumber(Requests.PrepareRequest.MAX_ROWS_TOTAL_FIELD_NUMBER);
+
     public final String connectionId;
     public final String sql;
     public final long maxRowCount;
@@ -1171,7 +1206,13 @@ public interface Service {
         sql = msg.getSql();
       }
 
-      return new PrepareRequest(connectionId, sql, msg.getMaxRowCount());
+      // Use the old field unless the new field is provided
+      long totalRowsForStatement = msg.getMaxRowCount();
+      if (msg.hasField(MAX_ROWS_TOTAL_DESCRIPTOR)) {
+        totalRowsForStatement = msg.getMaxRowsTotal();
+      }
+
+      return new PrepareRequest(connectionId, sql, totalRowsForStatement);
     }
 
     @Override Requests.PrepareRequest serialize() {
@@ -1185,7 +1226,8 @@ public interface Service {
         builder.setSql(sql);
       }
 
-      return builder.setMaxRowCount(maxRowCount).build();
+      // Set both field for backwards compatibility
+      return builder.setMaxRowCount(maxRowCount).setMaxRowsTotal(maxRowCount).build();
     }
 
     @Override public int hashCode() {
@@ -1272,6 +1314,9 @@ public interface Service {
   class FetchRequest extends Request {
     private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.FetchRequest.
         getDescriptor().findFieldByNumber(Requests.FetchRequest.CONNECTION_ID_FIELD_NUMBER);
+    private static final FieldDescriptor FRAME_MAX_SIZE_DESCRIPTOR = Requests.FetchRequest.
+        getDescriptor().findFieldByNumber(Requests.FetchRequest.FRAME_MAX_SIZE_FIELD_NUMBER);
+
     public final String connectionId;
     public final int statementId;
     public final long offset;
@@ -1311,8 +1356,13 @@ public interface Service {
         connectionId = msg.getConnectionId();
       }
 
+      int fetchMaxRowCount = msg.getFetchMaxRowCount();
+      if (msg.hasField(FRAME_MAX_SIZE_DESCRIPTOR)) {
+        fetchMaxRowCount = msg.getFrameMaxSize();
+      }
+
       return new FetchRequest(connectionId, msg.getStatementId(), msg.getOffset(),
-          msg.getFetchMaxRowCount());
+          fetchMaxRowCount);
     }
 
     @Override Requests.FetchRequest serialize() {
@@ -1324,7 +1374,8 @@ public interface Service {
 
       builder.setStatementId(statementId);
       builder.setOffset(offset);
-      builder.setFetchMaxRowCount(fetchMaxRowCount);
+      // Both fields for backwards compat
+      builder.setFetchMaxRowCount(fetchMaxRowCount).setFrameMaxSize(fetchMaxRowCount);
 
       return builder.build();
     }

http://git-wip-us.apache.org/repos/asf/calcite/blob/987a257a/avatica/core/src/main/protobuf/requests.proto
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/protobuf/requests.proto b/avatica/core/src/main/protobuf/requests.proto
index afa8aec..228be27 100644
--- a/avatica/core/src/main/protobuf/requests.proto
+++ b/avatica/core/src/main/protobuf/requests.proto
@@ -72,15 +72,19 @@ message TypeInfoRequest {
 message PrepareAndExecuteRequest {
   string connection_id = 1;
   string sql = 2;
-  uint64 max_row_count = 3;
+  uint64 max_row_count = 3; // Deprecated
   uint32 statement_id = 4;
+  int64 max_rows_total = 5; // The maximum number of rows that will be allowed for this query
+  int32 first_frame_max_size = 6; // The maximum number of rows that will be returned in the
+                                  // first Frame returned for this query.
 }
 
 // Request for Meta.prepare(Meta.ConnectionHandle, String, long)
 message PrepareRequest {
   string connection_id = 1;
   string sql = 2;
-  uint64 max_row_count = 3;
+  uint64 max_row_count = 3; // Deprecated
+  int64 max_rows_total = 4; // The maximum number of rows that will be allowed for this query
 }
 
 // Request for Meta#fetch(Meta.StatementHandle, List, long, int)
@@ -88,7 +92,8 @@ message FetchRequest {
   string connection_id = 1;
   uint32 statement_id = 2;
   uint64 offset = 3;
-  uint32 fetch_max_row_count = 4; // Maximum number of rows to be returned in the frame. Negative means no limit.
+  uint32 fetch_max_row_count = 4; // Maximum number of rows to be returned in the frame. Negative means no limit. Deprecated!
+  int32 frame_max_size = 5;
 }
 
 // Request for Meta#createStatement(Meta.ConnectionHandle)
@@ -122,7 +127,7 @@ message ConnectionSyncRequest {
 message ExecuteRequest {
   StatementHandle statementHandle = 1;
   repeated TypedValue parameter_values = 2;
-  uint64 max_row_count = 3;
+  uint64 first_frame_max_size = 3; // The maximum number of rows to return in the first Frame
   bool has_parameter_values = 4;
 }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/987a257a/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufSerializationTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufSerializationTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufSerializationTest.java
index cd8a329..d439c83 100644
--- a/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufSerializationTest.java
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufSerializationTest.java
@@ -31,6 +31,9 @@ import org.junit.Test;
 import java.io.ByteArrayOutputStream;
 import java.util.Arrays;
 import java.util.List;
+import java.util.UUID;
+
+import static org.junit.Assert.assertEquals;
 
 /**
  * Protobuf serialization tests.
@@ -70,6 +73,177 @@ public class ProtobufSerializationTest {
     Assert.assertEquals(executeRequest, newRequest);
   }
 
+  @Test public void testPrepareSerialization() throws Exception {
+    final String sql = "SELECT * FROM FOO";
+    final String connectionId = UUID.randomUUID().toString();
+
+    for (long maxRowCount : Arrays.asList(-1L, 0L, 1L, Long.MAX_VALUE)) {
+      Service.PrepareRequest prepareReq = new Service.PrepareRequest(connectionId, sql,
+          maxRowCount);
+
+      Requests.PrepareRequest prepareProtoReq = prepareReq.serialize();
+      assertEquals(maxRowCount, prepareProtoReq.getMaxRowCount());
+      assertEquals(maxRowCount, prepareProtoReq.getMaxRowsTotal());
+
+      assertEquals(prepareReq, prepareReq.deserialize(prepareProtoReq));
+    }
+  }
+
+  @Test public void testPrepareDeserialization() throws Exception {
+    final String sql = "SELECT * FROM FOO";
+    final String connectionId = UUID.randomUUID().toString();
+    final long maxRowCount = 200L;
+
+    // The "current" serialization strategy.
+    Requests.PrepareRequest protoPrepare = Requests.PrepareRequest.newBuilder().
+        setConnectionId(connectionId).setSql(sql).setMaxRowsTotal(maxRowCount).build();
+
+    Service.PrepareRequest prepareReq = new Service.PrepareRequest().deserialize(protoPrepare);
+    assertEquals(maxRowCount, prepareReq.maxRowCount);
+
+    // The "old" serialization strategy.
+    protoPrepare = Requests.PrepareRequest.newBuilder().
+        setConnectionId(connectionId).setSql(sql).setMaxRowCount(maxRowCount).build();
+
+    prepareReq = new Service.PrepareRequest().deserialize(protoPrepare);
+    assertEquals(maxRowCount, prepareReq.maxRowCount);
+
+    // Both the new and old provided should default to the new
+    protoPrepare = Requests.PrepareRequest.newBuilder().
+        setConnectionId(connectionId).setSql(sql).setMaxRowCount(500L)
+        .setMaxRowsTotal(maxRowCount).build();
+
+    prepareReq = new Service.PrepareRequest().deserialize(protoPrepare);
+    assertEquals(maxRowCount, prepareReq.maxRowCount);
+  }
+
+  @Test public void testPrepareAndExecuteSerialization() throws Exception {
+    final String sql = "SELECT * FROM FOO";
+    final int statementId = 12345;
+    final String connectionId = UUID.randomUUID().toString();
+
+    for (long maxRowCount : Arrays.asList(-1L, 0L, 1L, Long.MAX_VALUE)) {
+      Service.PrepareAndExecuteRequest prepareAndExecuteReq =
+          new Service.PrepareAndExecuteRequest(connectionId, statementId, sql, maxRowCount);
+
+      Requests.PrepareAndExecuteRequest prepareAndExecuteProtoReq =
+          prepareAndExecuteReq.serialize();
+      assertEquals(maxRowCount, prepareAndExecuteProtoReq.getMaxRowCount());
+      assertEquals(maxRowCount, prepareAndExecuteProtoReq.getMaxRowsTotal());
+      assertEquals((int) maxRowCount, prepareAndExecuteProtoReq.getFirstFrameMaxSize());
+
+      assertEquals(prepareAndExecuteReq,
+          prepareAndExecuteReq.deserialize(prepareAndExecuteProtoReq));
+    }
+
+    int maxRowsInFirstFrame = 50;
+    for (long maxRowCount : Arrays.asList(-1L, 0L, 1L, Long.MAX_VALUE)) {
+      Service.PrepareAndExecuteRequest prepareAndExecuteReq =
+          new Service.PrepareAndExecuteRequest(connectionId, statementId, sql, maxRowCount,
+              maxRowsInFirstFrame);
+
+      Requests.PrepareAndExecuteRequest prepareAndExecuteProtoReq =
+          prepareAndExecuteReq.serialize();
+      assertEquals(maxRowCount, prepareAndExecuteProtoReq.getMaxRowCount());
+      assertEquals(maxRowCount, prepareAndExecuteProtoReq.getMaxRowsTotal());
+      assertEquals(maxRowsInFirstFrame, prepareAndExecuteProtoReq.getFirstFrameMaxSize());
+
+      assertEquals(prepareAndExecuteReq,
+          prepareAndExecuteReq.deserialize(prepareAndExecuteProtoReq));
+    }
+  }
+
+  @Test public void testPrepareAndExecuteDeserialization() throws Exception {
+    final String sql = "SELECT * FROM FOO";
+    final String connectionId = UUID.randomUUID().toString();
+    final long maxRowCount = 200L;
+    final int maxRowsInFirstFrame = 50;
+
+    // The "current" serialization strategy (maxRowsTotal and firstFrameMaxSize)
+    Requests.PrepareAndExecuteRequest protoPrepare = Requests.PrepareAndExecuteRequest.newBuilder().
+        setConnectionId(connectionId).setSql(sql).setMaxRowsTotal(maxRowCount).
+        setFirstFrameMaxSize(maxRowsInFirstFrame).build();
+
+    Service.PrepareAndExecuteRequest prepareAndExecuteReq = new Service.PrepareAndExecuteRequest().
+        deserialize(protoPrepare);
+    assertEquals(maxRowCount, prepareAndExecuteReq.maxRowCount);
+    assertEquals(maxRowsInFirstFrame, prepareAndExecuteReq.maxRowsInFirstFrame);
+
+    // The "old" serialization strategy (maxRowCount)
+    protoPrepare = Requests.PrepareAndExecuteRequest.newBuilder().
+        setConnectionId(connectionId).setSql(sql).setMaxRowCount(maxRowCount).build();
+
+    prepareAndExecuteReq = new Service.PrepareAndExecuteRequest().deserialize(protoPrepare);
+    assertEquals(maxRowCount, prepareAndExecuteReq.maxRowCount);
+    assertEquals((int) maxRowCount, prepareAndExecuteReq.maxRowsInFirstFrame);
+
+    // Both the new and old provided should default to the new (firstFrameMaxSize should be the
+    // the same as what ultimately is set to maxRowCount)
+    protoPrepare = Requests.PrepareAndExecuteRequest.newBuilder().
+        setConnectionId(connectionId).setSql(sql).setMaxRowCount(500L)
+        .setMaxRowsTotal(maxRowCount).build();
+
+    prepareAndExecuteReq = new Service.PrepareAndExecuteRequest().deserialize(protoPrepare);
+    assertEquals(maxRowCount, prepareAndExecuteReq.maxRowCount);
+    assertEquals((int) maxRowCount, prepareAndExecuteReq.maxRowsInFirstFrame);
+
+    // Same as previous example, but explicitly setting maxRowsInFirstFrame too
+    protoPrepare = Requests.PrepareAndExecuteRequest.newBuilder().
+        setConnectionId(connectionId).setSql(sql).setMaxRowCount(500L)
+        .setMaxRowsTotal(maxRowCount).setFirstFrameMaxSize(maxRowsInFirstFrame).build();
+
+    prepareAndExecuteReq = new Service.PrepareAndExecuteRequest().deserialize(protoPrepare);
+    assertEquals(maxRowCount, prepareAndExecuteReq.maxRowCount);
+    assertEquals(maxRowsInFirstFrame, prepareAndExecuteReq.maxRowsInFirstFrame);
+  }
+
+  @Test public void testFetchRequestSerialization() throws Exception {
+    final String connectionId = UUID.randomUUID().toString();
+    final int statementId = 12345;
+    final long offset = 0L;
+
+    for (int maxRowCount : Arrays.asList(-1, 0, 1, Integer.MAX_VALUE)) {
+      Service.FetchRequest fetchReq = new Service.FetchRequest(connectionId, statementId,
+          offset, maxRowCount);
+
+      Requests.FetchRequest fetchProtoReq = fetchReq.serialize();
+      assertEquals(maxRowCount, fetchProtoReq.getFetchMaxRowCount());
+      assertEquals(maxRowCount, fetchProtoReq.getFrameMaxSize());
+
+      assertEquals(fetchReq, fetchReq.deserialize(fetchProtoReq));
+    }
+  }
+
+  @Test public void testFetchRequestDeserialization() throws Exception {
+    final String connectionId = UUID.randomUUID().toString();
+    final int statementId = 12345;
+    final long offset = 0L;
+    final int maxSize = 200;
+
+    // The "current" serialization strategy.
+    Requests.FetchRequest protoFetch = Requests.FetchRequest.newBuilder().
+        setConnectionId(connectionId).setStatementId(statementId).
+        setOffset(offset).setFrameMaxSize(maxSize).build();
+
+    Service.FetchRequest fetchReq = new Service.FetchRequest().deserialize(protoFetch);
+    assertEquals(maxSize, fetchReq.fetchMaxRowCount);
+
+    // The "old" serialization strategy.
+    protoFetch = Requests.FetchRequest.newBuilder().
+        setConnectionId(connectionId).setStatementId(statementId).
+        setOffset(offset).setFetchMaxRowCount(maxSize).build();
+
+    fetchReq = new Service.FetchRequest().deserialize(protoFetch);
+    assertEquals(maxSize, fetchReq.fetchMaxRowCount);
+
+    // Both the new and old provided should default to the new
+    protoFetch = Requests.FetchRequest.newBuilder().
+        setConnectionId(connectionId).setStatementId(statementId).
+        setOffset(offset).setFetchMaxRowCount(100).setFrameMaxSize(maxSize).build();
+
+    fetchReq = new Service.FetchRequest().deserialize(protoFetch);
+    assertEquals(maxSize, fetchReq.fetchMaxRowCount);
+  }
 }
 
 // End ProtobufSerializationTest.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/987a257a/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 d2da076..9dac3fb 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
@@ -81,7 +81,7 @@ public class JdbcMeta implements ProtobufMeta {
    *
    * <p>Any other negative value will return an unlimited number of rows but
    * will do it in the default batch size, namely 100. */
-  public static final long UNLIMITED_COUNT = -2L;
+  public static final int UNLIMITED_COUNT = -2;
 
   // End of constants, start of member variables
 
@@ -698,6 +698,11 @@ public class JdbcMeta implements ProtobufMeta {
 
   public ExecuteResult prepareAndExecute(StatementHandle h, String sql,
       long maxRowCount, PrepareCallback callback) throws NoSuchStatementException {
+    return prepareAndExecute(h, sql, maxRowCount, (int) maxRowCount, callback);
+  }
+
+  public ExecuteResult prepareAndExecute(StatementHandle h, String sql, long maxRowCount,
+      int maxRowsInFirstFrame, PrepareCallback callback) throws NoSuchStatementException {
     try {
       final StatementInfo info = statementCache.getIfPresent(h.id);
       if (info == null) {
@@ -722,7 +727,7 @@ public class JdbcMeta implements ProtobufMeta {
                 AvaticaUtils.getLargeUpdateCount(statement)));
       } else {
         resultSets.add(
-            JdbcResultSet.create(h.connectionId, h.id, info.getResultSet(), maxRowCount));
+            JdbcResultSet.create(h.connectionId, h.id, info.getResultSet(), maxRowsInFirstFrame));
       }
       LOG.trace("prepAndExec statement {}", h);
       // TODO: review client to ensure statementId is updated when appropriate
@@ -788,8 +793,13 @@ public class JdbcMeta implements ProtobufMeta {
     return typeList.toArray(new String[typeList.size()]);
   }
 
+  @Override public ExecuteResult execute(StatementHandle h, List<TypedValue> parameterValues,
+      long maxRowCount) throws NoSuchStatementException {
+    return execute(h, parameterValues, (int) maxRowCount);
+  }
+
   @Override public ExecuteResult execute(StatementHandle h,
-      List<TypedValue> parameterValues, long maxRowCount) throws NoSuchStatementException {
+      List<TypedValue> parameterValues, int maxRowsInFirstFrame) throws NoSuchStatementException {
     try {
       if (MetaImpl.checkParameterValueHasNull(parameterValues)) {
         throw new SQLException("exception while executing query: unbound parameter");
@@ -832,7 +842,7 @@ public class JdbcMeta implements ProtobufMeta {
         } else {
           resultSets = Collections.<MetaResultSet>singletonList(
               JdbcResultSet.create(h.connectionId, h.id, statementInfo.getResultSet(),
-                  maxRowCount, signature2));
+                  maxRowsInFirstFrame, signature2));
         }
       } else {
         resultSets = Collections.<MetaResultSet>singletonList(

http://git-wip-us.apache.org/repos/asf/calcite/blob/987a257a/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 6630124..5383289 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
@@ -65,7 +65,7 @@ class JdbcResultSet extends Meta.MetaResultSet {
    * negative value (typically -1) returns an unlimited number of rows
    * in frames of the default frame size. */
   public static JdbcResultSet create(String connectionId, int statementId,
-      ResultSet resultSet, long maxRowCount) {
+      ResultSet resultSet, int maxRowCount) {
     try {
       Meta.Signature sig = JdbcMeta.signature(resultSet.getMetaData());
       return create(connectionId, statementId, resultSet, maxRowCount, sig);
@@ -75,7 +75,7 @@ class JdbcResultSet extends Meta.MetaResultSet {
   }
 
   public static JdbcResultSet create(String connectionId, int statementId,
-      ResultSet resultSet, long maxRowCount, Meta.Signature signature) {
+      ResultSet resultSet, int maxRowCount, Meta.Signature signature) {
     try {
       final Calendar calendar = Calendar.getInstance(DateTimeUtils.GMT_ZONE);
       final int fetchRowCount;
@@ -86,7 +86,7 @@ class JdbcResultSet extends Meta.MetaResultSet {
       } else if (maxRowCount > AvaticaStatement.DEFAULT_FETCH_SIZE) {
         fetchRowCount = AvaticaStatement.DEFAULT_FETCH_SIZE;
       } else {
-        fetchRowCount = (int) maxRowCount;
+        fetchRowCount = maxRowCount;
       }
       final Meta.Frame firstFrame = frame(null, resultSet, 0, fetchRowCount, calendar);
       if (firstFrame.done) {

http://git-wip-us.apache.org/repos/asf/calcite/blob/987a257a/avatica/site/_docs/protobuf_reference.md
----------------------------------------------------------------------
diff --git a/avatica/site/_docs/protobuf_reference.md b/avatica/site/_docs/protobuf_reference.md
index ef910f1..31d31e0 100644
--- a/avatica/site/_docs/protobuf_reference.md
+++ b/avatica/site/_docs/protobuf_reference.md
@@ -264,7 +264,7 @@ This request is used to execute a PreparedStatement, optionally with values to b
 message ExecuteRequest {
   StatementHandle statementHandle = 1;
   repeated TypedValue parameter_values = 2;
-  uint64 max_row_count = 3;
+  uint64 first_frame_max_size = 3;
   bool has_parameter_values = 4;
 }
 {% endhighlight %}
@@ -273,7 +273,7 @@ message ExecuteRequest {
 
 `parameter_values` The <a href="#typedvalue">TypedValue</a> for each parameter on the prepared statement.
 
-`max_row_count` The maximum number of rows returned in the response.
+`first_frame_max_size` The maximum number of rows returned in the response.
 
 `has_parameter_values` A boolean which denotes if the user set a value for the `parameter_values` field.
 
@@ -286,7 +286,8 @@ message FetchRequest {
   string connection_id = 1;
   uint32 statement_id = 2;
   uint64 offset = 3;
-  uint32 fetch_max_row_count = 4; // Maximum number of rows to be returned in the frame. Negative means no limit.
+  uint32 fetch_max_row_count = 4; // Deprecated!
+  int32 frame_max_size = 5;
 }
 {% endhighlight %}
 
@@ -296,7 +297,9 @@ message FetchRequest {
 
 `offset` The positional offset into a result set to fetch.
 
-`fetch_match_row_count` The maximum number of rows to return in the response to this request.
+`fetch_match_row_count` The maximum number of rows to return in the response to this request. Negative means no limit. *Deprecated*, use `frame_max_size`.
+
+`frame_max_size` The maximum number of rows to return in the response. Negative means no limit.
 
 ### OpenConnectionRequest
 
@@ -340,7 +343,9 @@ message PrepareAndExecuteRequest {
   string connection_id = 1;
   uint32 statement_id = 4;
   string sql = 2;
-  uint64 max_row_count = 3;
+  uint64 max_row_count = 3; // Deprecated!
+  int64 max_rows_total = 5;
+  int32 max_rows_in_first_frame = 6;
 }
 {% endhighlight %}
 
@@ -350,7 +355,11 @@ message PrepareAndExecuteRequest {
 
 `sql` A SQL statement
 
-`max_row_count` The maximum number of rows returned in the response.
+`max_row_count` The maximum number of rows returned in the response. *Deprecated*, use `max_rows_total`.
+
+`max_rows_total` The maximum number of rows which this query should return (over all `Frame`s).
+
+`first_frame_max_size` The maximum number of rows which should be included in the first `Frame` in the `ExecuteResponse`.
 
 ### PrepareRequest
 
@@ -360,7 +369,8 @@ This request is used to create create a new Statement with the given query in th
 message PrepareRequest {
   string connection_id = 1;
   string sql = 2;
-  uint64 max_row_count = 3;
+  uint64 max_row_count = 3; // Deprecated!
+  int64 max_rows_total = 4;
 }
 {% endhighlight %}
 
@@ -368,7 +378,9 @@ message PrepareRequest {
 
 `sql` A SQL statement
 
-`max_row_count` The maximum number of rows returned in the response.
+`max_row_count` The maximum number of rows returned in the response. *Deprecated*, use `max_rows_total` instead.
+
+`max_rows_total` The maximum number of rows returned for the query in total.
 
 ### SyncResultsRequest