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 2016/10/18 19:04:48 UTC

[3/3] calcite git commit: [CALCITE-1454] Allow custom implementations of SqlConformance

[CALCITE-1454] Allow custom implementations of SqlConformance

SqlParser.Config.allowBangEqual() is now obsolete; use
SqlParser.Config.conformance().isBangEqualAllowed().


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

Branch: refs/heads/master
Commit: 105bba1f83cd9631e8e1211d262e4886a4a863b7
Parents: 54556b8
Author: Julian Hyde <jh...@apache.org>
Authored: Mon Oct 17 21:30:30 2016 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Tue Oct 18 10:25:55 2016 -0700

----------------------------------------------------------------------
 core/src/main/codegen/templates/Parser.jj       |  20 +---
 .../config/CalciteConnectionConfigImpl.java     |   3 +-
 .../config/CalciteConnectionProperty.java       |   4 +-
 .../calcite/jdbc/CalciteConnectionImpl.java     |   4 +-
 .../calcite/prepare/CalcitePrepareImpl.java     |   2 +-
 .../org/apache/calcite/prepare/PlannerImpl.java |   3 +-
 .../sql/parser/SqlAbstractParserImpl.java       |   5 +-
 .../apache/calcite/sql/parser/SqlParser.java    |  50 ++++++--
 .../sql/validate/SqlAbstractConformance.java    |  47 ++++++++
 .../calcite/sql/validate/SqlConformance.java    | 119 ++++++++++---------
 .../sql/validate/SqlConformanceEnum.java        | 102 ++++++++++++++++
 .../sql/validate/SqlDelegatingConformance.java  |  53 +++++++++
 .../calcite/sql/validate/SqlValidator.java      |   2 +-
 .../calcite/sql/validate/SqlValidatorUtil.java  |   2 +-
 .../calcite/sql/test/DefaultSqlTestFactory.java |   5 +-
 .../calcite/sql/test/SqlOperatorBaseTest.java   |   6 +-
 .../apache/calcite/sql/test/SqlTesterImpl.java  |   3 +-
 .../apache/calcite/test/SqlToRelTestBase.java   |   3 +-
 .../apache/calcite/test/SqlValidatorTest.java   |  55 ++++++++-
 19 files changed, 388 insertions(+), 100 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/105bba1f/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 98466b2..6f964f3 100644
--- a/core/src/main/codegen/templates/Parser.jj
+++ b/core/src/main/codegen/templates/Parser.jj
@@ -96,10 +96,10 @@ import org.apache.calcite.sql.parser.SqlParserImplFactory;
 import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.calcite.sql.parser.SqlParserUtil;
 import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.calcite.sql.validate.SqlConformance;
 import org.apache.calcite.util.Util;
 import org.apache.calcite.util.trace.CalciteTrace;
 
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 
 import org.slf4j.Logger;
@@ -135,7 +135,7 @@ public class ${parser.class} extends SqlAbstractParserImpl
     private Casing unquotedCasing;
     private Casing quotedCasing;
     private int identifierMaxLength;
