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 2017/07/18 17:10:41 UTC

[1/4] calcite git commit: [CALCITE-1883] HepPlanner should force garbage collect whenever a root registered (Ted Xu)

Repository: calcite
Updated Branches:
  refs/heads/master 93a96ddf4 -> bdb953fa0


[CALCITE-1883] HepPlanner should force garbage collect whenever a root registered (Ted Xu)

Close apache/calcite#497


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

Branch: refs/heads/master
Commit: eb911cb5756f2ddb4ce643b7e462702b967ca462
Parents: cbbe627
Author: Ted Xu <fr...@gmail.com>
Authored: Tue Jul 18 09:10:55 2017 +0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Mon Jul 17 22:03:16 2017 -0700

----------------------------------------------------------------------
 .../org/apache/calcite/plan/hep/HepPlanner.java    |  1 +
 .../org/apache/calcite/test/HepPlannerTest.java    | 17 +++++++++++++++++
 2 files changed, 18 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/eb911cb5/core/src/main/java/org/apache/calcite/plan/hep/HepPlanner.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/hep/HepPlanner.java b/core/src/main/java/org/apache/calcite/plan/hep/HepPlanner.java
index 1753305..33e4056 100644
--- a/core/src/main/java/org/apache/calcite/plan/hep/HepPlanner.java
+++ b/core/src/main/java/org/apache/calcite/plan/hep/HepPlanner.java
@@ -783,6 +783,7 @@ public class HepPlanner extends AbstractRelOptPlanner {
       graph.addEdge(newVertex, (HepRelVertex) input);
     }
 
+    nTransformations++;
     return newVertex;
   }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/eb911cb5/core/src/test/java/org/apache/calcite/test/HepPlannerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/HepPlannerTest.java b/core/src/test/java/org/apache/calcite/test/HepPlannerTest.java
index ac8f67a..3145db5 100644
--- a/core/src/test/java/org/apache/calcite/test/HepPlannerTest.java
+++ b/core/src/test/java/org/apache/calcite/test/HepPlannerTest.java
@@ -169,6 +169,23 @@ public class HepPlannerTest extends RelOptTestBase {
         programBuilder.build(),
         "select upper(name) from dept where deptno=20");
   }
+
+  @Test public void testGC() throws Exception {
+    HepProgramBuilder programBuilder = HepProgram.builder();
+    programBuilder.addMatchOrder(HepMatchOrder.TOP_DOWN);
+    programBuilder.addRuleInstance(CalcMergeRule.INSTANCE);
+    programBuilder.addRuleInstance(ProjectToCalcRule.INSTANCE);
+    programBuilder.addRuleInstance(FilterToCalcRule.INSTANCE);
+
+    HepPlanner planner = new HepPlanner(programBuilder.build());
+    planner.setRoot(
+        tester.convertSqlToRel("select upper(name) from dept where deptno=20").rel);
+    planner.findBestExp();
+    // Reuse of HepPlanner (should trigger GC).
+    planner.setRoot(
+        tester.convertSqlToRel("select upper(name) from dept where deptno=20").rel);
+    planner.findBestExp();
+  }
 }
 
 // End HepPlannerTest.java


[2/4] calcite git commit: Following [CALCITE-1803], clean up the flow control logic (Junxian Wu)

Posted by jh...@apache.org.
Following [CALCITE-1803], clean up the flow control logic (Junxian Wu)

Close apache/calcite#499


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

Branch: refs/heads/master
Commit: cbbe627feac1293796f68ff8ec8d4bd7b64724d2
Parents: 93a96dd
Author: Junxian Wu <ru...@yahoo-inc.com>
Authored: Mon Jul 17 17:44:58 2017 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Mon Jul 17 22:03:16 2017 -0700

----------------------------------------------------------------------
 .../adapter/druid/DruidConnectionImpl.java      | 29 ++++++++++----------
 1 file changed, 15 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/cbbe627f/druid/src/main/java/org/apache/calcite/adapter/druid/DruidConnectionImpl.java
