calcite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From maryann...@apache.org
Subject calcite git commit: [CALCITE-1374] Support operator "!=" as an alternative to "<>"
Date Mon, 26 Sep 2016 20:47:53 GMT
Repository: calcite
Updated Branches:
  refs/heads/master 349c7dceb -> c5bd9d212


[CALCITE-1374] Support operator "!=" as an alternative to "<>"


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

Branch: refs/heads/master
Commit: c5bd9d21287790e1cb9defa7350098bd51e1d805
Parents: 349c7dc
Author: maryannxue <maryann.xue@gmail.com>
Authored: Mon Sep 26 13:47:36 2016 -0700
Committer: maryannxue <maryann.xue@gmail.com>
Committed: Mon Sep 26 13:47:36 2016 -0700

----------------------------------------------------------------------
 core/src/main/codegen/templates/Parser.jj       | 15 ++++++++++++
 .../calcite/prepare/CalcitePrepareImpl.java     |  3 ++-
 .../apache/calcite/runtime/CalciteResource.java |  3 +++
 .../sql/parser/SqlAbstractParserImpl.java       |  5 ++++
 .../apache/calcite/sql/parser/SqlParser.java    | 22 ++++++++++++++---
 .../calcite/sql/validate/SqlConformance.java    | 16 +++++++++++++
 .../calcite/runtime/CalciteResource.properties  |  1 +
 .../calcite/sql/parser/SqlParserTest.java       |  5 ++--
 .../calcite/sql/test/DefaultSqlTestFactory.java |  1 +
 .../apache/calcite/sql/test/SqlAdvisorTest.java |  1 +
 .../calcite/sql/test/SqlOperatorBaseTest.java   | 25 +++++++++++++++-----
 site/_docs/reference.md                         |  3 ++-
 12 files changed, 87 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/c5bd9d21/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 2d97cf3..2869e97 100644
--- a/core/src/main/codegen/templates/Parser.jj
+++ b/core/src/main/codegen/templates/Parser.jj
@@ -134,6 +134,7 @@ public class ${parser.class} extends SqlAbstractParserImpl
     private Casing unquotedCasing;
     private Casing quotedCasing;
     private int identifierMaxLength;