-    private boolean allowBangEqual;
+    private SqlConformance conformance;
 
     /**
      * {@link SqlParserImplFactory} implementation for creating parser.
@@ -146,7 +146,6 @@ public class ${parser.class} extends SqlAbstractParserImpl
         }
     };
 
-    // implement SqlAbstractParserImpl
     public SqlParseException normalizeException(Throwable ex)
     {
         try {
@@ -159,7 +158,6 @@ public class ${parser.class} extends SqlAbstractParserImpl
         }
     }
 
-    // implement SqlAbstractParserImpl
     public Metadata getMetadata()
     {
         synchronized (${parser.class}.class) {
@@ -171,13 +169,11 @@ public class ${parser.class} extends SqlAbstractParserImpl
         }
     }
 
-    // implement SqlAbstractParserImpl
     public void setTabSize(int tabSize)
     {
         jj_input_stream.setTabSize(tabSize);
     }
 
-    // implement SqlAbstractParserImpl
     public void switchTo(String stateName)
     {
         int state = Arrays.asList(${parser.class}TokenManager.lexStateNames)
@@ -185,37 +181,31 @@ public class ${parser.class} extends SqlAbstractParserImpl
         token_source.SwitchTo(state);
     }
 
-    // implement SqlAbstractParserImpl
     public void setQuotedCasing(Casing quotedCasing)
     {
         this.quotedCasing = quotedCasing;
     }
 
-    // implement SqlAbstractParserImpl
     public void setUnquotedCasing(Casing unquotedCasing)
     {
         this.unquotedCasing = unquotedCasing;
     }
 
-    // implement SqlAbstractParserImpl
     public void setIdentifierMaxLength(int identifierMaxLength)
     {
         this.identifierMaxLength = identifierMaxLength;
     }
 
-    // implement SqlAbstractParserImpl
-    public void setAllowBangEqual(boolean allowBangEqual)
+    public void setConformance(SqlConformance conformance)
     {
-        this.allowBangEqual = allowBangEqual;
+        this.conformance = conformance;
     }
 
-    // implement SqlAbstractParserImpl
     public SqlNode parseSqlExpressionEof() throws Exception
     {
         return SqlExpressionEof();
     }
 
-    // implement SqlAbstractParserImpl
     public SqlNode parseSqlStmtEof() throws Exception
     {
         return SqlStmtEof();
@@ -4742,7 +4732,7 @@ SqlBinaryOperator BinaryRowOperator() :
     { return SqlStdOperatorTable.NOT_EQUALS; }
     | <NE2>
     {
-        if (!this.allowBangEqual) {
+        if (!this.conformance.isBangEqualAllowed()) {
             throw new ParseException(RESOURCE.bangEqualNotAllowed().str());
         }
         return SqlStdOperatorTable.NOT_EQUALS;

http://git-wip-us.apache.org/repos/asf/calcite/blob/105bba1f/core/src/main/java/org/apache/calcite/config/CalciteConnectionConfigImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/config/CalciteConnectionConfigImpl.java b/core/src/main/java/org/apache/calcite/config/CalciteConnectionConfigImpl.java
index 9af61f5..f3dbd2a 100644
--- a/core/src/main/java/org/apache/calcite/config/CalciteConnectionConfigImpl.java
+++ b/core/src/main/java/org/apache/calcite/config/CalciteConnectionConfigImpl.java
@@ -25,6 +25,7 @@ import org.apache.calcite.sql.fun.OracleSqlOperatorTable;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.util.ChainedSqlOperatorTable;
 import org.apache.calcite.sql.validate.SqlConformance;
+import org.apache.calcite.sql.validate.SqlConformanceEnum;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -150,7 +151,7 @@ public class CalciteConnectionConfigImpl extends ConnectionConfigImpl
 
   public SqlConformance conformance() {
     return CalciteConnectionProperty.CONFORMANCE.wrap(properties)
-        .getEnum(SqlConformance.class);
+        .getEnum(SqlConformanceEnum.class);
   }
 }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/105bba1f/core/src/main/java/org/apache/calcite/config/CalciteConnectionProperty.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/config/CalciteConnectionProperty.java b/core/src/main/java/org/apache/calcite/config/CalciteConnectionProperty.java
index db88abc..2086f87 100644
--- a/core/src/main/java/org/apache/calcite/config/CalciteConnectionProperty.java
+++ b/core/src/main/java/org/apache/calcite/config/CalciteConnectionProperty.java
@@ -18,7 +18,7 @@ package org.apache.calcite.config;
 
 import org.apache.calcite.avatica.ConnectionProperty;
 import org.apache.calcite.model.JsonSchema;
-import org.apache.calcite.sql.validate.SqlConformance;
+import org.apache.calcite.sql.validate.SqlConformanceEnum;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -114,7 +114,7 @@ public enum CalciteConnectionProperty implements ConnectionProperty {
   TYPE_SYSTEM("typeSystem", Type.PLUGIN, null, false),
 
   /** SQL conformance level. */
-  CONFORMANCE("conformance", Type.ENUM, SqlConformance.DEFAULT, false);
+  CONFORMANCE("conformance", Type.ENUM, SqlConformanceEnum.DEFAULT, false);
 
   private final String camelName;
   private final Type type;

http://git-wip-us.apache.org/repos/asf/calcite/blob/105bba1f/core/src/main/java/org/apache/calcite/jdbc/CalciteConnectionImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/jdbc/CalciteConnectionImpl.java b/core/src/main/java/org/apache/calcite/jdbc/CalciteConnectionImpl.java
index 195ced7..5eebb38 100644
--- a/core/src/main/java/org/apache/calcite/jdbc/CalciteConnectionImpl.java
+++ b/core/src/main/java/org/apache/calcite/jdbc/CalciteConnectionImpl.java
@@ -54,7 +54,7 @@ import org.apache.calcite.server.CalciteServerStatement;
 import org.apache.calcite.sql.advise.SqlAdvisor;
 import org.apache.calcite.sql.advise.SqlAdvisorValidator;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
-import org.apache.calcite.sql.validate.SqlConformance;
+import org.apache.calcite.sql.validate.SqlConformanceEnum;
 import org.apache.calcite.sql.validate.SqlValidatorWithHints;
 import org.apache.calcite.tools.RelRunner;
 import org.apache.calcite.util.BuiltInMethod;
@@ -430,7 +430,7 @@ abstract class CalciteConnectionImpl
           new SqlAdvisorValidator(SqlStdOperatorTable.instance(),
           new CalciteCatalogReader(rootSchema, con.config().caseSensitive(),
               schemaPath, typeFactory),
-          typeFactory, SqlConformance.DEFAULT);
+          typeFactory, SqlConformanceEnum.DEFAULT);
       return new SqlAdvisor(validator);
     }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/105bba1f/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 360677c..fcbee23 100644