----------------------------------------------------------------------
diff --git a/druid/src/main/java/org/apache/calcite/adapter/druid/DruidConnectionImpl.java b/druid/src/main/java/org/apache/calcite/adapter/druid/DruidConnectionImpl.java
index fe11e0a..191ec47 100644
--- a/druid/src/main/java/org/apache/calcite/adapter/druid/DruidConnectionImpl.java
+++ b/druid/src/main/java/org/apache/calcite/adapter/druid/DruidConnectionImpl.java
@@ -338,7 +338,7 @@ class DruidConnectionImpl implements DruidConnection {
       break;
     case VALUE_STRING:
     default:
-      String s = parser.getText();
+      final String s = parser.getText();
       if (type != null) {
         switch (type) {
         case LONG:
@@ -347,32 +347,33 @@ class DruidConnectionImpl implements DruidConnection {
         case PRIMITIVE_SHORT:
         case INTEGER:
         case PRIMITIVE_INT:
-          if (s.equals("Infinity") || s.equals("-Infinity") || s.equals("NaN")) {
+          switch (s) {
+          case "Infinity":
+          case "-Infinity":
+          case "NaN":
             throw new RuntimeException("/ by zero");
           }
+          break;
         case FLOAT:
         case PRIMITIVE_FLOAT:
         case PRIMITIVE_DOUBLE:
         case NUMBER:
         case DOUBLE:
-          if (s.equals("Infinity")) {
+          switch (s) {
+          case "Infinity":
             rowBuilder.set(i, Double.POSITIVE_INFINITY);
-            break;
-          } else if (s.equals("-Infinity")) {
+            return;
+          case "-Infinity":
             rowBuilder.set(i, Double.NEGATIVE_INFINITY);
-            break;
-          } else if (s.equals("NaN")) {
+            return;
+          case "NaN":
             rowBuilder.set(i, Double.NaN);
-            break;
+            return;
           }
-          //fallthrough
-        default:
-          rowBuilder.set(i, s);
-          break;
         }
-      } else {
-        rowBuilder.set(i, s);
       }
+      rowBuilder.set(i, s);
+      break;
     }
   }
 


[3/4] calcite git commit: [CALCITE-1893] Add MYSQL_5 conformance

Posted by jh...@apache.org.
[CALCITE-1893] Add MYSQL_5 conformance


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

Branch: refs/heads/master
Commit: 7ef986e28458637a7e5aa89cf4378c9e9cca04be
Parents: eb911cb
Author: Julian Hyde <jh...@apache.org>
Authored: Mon Jul 17 13:34:03 2017 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Mon Jul 17 22:03:17 2017 -0700

----------------------------------------------------------------------
 .../calcite/sql/validate/SqlConformance.java      | 18 ++++++++++++++----
 .../calcite/sql/validate/SqlConformanceEnum.java  | 11 +++++++++++
 2 files changed, 25 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/7ef986e2/core/src/main/java/org/apache/calcite/sql/validate/SqlConformance.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlConformance.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlConformance.java
index 835b763..91238d3 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlConformance.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlConformance.java
@@ -66,7 +66,8 @@ public interface SqlConformance {
    * column names in the {@code GROUP BY} clause.
    *
    * <p>Among the built-in conformance levels, true in
-   * {@link SqlConformanceEnum#LENIENT};
+   * {@link SqlConformanceEnum#LENIENT},
+   * {@link SqlConformanceEnum#MYSQL_5};
    * false otherwise.
    */
   boolean isGroupByAlias();
@@ -76,7 +77,8 @@ public interface SqlConformance {
    * in the select list'.
    *
    * <p>Among the built-in conformance levels, true in
-   * {@link SqlConformanceEnum#LENIENT};
+   * {@link SqlConformanceEnum#LENIENT},
+   * {@link SqlConformanceEnum#MYSQL_5};
    * false otherwise.
    */
   boolean isGroupByOrdinal();
@@ -86,7 +88,8 @@ public interface SqlConformance {
    * column names in the {@code HAVING} clause.
    *
    * <p>Among the built-in conformance levels, true in
-   * {@link SqlConformanceEnum#LENIENT};
+   * {@link SqlConformanceEnum#LENIENT},
+   * {@link SqlConformanceEnum#MYSQL_5};
    * false otherwise.
    */
   boolean isHavingAlias();
@@ -98,6 +101,7 @@ public interface SqlConformance {
    * <p>Among the built-in conformance levels, true in
    * {@link SqlConformanceEnum#DEFAULT},
    * {@link SqlConformanceEnum#LENIENT},
+   * {@link SqlConformanceEnum#MYSQL_5},
    * {@link SqlConformanceEnum#ORACLE_10},
    * {@link SqlConformanceEnum#ORACLE_12},
    * {@link SqlConformanceEnum#STRICT_92},
@@ -115,6 +119,7 @@ public interface SqlConformance {
    * <p>Among the built-in conformance levels, true in
    * {@link SqlConformanceEnum#DEFAULT},
    * {@link SqlConformanceEnum#LENIENT},
+   * {@link SqlConformanceEnum#MYSQL_5},
    * {@link SqlConformanceEnum#ORACLE_10},
    * {@link SqlConformanceEnum#ORACLE_12},
    * {@link SqlConformanceEnum#STRICT_92};
@@ -152,6 +157,7 @@ public interface SqlConformance {
    *
    * <p>Among the built-in conformance levels, true in
    * {@link SqlConformanceEnum#LENIENT},
+   * {@link SqlConformanceEnum#MYSQL_5},
    * {@link SqlConformanceEnum#ORACLE_10};
    * {@link SqlConformanceEnum#ORACLE_12};
    * false otherwise.
@@ -167,6 +173,9 @@ public interface SqlConformance {
    * {@link SqlConformanceEnum#ORACLE_10};
    * {@link SqlConformanceEnum#ORACLE_12};
    * false otherwise.
+   *
+   * <p>Note: MySQL does not support {@code MINUS} or {@code EXCEPT} (as of
+   * version 5.5).
    */
   boolean isMinusAllowed();
 
@@ -234,7 +243,8 @@ public interface SqlConformance {
    * not.
    *
    * <p>Among the built-in conformance levels, true in
-   * {@link SqlConformanceEnum#LENIENT};
+   * {@link SqlConformanceEnum#LENIENT},
+   * {@link SqlConformanceEnum#MYSQL_5};
    * false otherwise.
    */
   boolean allowNiladicParentheses();

http://git-wip-us.apache.org/repos/asf/calcite/blob/7ef986e2/core/src/main/java/org/apache/calcite/sql/validate/SqlConformanceEnum.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlConformanceEnum.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlConformanceEnum.java
index b65042e..74d31f1 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlConformanceEnum.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlConformanceEnum.java
@@ -40,6 +40,10 @@ public enum SqlConformanceEnum implements SqlConformance {
   PRAGMATIC_99,
 
   /** Conformance value that instructs Calcite to use SQL semantics
+   * consistent with MySQL version 5.x. */
+  MYSQL_5,
+
+  /** Conformance value that instructs Calcite to use SQL semantics
    * consistent with Oracle version 10. */
   ORACLE_10,
 
@@ -65,6 +69,7 @@ public enum SqlConformanceEnum implements SqlConformance {
   public boolean isGroupByAlias() {
     switch (this) {
     case LENIENT:
+    case MYSQL_5:
       return true;
     default:
       return false;
@@ -74,6 +79,7 @@ public enum SqlConformanceEnum implements SqlConformance {
   public boolean isGroupByOrdinal() {
     switch (this) {
     case LENIENT:
+    case MYSQL_5:
       return true;
     default:
       return false;
@@ -83,6 +89,7 @@ public enum SqlConformanceEnum implements SqlConformance {
   public boolean isHavingAlias() {
     switch (this) {
     case LENIENT:
+    case MYSQL_5:
       return true;
     default:
       return false;
@@ -93,6 +100,7 @@ public enum SqlConformanceEnum implements SqlConformance {
     switch (this) {
     case DEFAULT:
     case LENIENT:
+    case MYSQL_5:
     case ORACLE_10:
     case ORACLE_12:
     case STRICT_92:
@@ -109,6 +117,7 @@ public enum SqlConformanceEnum implements SqlConformance {
     switch (this) {
     case DEFAULT:
     case LENIENT:
+    case MYSQL_5:
     case ORACLE_10:
     case ORACLE_12:
     case STRICT_92:
@@ -139,6 +148,7 @@ public enum SqlConformanceEnum implements SqlConformance {
   public boolean isBangEqualAllowed() {
     switch (this) {
     case LENIENT:
+    case MYSQL_5:
     case ORACLE_10:
     case ORACLE_12:
       return true;
@@ -183,6 +193,7 @@ public enum SqlConformanceEnum implements SqlConformance {
   public boolean allowNiladicParentheses() {
     switch (this) {
     case LENIENT:
+    case MYSQL_5:
       return true;
     default:
       return false;


[4/4] calcite git commit: [CALCITE-1886] Support "LIMIT [offset, ] row_count", per MySQL (Kaiwang Chen)

Posted by jh...@apache.org.
[CALCITE-1886] Support "LIMIT [offset,] row_count", per MySQL (Kaiwang Chen)

Close apache/calcite#498


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

Branch: refs/heads/master
Commit: bdb953fa06d6549039c2967404b0194ab7ae6a8c
Parents: 7ef986e
Author: kaiwang.ckw <ka...@alibaba-inc.com>
Authored: Fri Jul 14 14:58:44 2017 +0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Mon Jul 17 23:05:38 2017 -0700

----------------------------------------------------------------------
 core/src/main/codegen/templates/Parser.jj       | 22 ++++++++-
 .../apache/calcite/runtime/CalciteResource.java |  3 ++
 .../sql/validate/SqlAbstractConformance.java    |  4 ++
 .../calcite/sql/validate/SqlConformance.java    | 16 +++++++
 .../sql/validate/SqlConformanceEnum.java        | 10 ++++
 .../calcite/runtime/CalciteResource.properties  |  1 +
 .../calcite/sql/parser/SqlParserTest.java       | 48 ++++++++++++++++++++
 site/_docs/reference.md                         |  6 ++-
 8 files changed, 108 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/bdb953fa/core/src/main/codegen/templates/Parser.jj
----------------------------------------------------------------------
diff --git a/core/src/main/codegen/templates/Parser.jj b/core/src/main/codegen/templates/Parser.jj
index 67d1a1b..a2789d0 100644
--- a/core/src/main/codegen/templates/Parser.jj
+++ b/core/src/main/codegen/templates/Parser.jj
@@ -575,6 +575,12 @@ JAVACODE boolean matchesPrefix(int[] seq, int[][] prefixes)
  *    [ OFFSET start ]</pre>
  * </blockquote>
  *
+ * <p>MySQL syntax for limit:
+ *
+ * <blockquote><pre>
+ *    [ LIMIT { count | start, count } ]</pre>
+ * </blockquote>
+ *
  * <p>SQL:2008 syntax for limit:
  *
  * <blockquote><pre>
@@ -600,11 +606,25 @@ SqlNode OrderedQueryOrExpr(ExprContext exprContext) :
     ]
     [
         // Postgres-style syntax. "LIMIT ... OFFSET ..."
-        <LIMIT> ( count = UnsignedNumericLiteral() | <ALL> )
+        <LIMIT>
+        (
+            // MySQL-style syntax. "LIMIT start, count"
+            start = UnsignedNumericLiteral()
+            <COMMA> count = UnsignedNumericLiteral() {
+                if (!this.conformance.isLimitStartCountAllowed()) {
+                    throw new ParseException(RESOURCE.limitStartCountNotAllowed().str());
+                }
+            }
+        |
+            count = UnsignedNumericLiteral()
+        |
+            <ALL>
+        )
     ]
     [
         // ROW or ROWS is required in SQL:2008 but we make it optional
         // because it is not present in Postgres-style syntax.
+        // If you specify both LIMIT start and OFFSET, OFFSET wins.
         <OFFSET> start = UnsignedNumericLiteral() [ <ROW> | <ROWS> ]
     ]
     [

http://git-wip-us.apache.org/repos/asf/calcite/blob/bdb953fa/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java b/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java
index f79fa36..84f21e1 100644
--- a/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java
+++ b/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java
@@ -34,6 +34,9 @@ public interface CalciteResource {
   @BaseMessage("Bang equal ''!='' is not allowed under the current SQL conformance level")
   ExInst<CalciteException> bangEqualNotAllowed();
 
+  @BaseMessage("''LIMIT start, count'' is not allowed under the current SQL conformance level")
+  ExInst<CalciteException> limitStartCountNotAllowed();
+
   @BaseMessage("APPLY operator is not allowed under the current SQL conformance level")
   ExInst<CalciteException> applyNotAllowed();
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/bdb953fa/core/src/main/java/org/apache/calcite/sql/validate/SqlAbstractConformance.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlAbstractConformance.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlAbstractConformance.java
index 78f2df3..4cd8bb8 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlAbstractConformance.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlAbstractConformance.java
@@ -74,6 +74,10 @@ public abstract class SqlAbstractConformance implements SqlConformance {
   public boolean allowExtend() {
     return SqlConformanceEnum.DEFAULT.allowExtend();
   }
+
+  public boolean isLimitStartCountAllowed() {
+    return SqlConformanceEnum.DEFAULT.isLimitStartCountAllowed();
+  }
 }
 
 // End SqlAbstractConformance.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/bdb953fa/core/src/main/java/org/apache/calcite/sql/validate/SqlConformance.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlConformance.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlConformance.java
index 91238d3..9f8e3c0 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlConformance.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlConformance.java
@@ -269,6 +269,22 @@ public interface SqlConformance {
    */
   boolean allowExtend();
 
+  /**
+   * Whether to allow the SQL syntax "{@code LIMIT start, count}".
+   *
+   * <p>The equivalent syntax in standard SQL is
+   * "{@code OFFSET start ROW FETCH FIRST count ROWS ONLY}",
+   * and in PostgreSQL "{@code LIMIT count OFFSET start}".
+   *
+   * <p>MySQL and CUBRID allow this behavior.
+   *
+   * <p>Among the built-in conformance levels, true in
+   * {@link SqlConformanceEnum#LENIENT},
+   * {@link SqlConformanceEnum#MYSQL_5};
+   * false otherwise.
+   */
+
+  boolean isLimitStartCountAllowed();
 }
 
 // End SqlConformance.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/bdb953fa/core/src/main/java/org/apache/calcite/sql/validate/SqlConformanceEnum.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlConformanceEnum.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlConformanceEnum.java
index 74d31f1..754e24e 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlConformanceEnum.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlConformanceEnum.java
@@ -208,6 +208,16 @@ public enum SqlConformanceEnum implements SqlConformance {
       return false;
     }
   }
+
+  public boolean isLimitStartCountAllowed() {
+    switch (this) {
+    case LENIENT:
+    case MYSQL_5:
+      return true;
+    default:
+      return false;
+    }
+  }
 }
 
 // End SqlConformanceEnum.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/bdb953fa/core/src/main/resources/org/apache/calcite/runtime/CalciteResource.properties
----------------------------------------------------------------------
diff --git a/core/src/main/resources/org/apache/calcite/runtime/CalciteResource.properties b/core/src/main/resources/org/apache/calcite/runtime/CalciteResource.properties
index 8451ed3..360fb6e 100644
--- a/core/src/main/resources/org/apache/calcite/runtime/CalciteResource.properties
+++ b/core/src/main/resources/org/apache/calcite/runtime/CalciteResource.properties
@@ -18,6 +18,7 @@
 #
 ParserContext=line {0,number,#}, column {1,number,#}
 BangEqualNotAllowed=Bang equal ''!='' is not allowed under the current SQL conformance level
+LimitStartCountNotAllowed=''LIMIT start, count'' is not allowed under the current SQL conformance level
 ApplyNotAllowed=APPLY operator is not allowed under the current SQL conformance level
 IllegalLiteral=Illegal {0} literal {1}: {2}
 IdentifierTooLong=Length of identifier ''{0}'' must be less than or equal to {1,number,#} characters

http://git-wip-us.apache.org/repos/asf/calcite/blob/bdb953fa/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java b/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java
index e70e291..b9db101 100644
--- a/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java
+++ b/core/src/test/java/org/apache/calcite/sql/parser/SqlParserTest.java
@@ -2531,6 +2531,54 @@ public class SqlParserTest {
         .ok(expected);
   }
 
+  @Test public void testLimitStartCount() {
+    conformance = SqlConformanceEnum.DEFAULT;
+    final String error = "'LIMIT start, count' is not allowed under the "
+        + "current SQL conformance level";
+    sql("select a from foo limit 1,2")
+        .fails(error);
+
+    // "limit all" is equivalent to no limit
+    final String expected0 = "SELECT `A`\n"
+        + "FROM `FOO`";
+    sql("select a from foo limit all")
+        .ok(expected0);
+
+    final String expected1 = "SELECT `A`\n"
+        + "FROM `FOO`\n"
+        + "ORDER BY `X`";
+    sql("select a from foo order by x limit all")
+        .ok(expected1);
+
+    conformance = SqlConformanceEnum.LENIENT;
+    final String expected2 = "SELECT `A`\n"
+        + "FROM `FOO`\n"
+        + "OFFSET 2 ROWS\n"
+        + "FETCH NEXT 3 ROWS ONLY";
+    sql("select a from foo limit 2,3")
+        .ok(expected2);
+
+    // "offset 4" overrides the earlier "2"
+    final String expected3 = "SELECT `A`\n"
+        + "FROM `FOO`\n"
+        + "OFFSET 4 ROWS\n"
+        + "FETCH NEXT 3 ROWS ONLY";
+    sql("select a from foo limit 2,3 offset 4")
+        .ok(expected3);
+
+    // "fetch next 4" overrides the earlier "limit 3"
+    final String expected4 = "SELECT `A`\n"
+        + "FROM `FOO`\n"
+        + "OFFSET 2 ROWS\n"
+        + "FETCH NEXT 4 ROWS ONLY";
+    sql("select a from foo limit 2,3 fetch next 4 rows only")
+        .ok(expected4);
+
+    // "limit start, all" is not valid
+    sql("select a from foo limit 2, ^all^")
+        .fails("(?s).*Encountered \"all\" at line 1.*");
+  }
+
   @Test public void testSqlInlineComment() {
     check(
         "select 1 from t --this is a comment\n",

http://git-wip-us.apache.org/repos/asf/calcite/blob/bdb953fa/site/_docs/reference.md
----------------------------------------------------------------------
diff --git a/site/_docs/reference.md b/site/_docs/reference.md
index 4756468..9fe6876 100644
--- a/site/_docs/reference.md
+++ b/site/_docs/reference.md
@@ -153,7 +153,7 @@ query:
       |   query INTERSECT [ ALL | DISTINCT ] query
       }
       [ ORDER BY orderItem [, orderItem ]* ]
-      [ LIMIT { count | ALL } ]
+      [ LIMIT [ start, ] { count | ALL } ]
       [ OFFSET start { ROW | ROWS } ]
       [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ]
 
@@ -283,6 +283,10 @@ but is not standard SQL and is only allowed in certain
 CROSS APPLY and OUTER APPLY are only allowed in certain
 [conformance levels]({{ site.apiRoot }}/org/apache/calcite/sql/validate/SqlConformance.html#isApplyAllowed--).
 
+"LIMIT start, count" is equivalent to "LIMIT count OFFSET start"
+but is only allowed in certain
+[conformance levels]({{ site.apiRoot }}/org/apache/calcite/sql/validate/SqlConformance.html#isLimitStartCountAllowed--).
+
 ## Keywords
 
 The following is a list of SQL keywords.