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 <>.
+ * 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 <> 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");
}