--- a/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
+++ b/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
@@ -699,7 +699,7 @@ public class CalcitePrepareImpl implements CalcitePrepare {
               .setQuotedCasing(config.quotedCasing())
               .setUnquotedCasing(config.unquotedCasing())
               .setQuoting(config.quoting())
-              .setAllowBangEqual(config.conformance().isBangEqualAllowed()));
+              .setConformance(config.conformance()));
       SqlNode sqlNode;
       try {
         sqlNode = parser.parseStmt();

http://git-wip-us.apache.org/repos/asf/calcite/blob/105bba1f/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java b/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java
index 3291ceb..635b2c5 100644
--- a/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java
+++ b/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java
@@ -37,6 +37,7 @@ import org.apache.calcite.sql.SqlOperatorTable;
 import org.apache.calcite.sql.parser.SqlParseException;
 import org.apache.calcite.sql.parser.SqlParser;
 import org.apache.calcite.sql.validate.SqlConformance;
+import org.apache.calcite.sql.validate.SqlConformanceEnum;
 import org.apache.calcite.sql.validate.SqlValidator;
 import org.apache.calcite.sql2rel.RelDecorrelator;
 import org.apache.calcite.sql2rel.SqlRexConvertletTable;
@@ -198,7 +199,7 @@ public class PlannerImpl implements Planner {
         return connectionConfig.conformance();
       }
     }
-    return SqlConformance.DEFAULT;
+    return SqlConformanceEnum.DEFAULT;
   }
 
   public Pair<SqlNode, RelDataType> validateAndGetType(SqlNode sqlNode)

http://git-wip-us.apache.org/repos/asf/calcite/blob/105bba1f/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 c7cef03..ad605da 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
@@ -26,6 +26,7 @@ import org.apache.calcite.sql.SqlOperator;
 import org.apache.calcite.sql.SqlSyntax;
 import org.apache.calcite.sql.SqlUnresolvedFunction;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.validate.SqlConformance;
 import org.apache.calcite.util.Util;
 
 import com.google.common.collect.ImmutableList;
@@ -444,9 +445,9 @@ public abstract class SqlAbstractParserImpl {
   public abstract void setIdentifierMaxLength(int identifierMaxLength);
 
   /**
-   * Sets whether the bang-equal token != is allowed as an alternative to &lt;&gt;.
+   * Sets the SQL language conformance level.
    */
-  public abstract void setAllowBangEqual(boolean allowBangEqual);
+  public abstract void setConformance(SqlConformance conformance);
 
   /**
    * Sets the SQL text that is being parsed.

http://git-wip-us.apache.org/repos/asf/calcite/blob/105bba1f/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 a1311a0..626269a 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
@@ -22,6 +22,9 @@ import org.apache.calcite.config.Lex;
 import org.apache.calcite.runtime.CalciteContextException;
 import org.apache.calcite.sql.SqlNode;
 import org.apache.calcite.sql.parser.impl.SqlParserImpl;
+import org.apache.calcite.sql.validate.SqlConformance;
+import org.apache.calcite.sql.validate.SqlConformanceEnum;
+import org.apache.calcite.sql.validate.SqlDelegatingConformance;
 
 import com.google.common.base.Preconditions;
 
@@ -32,7 +35,9 @@ 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;
+  @Deprecated // to be removed before 2.0
+  public static final boolean DEFAULT_ALLOW_BANG_EQUAL =
+      SqlConformanceEnum.DEFAULT.isBangEqualAllowed();
 
   //~ Instance fields --------------------------------------------------------
   private final SqlAbstractParserImpl parser;
@@ -48,7 +53,7 @@ public class SqlParser {
     parser.setQuotedCasing(config.quotedCasing());
     parser.setUnquotedCasing(config.unquotedCasing());
     parser.setIdentifierMaxLength(config.identifierMaxLength());
-    parser.setAllowBangEqual(config.allowBangEqual());
+    parser.setConformance(config.conformance());
     switch (config.quoting()) {
     case DOUBLE_QUOTE:
       parser.switchTo("DQID");
@@ -196,6 +201,8 @@ public class SqlParser {
     Casing unquotedCasing();
     Quoting quoting();
     boolean caseSensitive();
+    SqlConformance conformance();
+    @Deprecated // to be removed before 2.0
     boolean allowBangEqual();
     SqlParserImplFactory parserFactory();
   }
@@ -207,7 +214,9 @@ 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 SqlConformance conformance = SqlConformanceEnum.DEFAULT;
+    private boolean allowBangEqual =
+        SqlConformanceEnum.DEFAULT.isBangEqualAllowed();
     private SqlParserImplFactory parserFactory = SqlParserImpl.FACTORY;
 
     private ConfigBuilder() {}
@@ -218,6 +227,7 @@ public class SqlParser {
       this.unquotedCasing = config.unquotedCasing();
       this.quoting = config.quoting();
       this.identifierMaxLength = config.identifierMaxLength();
+      this.conformance = config.conformance();
       this.allowBangEqual = config.allowBangEqual();
       this.parserFactory = config.parserFactory();
       return this;
@@ -248,8 +258,23 @@ public class SqlParser {
       return this;
     }
 
-    public ConfigBuilder setAllowBangEqual(boolean allowBangEqual) {
-      this.allowBangEqual = allowBangEqual;
+    @SuppressWarnings("unused")
+    @Deprecated // to be removed before 2.0
+    public ConfigBuilder setAllowBangEqual(final boolean allowBangEqual) {
+      if (allowBangEqual != conformance.isBangEqualAllowed()) {
+        setConformance(
+            new SqlDelegatingConformance(conformance) {
+              @Override public boolean isBangEqualAllowed() {
+                return allowBangEqual;
+              }
+            });
+      }
+      return this;
+    }
+
+    public ConfigBuilder setConformance(SqlConformance conformance) {
+      this.conformance = conformance;
+      this.allowBangEqual = conformance.isBangEqualAllowed();
       return this;
     }
 
@@ -270,8 +295,9 @@ public class SqlParser {
      * {@link Config}. */
     public Config build() {
       return new ConfigImpl(identifierMaxLength, quotedCasing, unquotedCasing,
-          quoting, caseSensitive, allowBangEqual, parserFactory);
+          quoting, caseSensitive, conformance, parserFactory);
     }