+    private boolean allowBangEqual;
 
     /**
      * {@link SqlParserImplFactory} implementation for creating parser.
@@ -202,6 +203,12 @@ public class ${parser.class} extends SqlAbstractParserImpl
     }
 
     // implement SqlAbstractParserImpl
+    public void setAllowBangEqual(boolean allowBangEqual)
+    {
+        this.allowBangEqual = allowBangEqual;
+    }
+
+    // implement SqlAbstractParserImpl
     public SqlNode parseSqlExpressionEof() throws Exception
     {
         return SqlExpressionEof();
@@ -4728,6 +4735,13 @@ SqlBinaryOperator BinaryRowOperator() :
     { return SqlStdOperatorTable.GREATER_THAN_OR_EQUAL; }
     | <NE>
     { return SqlStdOperatorTable.NOT_EQUALS; }
+    | <NE2>
+    {
+        if (!this.allowBangEqual) {
+            throw new ParseException(RESOURCE.bangEqualNotAllowed().str());
+        }
+        return SqlStdOperatorTable.NOT_EQUALS;
+    }
     | <PLUS>
     { return SqlStdOperatorTable.PLUS; }
     | <MINUS>
@@ -5712,6 +5726,7 @@ String CommonNonReservedKeyWord() :
     | < LE: "<=" >
     | < GE: ">=" >
     | < NE: "<>" >
+    | < NE2: "!=" >
     | < PLUS: "+" >
     | < MINUS: "-" >
     | < STAR: "*" >

http://git-wip-us.apache.org/repos/asf/calcite/blob/c5bd9d21/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java b/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
index 169634b..c0567ce 100644
--- a/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
+++ b/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
@@ -697,7 +697,8 @@ public class CalcitePrepareImpl implements CalcitePrepare {
           createParserConfig()
               .setQuotedCasing(config.quotedCasing())
               .setUnquotedCasing(config.unquotedCasing())
-              .setQuoting(config.quoting()));
+              .setQuoting(config.quoting())
+              .setAllowBangEqual(config.conformance().isBangEqualAllowed()));
       SqlNode sqlNode;
       try {
         sqlNode = parser.parseStmt();

http://git-wip-us.apache.org/repos/asf/calcite/blob/c5bd9d21/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 f261659..f9cdf50 100644
--- a/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java
+++ b/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java
@@ -31,6 +31,9 @@ public interface CalciteResource {
   @BaseMessage("line {0,number,#}, column {1,number,#}")
   Inst parserContext(int a0, int a1);
 
+  @BaseMessage("Bang equal ''!='' is not allowed under the current SQL conformance level")
+  ExInst<CalciteException> bangEqualNotAllowed();
+
   @BaseMessage("Illegal {0} literal {1}: {2}")
   ExInst<CalciteException> illegalLiteral(String a0, String a1, String a2);
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/c5bd9d21/core/src/main/java/org/apache/calcite/sql/parser/SqlAbstractParserImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/parser/SqlAbstractParserImpl.java b/core/src/main/java/org/apache/calcite/sql/parser/SqlAbstractParserImpl.java
index 2e0008d..c7cef03 100644
--- a/core/src/main/java/org/apache/calcite/sql/parser/SqlAbstractParserImpl.java
+++ b/core/src/main/java/org/apache/calcite/sql/parser/SqlAbstractParserImpl.java
@@ -444,6 +444,11 @@ public abstract class SqlAbstractParserImpl {
   public abstract void setIdentifierMaxLength(int identifierMaxLength);
 
   /**
+   * Sets whether the bang-equal token != is allowed as an alternative to &lt;&gt;.
+   */
+  public abstract void setAllowBangEqual(boolean allowBangEqual);
+
+  /**
    * Sets the SQL text that is being parsed.
    */
   public void setOriginalSql(String originalSql) {

http://git-wip-us.apache.org/repos/asf/calcite/blob/c5bd9d21/core/src/main/java/org/apache/calcite/sql/parser/SqlParser.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/parser/SqlParser.java b/core/src/main/java/org/apache/calcite/sql/parser/SqlParser.java
index e1bda73..a1311a0 100644
--- a/core/src/main/java/org/apache/calcite/sql/parser/SqlParser.java
+++ b/core/src/main/java/org/apache/calcite/sql/parser/SqlParser.java
@@ -32,6 +32,7 @@ import java.io.StringReader;
  */
 public class SqlParser {
   public static final int DEFAULT_IDENTIFIER_MAX_LENGTH = 128;
+  public static final boolean DEFAULT_ALLOW_BANG_EQUAL = false;
 
   //~ Instance fields --------------------------------------------------------
   private final SqlAbstractParserImpl parser;
@@ -47,6 +48,7 @@ public class SqlParser {
     parser.setQuotedCasing(config.quotedCasing());
     parser.setUnquotedCasing(config.unquotedCasing());
     parser.setIdentifierMaxLength(config.identifierMaxLength());
+    parser.setAllowBangEqual(config.allowBangEqual());
     switch (config.quoting()) {
     case DOUBLE_QUOTE:
       parser.switchTo("DQID");
@@ -194,6 +196,7 @@ public class SqlParser {
     Casing unquotedCasing();
     Quoting quoting();
     boolean caseSensitive();
+    boolean allowBangEqual();
     SqlParserImplFactory parserFactory();
   }
 
@@ -204,6 +207,7 @@ public class SqlParser {
     private Quoting quoting = Lex.ORACLE.quoting;
     private int identifierMaxLength = DEFAULT_IDENTIFIER_MAX_LENGTH;
     private boolean caseSensitive = Lex.ORACLE.caseSensitive;
+    private boolean allowBangEqual = DEFAULT_ALLOW_BANG_EQUAL;
     private SqlParserImplFactory parserFactory = SqlParserImpl.FACTORY;
 
     private ConfigBuilder() {}
@@ -214,6 +218,7 @@ public class SqlParser {
       this.unquotedCasing = config.unquotedCasing();
       this.quoting = config.quoting();
       this.identifierMaxLength = config.identifierMaxLength();
+      this.allowBangEqual = config.allowBangEqual();
       this.parserFactory = config.parserFactory();
       return this;
     }
@@ -243,6 +248,11 @@ public class SqlParser {
       return this;
     }
 
+    public ConfigBuilder setAllowBangEqual(boolean allowBangEqual) {
+      this.allowBangEqual = allowBangEqual;
+      return this;
+    }
+
     public ConfigBuilder setParserFactory(SqlParserImplFactory factory) {
       this.parserFactory = Preconditions.checkNotNull(factory);
       return this;
@@ -259,8 +269,8 @@ public class SqlParser {
     /** Builds a
      * {@link Config}. */
     public Config build() {
-      return new ConfigImpl(identifierMaxLength, quotedCasing,
-          unquotedCasing, quoting, caseSensitive, parserFactory);
+      return new ConfigImpl(identifierMaxLength, quotedCasing, unquotedCasing,
+          quoting, caseSensitive, allowBangEqual, parserFactory);
     }
   }
 
@@ -270,6 +280,7 @@ public class SqlParser {
   private static class ConfigImpl implements Config {
     private final int identifierMaxLength;
     private final boolean caseSensitive;
+    private final boolean allowBangEqual;
     private final Casing quotedCasing;
     private final Casing unquotedCasing;
     private final Quoting quoting;
@@ -277,9 +288,10 @@ public class SqlParser {
 
     private ConfigImpl(int identifierMaxLength, Casing quotedCasing,
         Casing unquotedCasing, Quoting quoting, boolean caseSensitive,
-        SqlParserImplFactory parserFactory) {
+        boolean allowBangEqual, SqlParserImplFactory parserFactory) {
       this.identifierMaxLength = identifierMaxLength;
       this.caseSensitive = caseSensitive;
+      this.allowBangEqual = allowBangEqual;
       this.quotedCasing = Preconditions.checkNotNull(quotedCasing);
       this.unquotedCasing = Preconditions.checkNotNull(unquotedCasing);
       this.quoting = Preconditions.checkNotNull(quoting);
@@ -306,6 +318,10 @@ public class SqlParser {
       return caseSensitive;
     }
 
+    public boolean allowBangEqual() {
+      return allowBangEqual;
+    }
+
     public SqlParserImplFactory parserFactory() {
       return parserFactory;
     }

http://git-wip-us.apache.org/repos/asf/calcite/blob/c5bd9d21/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 4dec2cd..2b72499 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
@@ -91,6 +91,22 @@ public enum SqlConformance {
       return false;
     }
   }
+
+  /**
+   * Whether the bang-equal token != is allowed as an alternative to &lt;&gt; in
+   * the parser.
+   *
+   * <p>True in {@link #ORACLE_10};
+   * false otherwise.
+   */
+  public boolean isBangEqualAllowed() {
+    switch (this) {
+    case ORACLE_10:
+      return true;
+    default:
+      return false;
+    }
+  }
 }
 
 // End SqlConformance.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/c5bd9d21/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 729fa13..b21e5a5 100644
--- a/core/src/main/resources/org/apache/calcite/runtime/CalciteResource.properties
+++ b/core/src/main/resources/org/apache/calcite/runtime/CalciteResource.properties
@@ -17,6 +17,7 @@
 # limitations under the License.
 #
 ParserContext=line {0,number,#}, column {1,number,#}
+BangEqualNotAllowed=Bang equal ''!='' 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
 BadFormat=not in format ''{0}''

http://git-wip-us.apache.org/repos/asf/calcite/blob/c5bd9d21/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 a65f797..081bd2a 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
@@ -858,8 +858,9 @@ public class SqlParserTest {
     //   equals' is <> as in BASIC. There are many texts which will tell
     //   you that != is SQL's not-equals operator; those texts are false;
     //   it's one of those unstampoutable urban myths."
-    checkFails("'abc'^!^=123",
-        "Lexical error at line 1, column 6\\.  Encountered: \"!\" \\(33\\), after : \"\"");
+    // Therefore, we only support != with certain SQL conformance levels.
+    checkExpFails("'abc'!=123",
+        "Bang equal '!=' is not allowed under the current SQL conformance level");
   }
 
   @Test public void testBetween() {

http://git-wip-us.apache.org/repos/asf/calcite/blob/c5bd9d21/core/src/test/java/org/apache/calcite/sql/test/DefaultSqlTestFactory.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/sql/test/DefaultSqlTestFactory.java b/core/src/test/java/org/apache/calcite/sql/test/DefaultSqlTestFactory.java
index 4ea62e3..c9ecce6 100644
--- a/core/src/test/java/org/apache/calcite/sql/test/DefaultSqlTestFactory.java
+++ b/core/src/test/java/org/apache/calcite/sql/test/DefaultSqlTestFactory.java
@@ -80,6 +80,7 @@ public class DefaultSqlTestFactory implements SqlTestFactory {
             .setQuoting((Quoting) factory.get("quoting"))
             .setUnquotedCasing((Casing) factory.get("unquotedCasing"))
             .setQuotedCasing((Casing) factory.get("quotedCasing"))
+            .setAllowBangEqual(((SqlConformance) factory.get("conformance")).isBangEqualAllowed())
             .build());
   }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/c5bd9d21/core/src/test/java/org/apache/calcite/sql/test/SqlAdvisorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/sql/test/SqlAdvisorTest.java b/core/src/test/java/org/apache/calcite/sql/test/SqlAdvisorTest.java
index 03200f0..44aa38c 100644
--- a/core/src/test/java/org/apache/calcite/sql/test/SqlAdvisorTest.java
+++ b/core/src/test/java/org/apache/calcite/sql/test/SqlAdvisorTest.java
@@ -232,6 +232,7 @@ public class SqlAdvisorTest extends SqlValidatorTestCase {
           "KEYWORD(<)",
           "KEYWORD(<=)",
           "KEYWORD(<>)",
+          "KEYWORD(!=)",
           "KEYWORD(=)",
           "KEYWORD(>)",
           "KEYWORD(>=)",

http://git-wip-us.apache.org/repos/asf/calcite/blob/c5bd9d21/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java b/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
index 4442cc5..3607e7a 100644
--- a/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
+++ b/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
@@ -42,6 +42,7 @@ import org.apache.calcite.sql.type.SqlOperandTypeChecker;
 import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.calcite.sql.util.ChainedSqlOperatorTable;
 import org.apache.calcite.sql.util.SqlString;
+import org.apache.calcite.sql.validate.SqlConformance;
 import org.apache.calcite.sql.validate.SqlValidatorImpl;
 import org.apache.calcite.sql.validate.SqlValidatorScope;
 import org.apache.calcite.test.CalciteAssert;
@@ -2742,6 +2743,24 @@ public abstract class SqlOperatorBaseTest {
     tester.checkBoolean("'a'<>'A'", Boolean.TRUE);
     tester.checkBoolean("1e0<>1e1", Boolean.TRUE);
     tester.checkNull("'a'<>cast(null as varchar(1))");
+
+    // "!=" is not an acceptable alternative to "<>" under default SQL conformance
level
+    tester.checkFails(
+        "1 != 1",
+        "Bang equal '!=' is not allowed under the current SQL conformance level",
+        false);
+    // "!=" is allowed under ORACLE_10 SQL conformance level
+    final SqlTester tester1 =
+        tester
+            .withConformance(SqlConformance.ORACLE_10)
+            .withConnectionFactory(
+                CalciteAssert.EMPTY_CONNECTION_FACTORY
+                    .with("conformance", SqlConformance.ORACLE_10));
+
+    tester1
+        .checkBoolean("1 <> 1", Boolean.FALSE);
+    tester1
+        .checkBoolean("1 != 1", Boolean.FALSE);
   }
 
   @Test public void testNotEqualsOperatorIntervals() {
@@ -2756,12 +2775,6 @@ public abstract class SqlOperatorBaseTest {
         Boolean.TRUE);
     tester.checkNull(
         "cast(null as interval hour) <> interval '2' minute");
-
-    // "!=" is not an acceptable alternative to "<>"
-    tester.checkFails(
-        "1 ^!^= 1",
-        "(?s).*Encountered: \"!\" \\(33\\).*",
-        false);
   }
 
   @Test public void testOrOperator() {

http://git-wip-us.apache.org/repos/asf/calcite/blob/c5bd9d21/site/_docs/reference.md
----------------------------------------------------------------------
diff --git a/site/_docs/reference.md b/site/_docs/reference.md
index 428ef83..bb4796a 100644
--- a/site/_docs/reference.md
+++ b/site/_docs/reference.md
@@ -843,7 +843,7 @@ The operator precedence and associativity, highest to lowest.
 | * /                                               | left
 | + -                                               | left
 | BETWEEN, IN, LIKE, SIMILAR                        | -
-| < > = <= >= <>                                    | left
+| < > = <= >= <> !=                                 | left
 | IS NULL, IS FALSE, IS NOT TRUE etc.               | -
 | NOT                                               | right
 | AND                                               | left
@@ -855,6 +855,7 @@ The operator precedence and associativity, highest to lowest.
 |:------------------------------------------------- |:-----------
 | value1 = value2                                   | Equals
 | value1 <> value2                                  | Not equal
+| value1 != value2                                  | Not equal (only available at some conformance
levels)
 | value1 > value2                                   | Greater than
 | value1 >= value2                                  | Greater than or equal
 | value1 < value2                                   | Less than


Mime
View raw message