+
   }
 
   /** Implementation of
@@ -280,7 +306,7 @@ public class SqlParser {
   private static class ConfigImpl implements Config {
     private final int identifierMaxLength;
     private final boolean caseSensitive;
-    private final boolean allowBangEqual;
+    private final SqlConformance conformance;
     private final Casing quotedCasing;
     private final Casing unquotedCasing;
     private final Quoting quoting;
@@ -288,10 +314,10 @@ public class SqlParser {
 
     private ConfigImpl(int identifierMaxLength, Casing quotedCasing,
         Casing unquotedCasing, Quoting quoting, boolean caseSensitive,
-        boolean allowBangEqual, SqlParserImplFactory parserFactory) {
+        SqlConformance conformance, SqlParserImplFactory parserFactory) {
       this.identifierMaxLength = identifierMaxLength;
       this.caseSensitive = caseSensitive;
-      this.allowBangEqual = allowBangEqual;
+      this.conformance = Preconditions.checkNotNull(conformance);
       this.quotedCasing = Preconditions.checkNotNull(quotedCasing);
       this.unquotedCasing = Preconditions.checkNotNull(unquotedCasing);
       this.quoting = Preconditions.checkNotNull(quoting);
@@ -318,8 +344,12 @@ public class SqlParser {
       return caseSensitive;
     }
 
+    public SqlConformance conformance() {
+      return conformance;
+    }
+
     public boolean allowBangEqual() {
-      return allowBangEqual;
+      return conformance.isBangEqualAllowed();
     }
 
     public SqlParserImplFactory parserFactory() {

http://git-wip-us.apache.org/repos/asf/calcite/blob/105bba1f/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
new file mode 100644
index 0000000..a36770c
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlAbstractConformance.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.sql.validate;
+
+/**
+ * Abstract base class for implementing {@link SqlConformance}.
+ *
+ * <p>Every method in {@code SqlConformance} is implemented,
+ * and behaves the same as in {@link SqlConformanceEnum#DEFAULT}.
+ */
+public abstract class SqlAbstractConformance implements SqlConformance {
+  public boolean isSortByOrdinal() {
+    return SqlConformanceEnum.DEFAULT.isSortByOrdinal();
+  }
+
+  public boolean isSortByAlias() {
+    return SqlConformanceEnum.DEFAULT.isSortByAlias();
+  }
+
+  public boolean isSortByAliasObscures() {
+    return SqlConformanceEnum.DEFAULT.isSortByAliasObscures();
+  }
+
+  public boolean isFromRequired() {
+    return SqlConformanceEnum.DEFAULT.isFromRequired();
+  }
+
+  public boolean isBangEqualAllowed() {
+    return SqlConformanceEnum.DEFAULT.isBangEqualAllowed();
+  }
+}
+
+// End SqlAbstractConformance.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/105bba1f/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 2b72499..22ac06c 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
@@ -18,95 +18,106 @@ package org.apache.calcite.sql.validate;
 
 /**
  * Enumeration of valid SQL compatibility modes.
+ *
+ * <p>For most purposes, one of the built-in compatibility modes in enum
+ * {@link SqlConformanceEnum} will suffice.
+ *
+ * <p>If you wish to implement this interface to build your own conformance,
+ * we strongly recommend that you extend {@link SqlAbstractConformance},
+ * or use a {@link SqlDelegatingConformance},
+ * so that you won't be broken by future changes.
+ *
+ * @see SqlConformanceEnum
+ * @see SqlAbstractConformance
+ * @see SqlDelegatingConformance
  */
-public enum SqlConformance {
-  DEFAULT, STRICT_92, STRICT_99, PRAGMATIC_99, ORACLE_10, STRICT_2003,
-  PRAGMATIC_2003;
+public interface SqlConformance {
+  /** Short-cut for {@link SqlConformanceEnum#DEFAULT}. */
+  @SuppressWarnings("unused")
+  @Deprecated // to be removed before 2.0
+  SqlConformanceEnum DEFAULT = SqlConformanceEnum.DEFAULT;
+  /** Short-cut for {@link SqlConformanceEnum#STRICT_92}. */
+  @SuppressWarnings("unused")
+  @Deprecated // to be removed before 2.0
+  SqlConformanceEnum STRICT_92 = SqlConformanceEnum.STRICT_92;
+  /** Short-cut for {@link SqlConformanceEnum#STRICT_99}. */
+  @SuppressWarnings("unused")
+  @Deprecated // to be removed before 2.0
+  SqlConformanceEnum STRICT_99 = SqlConformanceEnum.STRICT_99;
+  /** Short-cut for {@link SqlConformanceEnum#PRAGMATIC_99}. */
+  @SuppressWarnings("unused")
+  @Deprecated // to be removed before 2.0
+  SqlConformanceEnum PRAGMATIC_99 = SqlConformanceEnum.PRAGMATIC_99;
+  /** Short-cut for {@link SqlConformanceEnum#ORACLE_10}. */
+  @SuppressWarnings("unused")
+  @Deprecated // to be removed before 2.0
+  SqlConformanceEnum ORACLE_10 = SqlConformanceEnum.ORACLE_10;
+  /** Short-cut for {@link SqlConformanceEnum#STRICT_2003}. */
+  @SuppressWarnings("unused")
+  @Deprecated // to be removed before 2.0
+  SqlConformanceEnum STRICT_2003 = SqlConformanceEnum.STRICT_2003;
+  /** Short-cut for {@link SqlConformanceEnum#PRAGMATIC_2003}. */
+  @SuppressWarnings("unused")
+  @Deprecated // to be removed before 2.0
+  SqlConformanceEnum PRAGMATIC_2003 = SqlConformanceEnum.PRAGMATIC_2003;
 
   /**
    * Whether 'order by 2' is interpreted to mean 'sort by the 2nd column in
    * the select list'.
    *
-   * <p>True in {@link #DEFAULT}, {@link #ORACLE_10}, {@link #STRICT_92},
-   * {@link #PRAGMATIC_99}, {@link #PRAGMATIC_2003};
+   * <p>Among the built-in conformance levels, true in
+   * {@link SqlConformanceEnum#DEFAULT},
+   * {@link SqlConformanceEnum#ORACLE_10},
+   * {@link SqlConformanceEnum#STRICT_92},
+   * {@link SqlConformanceEnum#PRAGMATIC_99},
+   * {@link SqlConformanceEnum#PRAGMATIC_2003};
    * false otherwise.
    */
-  public boolean isSortByOrdinal() {
-    switch (this) {
-    case DEFAULT:
-    case ORACLE_10:
-    case STRICT_92:
-    case PRAGMATIC_99:
-    case PRAGMATIC_2003:
-      return true;
-    default:
-      return false;
-    }
-  }
+  boolean isSortByOrdinal();
 
   /**
    * Whether 'order by x' is interpreted to mean 'sort by the select list item
    * whose alias is x' even if there is a column called x.
    *
-   * <p>True in {@link #DEFAULT}, {@link #ORACLE_10}, {@link #STRICT_92};
+   * <p>Among the built-in conformance levels, true in
+   * {@link SqlConformanceEnum#DEFAULT},
+   * {@link SqlConformanceEnum#ORACLE_10},
+   * {@link SqlConformanceEnum#STRICT_92};
    * false otherwise.
    */
-  public boolean isSortByAlias() {
-    switch (this) {
-    case DEFAULT:
-    case ORACLE_10:
-    case STRICT_92:
-      return true;
-    default:
-      return false;
-    }
-  }
+  boolean isSortByAlias();
 
   /**
    * Whether "empno" is invalid in "select empno as x from emp order by empno"
    * because the alias "x" obscures it.
    *
-   * <p>True in {@link #STRICT_92};
+   * <p>Among the built-in conformance levels, true in
+   * {@link SqlConformanceEnum#STRICT_92};
    * false otherwise.
    */
-  public boolean isSortByAliasObscures() {
-    return this == SqlConformance.STRICT_92;
-  }
+  boolean isSortByAliasObscures();
 
   /**
    * Whether FROM clause is required in a SELECT statement.
    *
-   * <p>True in {@link #ORACLE_10}, {@link #STRICT_92}, {@link #STRICT_99},
-   * {@link #STRICT_2003};
+   * <p>Among the built-in conformance levels, true in
+   * {@link SqlConformanceEnum#ORACLE_10},
+   * {@link SqlConformanceEnum#STRICT_92},
+   * {@link SqlConformanceEnum#STRICT_99},
+   * {@link SqlConformanceEnum#STRICT_2003};
    * false otherwise.
    */
-  public boolean isFromRequired() {
-    switch (this) {
-    case ORACLE_10:
-    case STRICT_92:
-    case STRICT_99:
-    case STRICT_2003:
-      return true;
-    default:
-      return false;
-    }
-  }
+  boolean isFromRequired();
 
   /**
    * Whether the bang-equal token != is allowed as an alternative to &lt;&gt; in
    * the parser.
    *
-   * <p>True in {@link #ORACLE_10};
+   * <p>Among the built-in conformance levels, true in
+   * {@link SqlConformanceEnum#ORACLE_10};
    * false otherwise.
    */
-  public boolean isBangEqualAllowed() {
-    switch (this) {
-    case ORACLE_10:
-      return true;
-    default:
-      return false;
-    }
-  }
+  boolean isBangEqualAllowed();
 }
 
 // End SqlConformance.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/105bba1f/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
new file mode 100644
index 0000000..5458893
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlConformanceEnum.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.sql.validate;
+
+/**
+ * Enumeration of built-in SQL compatibility modes.
+ */
+public enum SqlConformanceEnum implements SqlConformance {
+  /** Calcite's default SQL behavior. */
+  DEFAULT,
+
+  /** Conformance value that instructs Calcite to use SQL semantics strictly
+   * consistent with the SQL:92 standard. */
+  STRICT_92,
+
+  /** Conformance value that instructs Calcite to use SQL semantics strictly
+   * consistent with the SQL:99 standard. */
+  STRICT_99,
+
+  /** Conformance value that instructs Calcite to use SQL semantics
+   * consistent with the SQL:99 standard, but ignoring its more
+   * inconvenient or controversial dicta. */
+  PRAGMATIC_99,
+
+  /** Conformance value that instructs Calcite to use SQL semantics
+   * consistent with Oracle version 10. */
+  ORACLE_10,
+
+  /** Conformance value that instructs Calcite to use SQL semantics strictly
+   * consistent with the SQL:2003 standard. */
+  STRICT_2003,
+
+  /** Conformance value that instructs Calcite to use SQL semantics
+   * consistent with the SQL:2003 standard, but ignoring its more
+   * inconvenient or controversial dicta. */
+  PRAGMATIC_2003;
+
+  public boolean isSortByOrdinal() {
+    switch (this) {
+    case DEFAULT:
+    case ORACLE_10:
+    case STRICT_92:
+    case PRAGMATIC_99:
+    case PRAGMATIC_2003:
+      return true;
+    default:
+      return false;
+    }
+  }
+
+  public boolean isSortByAlias() {
+    switch (this) {
+    case DEFAULT:
+    case ORACLE_10:
+    case STRICT_92:
+      return true;
+    default:
+      return false;
+    }
+  }
+
+  public boolean isSortByAliasObscures() {
+    return this == SqlConformanceEnum.STRICT_92;
+  }
+
+  public boolean isFromRequired() {
+    switch (this) {
+    case ORACLE_10:
+    case STRICT_92:
+    case STRICT_99:
+    case STRICT_2003:
+      return true;
+    default:
+      return false;
+    }
+  }
+
+  public boolean isBangEqualAllowed() {
+    switch (this) {
+    case ORACLE_10:
+      return true;
+    default:
+      return false;
+    }
+  }
+}
+
+// End SqlConformanceEnum.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/105bba1f/core/src/main/java/org/apache/calcite/sql/validate/SqlDelegatingConformance.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlDelegatingConformance.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlDelegatingConformance.java
new file mode 100644
index 0000000..47d56d3
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlDelegatingConformance.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.sql.validate;
+
+/**
+ * Implementation of {@link SqlConformance} that delegates all methods to
+ * another object. You can create a sub-class that overrides particular
+ * methods.
+ */
+public class SqlDelegatingConformance extends SqlAbstractConformance {
+  private final SqlConformance delegate;
+
+  /** Creates a SqlDelegatingConformance. */
+  protected SqlDelegatingConformance(SqlConformance delegate) {
+    this.delegate = delegate;
+  }
+
+  @Override public boolean isSortByOrdinal() {
+    return delegate.isSortByOrdinal();
+  }
+
+  @Override public boolean isSortByAlias() {
+    return delegate.isSortByAlias();
+  }
+
+  @Override public boolean isSortByAliasObscures() {
+    return delegate.isSortByAliasObscures();
+  }
+
+  @Override public boolean isFromRequired() {
+    return delegate.isFromRequired();
+  }
+
+  @Override public boolean isBangEqualAllowed() {
+    return delegate.isBangEqualAllowed();
+  }
+}
+
+// End SqlDelegatingConformance.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/105bba1f/core/src/main/java/org/apache/calcite/sql/validate/SqlValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidator.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidator.java
index 605c665..215b96c 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidator.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidator.java
@@ -109,7 +109,7 @@ public interface SqlValidator {
 
   /**
    * Returns the dialect of SQL (SQL:2003, etc.) this validator recognizes.
-   * Default is {@link SqlConformance#DEFAULT}.
+   * Default is {@link SqlConformanceEnum#DEFAULT}.
    *
    * @return dialect of SQL this validator recognizes
    */

http://git-wip-us.apache.org/repos/asf/calcite/blob/105bba1f/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java
index 249f5f5..62410b3 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java
@@ -209,7 +209,7 @@ public class SqlValidatorUtil {
       SqlValidatorCatalogReader catalogReader,
       RelDataTypeFactory typeFactory) {
     return newValidator(opTab, catalogReader, typeFactory,
-        SqlConformance.DEFAULT);
+        SqlConformanceEnum.DEFAULT);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/calcite/blob/105bba1f/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 c9ecce6..be651ff 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
@@ -26,6 +26,7 @@ import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.parser.SqlParser;
 import org.apache.calcite.sql.type.SqlTypeFactoryImpl;
 import org.apache.calcite.sql.validate.SqlConformance;
+import org.apache.calcite.sql.validate.SqlConformanceEnum;
 import org.apache.calcite.sql.validate.SqlValidator;
 import org.apache.calcite.sql.validate.SqlValidatorUtil;
 import org.apache.calcite.sql.validate.SqlValidatorWithHints;
@@ -51,7 +52,7 @@ public class DefaultSqlTestFactory implements SqlTestFactory {
           .put("quotedCasing", Casing.UNCHANGED)
           .put("unquotedCasing", Casing.TO_UPPER)
           .put("caseSensitive", true)
-          .put("conformance", SqlConformance.DEFAULT)
+          .put("conformance", SqlConformanceEnum.DEFAULT)
           .put("operatorTable", SqlStdOperatorTable.instance())
           .put("connectionFactory",
               CalciteAssert.EMPTY_CONNECTION_FACTORY
@@ -80,7 +81,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())
+            .setConformance((SqlConformance) factory.get("conformance"))
             .build());
   }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/105bba1f/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 0c3acc6..3c024f8 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,7 +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.SqlConformanceEnum;
 import org.apache.calcite.sql.validate.SqlValidatorImpl;
 import org.apache.calcite.sql.validate.SqlValidatorScope;
 import org.apache.calcite.test.CalciteAssert;
@@ -2775,10 +2775,10 @@ public abstract class SqlOperatorBaseTest {
     // "!=" is allowed under ORACLE_10 SQL conformance level
     final SqlTester tester1 =
         tester
-            .withConformance(SqlConformance.ORACLE_10)
+            .withConformance(SqlConformanceEnum.ORACLE_10)
             .withConnectionFactory(
                 CalciteAssert.EMPTY_CONNECTION_FACTORY
-                    .with("conformance", SqlConformance.ORACLE_10));
+                    .with("conformance", SqlConformanceEnum.ORACLE_10));
 
     tester1
         .checkBoolean("1 <> 1", Boolean.FALSE);

http://git-wip-us.apache.org/repos/asf/calcite/blob/105bba1f/core/src/test/java/org/apache/calcite/sql/test/SqlTesterImpl.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/sql/test/SqlTesterImpl.java b/core/src/test/java/org/apache/calcite/sql/test/SqlTesterImpl.java
index 3c55d6d..fdf08f8 100644
--- a/core/src/test/java/org/apache/calcite/sql/test/SqlTesterImpl.java
+++ b/core/src/test/java/org/apache/calcite/sql/test/SqlTesterImpl.java
@@ -39,6 +39,7 @@ import org.apache.calcite.sql.parser.SqlParserUtil;
 import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.calcite.sql.util.SqlShuttle;
 import org.apache.calcite.sql.validate.SqlConformance;
+import org.apache.calcite.sql.validate.SqlConformanceEnum;
 import org.apache.calcite.sql.validate.SqlMonotonicity;
 import org.apache.calcite.sql.validate.SqlValidator;
 import org.apache.calcite.sql.validate.SqlValidatorNamespace;
@@ -290,7 +291,7 @@ public class SqlTesterImpl implements SqlTester {
 
   public SqlTesterImpl withConformance(SqlConformance conformance) {
     if (conformance == null) {
-      conformance = SqlConformance.DEFAULT;
+      conformance = SqlConformanceEnum.DEFAULT;
     }
     return with("conformance", conformance);
   }

http://git-wip-us.apache.org/repos/asf/calcite/blob/105bba1f/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java b/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
index d8e0ff0..166db72 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
@@ -44,6 +44,7 @@ import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.parser.SqlParser;
 import org.apache.calcite.sql.type.SqlTypeFactoryImpl;
 import org.apache.calcite.sql.validate.SqlConformance;
+import org.apache.calcite.sql.validate.SqlConformanceEnum;
 import org.apache.calcite.sql.validate.SqlMonotonicity;
 import org.apache.calcite.sql.validate.SqlValidator;
 import org.apache.calcite.sql.validate.SqlValidatorCatalogReader;
@@ -591,7 +592,7 @@ public abstract class SqlToRelTestBase {
     }
 
     public SqlConformance getConformance() {
-      return SqlConformance.DEFAULT;
+      return SqlConformanceEnum.DEFAULT;
     }
 
     public SqlValidator createValidator(

http://git-wip-us.apache.org/repos/asf/calcite/blob/105bba1f/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
index a6d0c35..caee32f 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
@@ -29,7 +29,10 @@ import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.test.SqlTester;
 import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.calcite.sql.util.ChainedSqlOperatorTable;
+import org.apache.calcite.sql.validate.SqlAbstractConformance;
 import org.apache.calcite.sql.validate.SqlConformance;
+import org.apache.calcite.sql.validate.SqlConformanceEnum;
+import org.apache.calcite.sql.validate.SqlDelegatingConformance;
 import org.apache.calcite.sql.validate.SqlMonotonicity;
 import org.apache.calcite.sql.validate.SqlValidator;
 import org.apache.calcite.sql.validate.SqlValidatorUtil;
@@ -46,11 +49,14 @@ import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.nio.charset.Charset;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Locale;
+import java.util.Objects;
 
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.is;
@@ -5731,6 +5737,49 @@ public class SqlValidatorTest extends SqlValidatorTestCase {
     return buf.toString();
   }
 
+  @Test public void testAbstractConformance()
+      throws InvocationTargetException, IllegalAccessException {
+    final SqlAbstractConformance c0 = new SqlAbstractConformance() {
+    };
+    final SqlConformance c1 = SqlConformanceEnum.DEFAULT;
+    for (Method method : SqlConformance.class.getMethods()) {
+      final Object o0 = method.invoke(c0);
+      final Object o1 = method.invoke(c1);
+      assertThat(method.toString(), Objects.equals(o0, o1), is(true));
+    }
+  }
+
+  @Test public void testUserDefinedConformance() {
+    final SqlAbstractConformance c =
+        new SqlDelegatingConformance(SqlConformanceEnum.DEFAULT) {
+          public boolean isBangEqualAllowed() {
+            return true;
+          }
+        };
+    // Our conformance behaves differently from ORACLE_10 for FROM-less query.
+    final SqlTester customTester = tester.withConformance(c);
+    final SqlTester defaultTester =
+        tester.withConformance(SqlConformanceEnum.DEFAULT);
+    final SqlTester oracleTester =
+        tester.withConformance(SqlConformanceEnum.ORACLE_10);
+    sql("^select 2+2^")
+        .tester(customTester)
+        .ok()
+        .tester(defaultTester)
+        .ok()
+        .tester(oracleTester)
+        .fails("SELECT must have a FROM clause");
+
+    // Our conformance behaves like ORACLE_10 for "!=" operator.
+    sql("select * from (values 1) where 1 != 2")
+        .tester(customTester)
+        .ok()
+        .tester(defaultTester)
+        .fails("Bang equal '!=' is not allowed under the current SQL conformance level")
+        .tester(oracleTester)
+        .ok();
+  }
+
   @Test public void testOrder() {
     final SqlConformance conformance = tester.getConformance();
     check("select empno as x from emp order by empno");
@@ -7016,13 +7065,13 @@ public class SqlValidatorTest extends SqlValidatorTestCase {
 
   @Test public void testSelectWithoutFrom() {
     sql("^select 2+2^")
-        .tester(tester.withConformance(SqlConformance.DEFAULT))
+        .tester(tester.withConformance(SqlConformanceEnum.DEFAULT))
         .ok();
     sql("^select 2+2^")
-        .tester(tester.withConformance(SqlConformance.ORACLE_10))
+        .tester(tester.withConformance(SqlConformanceEnum.ORACLE_10))
         .fails("SELECT must have a FROM clause");
     sql("^select 2+2^")
-        .tester(tester.withConformance(SqlConformance.STRICT_2003))
+        .tester(tester.withConformance(SqlConformanceEnum.STRICT_2003))
         .fails("SELECT must have a FROM clause");
   }