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 2014/09/19 03:03:02 UTC
[1/2] [OPTIQ-413] Add RelDataTypeSystem plugin,
allowing different max precision of a DECIMAL
Repository: incubator-optiq
Updated Branches:
refs/heads/master a2cc356cf -> 0fd4e3d9e
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/org/eigenbase/sql/type/SqlTypeName.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/sql/type/SqlTypeName.java b/core/src/main/java/org/eigenbase/sql/type/SqlTypeName.java
index 65edb45..41745f5 100644
--- a/core/src/main/java/org/eigenbase/sql/type/SqlTypeName.java
+++ b/core/src/main/java/org/eigenbase/sql/type/SqlTypeName.java
@@ -22,6 +22,7 @@ import java.sql.*;
import java.util.*;
+import org.eigenbase.reltype.RelDataTypeSystem;
import org.eigenbase.sql.*;
import org.eigenbase.sql.parser.*;
import org.eigenbase.util.*;
@@ -87,10 +88,6 @@ public enum SqlTypeName {
SqlTypeFamily.COLUMN_LIST);
public static final int MAX_DATETIME_PRECISION = 3;
- public static final int MAX_NUMERIC_PRECISION = 19;
- public static final int MAX_NUMERIC_SCALE = 19;
- public static final int MAX_CHAR_LENGTH = 65536;
- public static final int MAX_BINARY_LENGTH = 65536;
// Minimum and default interval precisions are defined by SQL2003
// Maximum interval precisions are implementation dependent,
@@ -301,31 +298,15 @@ public enum SqlTypeName {
}
/**
- * @return default precision for this type if supported, otherwise -1 if
- * precision is either unsupported or must be specified explicitly
+ * Returns the default precision for this type if supported, otherwise -1 if
+ * precision is either unsupported or must be specified explicitly.
+ *
+ * @deprecated Use
+ * {@link org.eigenbase.reltype.RelDataTypeSystem#getDefaultPrecision(SqlTypeName)};
+ * will be removed after optiq-0.9.1.
*/
public int getDefaultPrecision() {
- switch (this) {
- case CHAR:
- case BINARY:
- case VARCHAR:
- case VARBINARY:
- return 1;
- case TIME:
- return 0;
- case TIMESTAMP:
-
- // TODO jvs 26-July-2004: should be 6 for microseconds,
- // but we can't support that yet
- return 0;
- case DECIMAL:
- return MAX_NUMERIC_PRECISION;
- case INTERVAL_DAY_TIME:
- case INTERVAL_YEAR_MONTH:
- return DEFAULT_INTERVAL_START_PRECISION;
- default:
- return -1;
- }
+ return RelDataTypeSystem.DEFAULT.getDefaultPrecision(this);
}
/**
@@ -698,26 +679,13 @@ public enum SqlTypeName {
* precision/length are not applicable for this type.
*
* @return Maximum allowed precision
+ *
+ * @deprecated Use
+ * {@link org.eigenbase.reltype.RelDataTypeSystem#getMaxScale(SqlTypeName)};
+ * will be removed after optiq-0.9.1.
*/
public int getMaxPrecision() {
- switch (this) {
- case DECIMAL:
- return MAX_NUMERIC_PRECISION;
- case VARCHAR:
- case CHAR:
- return MAX_CHAR_LENGTH;
- case VARBINARY:
- case BINARY:
- return MAX_BINARY_LENGTH;
- case TIME:
- case TIMESTAMP:
- return MAX_DATETIME_PRECISION;
- case INTERVAL_DAY_TIME:
- case INTERVAL_YEAR_MONTH:
- return MAX_INTERVAL_START_PRECISION;
- default:
- return -1;
- }
+ return RelDataTypeSystem.DEFAULT.getMaxPrecision(this);
}
/**
@@ -726,17 +694,13 @@ public enum SqlTypeName {
* applicable for this type.
*
* @return Maximum allowed scale
+ *
+ * @deprecated Use
+ * {@link org.eigenbase.reltype.RelDataTypeSystem#getMaxScale(SqlTypeName)};
+ * will be removed after optiq-0.9.1.
*/
public int getMaxScale() {
- switch (this) {
- case DECIMAL:
- return MAX_NUMERIC_SCALE;
- case INTERVAL_DAY_TIME:
- case INTERVAL_YEAR_MONTH:
- return MAX_INTERVAL_FRACTIONAL_SECOND_PRECISION;
- default:
- return -1;
- }
+ return RelDataTypeSystem.DEFAULT.getMaxScale(this);
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/org/eigenbase/sql/validate/SqlValidatorImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/sql/validate/SqlValidatorImpl.java b/core/src/main/java/org/eigenbase/sql/validate/SqlValidatorImpl.java
index b0d2901..631ccf6 100644
--- a/core/src/main/java/org/eigenbase/sql/validate/SqlValidatorImpl.java
+++ b/core/src/main/java/org/eigenbase/sql/validate/SqlValidatorImpl.java
@@ -2500,7 +2500,7 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
String intervalStr = interval.getIntervalLiteral();
// throws EigenbaseContextException if string is invalid
int[] values = intervalQualifier.evaluateIntervalLiteral(intervalStr,
- literal.getParserPosition());
+ literal.getParserPosition(), typeFactory.getTypeSystem());
Util.discard(values);
}
break;
@@ -2525,43 +2525,41 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
assert qualifier != null;
boolean startPrecisionOutOfRange = false;
boolean fractionalSecondPrecisionOutOfRange = false;
-
+ final RelDataTypeSystem typeSystem = typeFactory.getTypeSystem();
+
+ final int startPrecision = qualifier.getStartPrecision(typeSystem);
+ final int fracPrecision =
+ qualifier.getFractionalSecondPrecision(typeSystem);
+ final int maxPrecision = typeSystem.getMaxPrecision(qualifier.typeName());
+ final int minPrecision = qualifier.typeName().getMinPrecision();
+ final int minScale = qualifier.typeName().getMinScale();
+ final int maxScale = typeSystem.getMaxScale(qualifier.typeName());
if (qualifier.isYearMonth()) {
- if ((qualifier.getStartPrecision()
- < SqlTypeName.INTERVAL_YEAR_MONTH.getMinPrecision())
- || (qualifier.getStartPrecision()
- > SqlTypeName.INTERVAL_YEAR_MONTH.getMaxPrecision())) {
+ if (startPrecision < minPrecision || startPrecision > maxPrecision) {
startPrecisionOutOfRange = true;
- } else if (
- (qualifier.getFractionalSecondPrecision()
- < SqlTypeName.INTERVAL_YEAR_MONTH.getMinScale())
- || (qualifier.getFractionalSecondPrecision()
- > SqlTypeName.INTERVAL_YEAR_MONTH.getMaxScale())) {
- fractionalSecondPrecisionOutOfRange = true;
+ } else {
+ if (fracPrecision < minScale || fracPrecision > maxScale) {
+ fractionalSecondPrecisionOutOfRange = true;
+ }
}
} else {
- if ((qualifier.getStartPrecision()
- < SqlTypeName.INTERVAL_DAY_TIME.getMinPrecision())
- || (qualifier.getStartPrecision()
- > SqlTypeName.INTERVAL_DAY_TIME.getMaxPrecision())) {
+ if (startPrecision < minPrecision || startPrecision > maxPrecision) {
startPrecisionOutOfRange = true;
- } else if (
- (qualifier.getFractionalSecondPrecision()
- < SqlTypeName.INTERVAL_DAY_TIME.getMinScale())
- || (qualifier.getFractionalSecondPrecision()
- > SqlTypeName.INTERVAL_DAY_TIME.getMaxScale())) {
- fractionalSecondPrecisionOutOfRange = true;
+ } else {
+ if (fracPrecision < minScale || fracPrecision > maxScale) {
+ fractionalSecondPrecisionOutOfRange = true;
+ }
}
}
if (startPrecisionOutOfRange) {
throw newValidationError(qualifier,
- RESOURCE.intervalStartPrecisionOutOfRange(
- qualifier.getStartPrecision(), "INTERVAL " + qualifier));
+ RESOURCE.intervalStartPrecisionOutOfRange(startPrecision,
+ "INTERVAL " + qualifier));
} else if (fractionalSecondPrecisionOutOfRange) {
throw newValidationError(qualifier,
RESOURCE.intervalFractionalSecondPrecisionOutOfRange(
- qualifier.getFractionalSecondPrecision(),
+ fracPrecision,
"INTERVAL " + qualifier));
}
}
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/org/eigenbase/sql2rel/SqlToRelConverter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/sql2rel/SqlToRelConverter.java b/core/src/main/java/org/eigenbase/sql2rel/SqlToRelConverter.java
index 6694895..c940b6c 100644
--- a/core/src/main/java/org/eigenbase/sql2rel/SqlToRelConverter.java
+++ b/core/src/main/java/org/eigenbase/sql2rel/SqlToRelConverter.java
@@ -4746,12 +4746,11 @@ public class SqlToRelConverter {
*/
private RelDataType computeHistogramType(RelDataType type) {
if (SqlTypeUtil.isExactNumeric(type)
- && (type.getSqlTypeName() != SqlTypeName.BIGINT)) {
- return new BasicSqlType(SqlTypeName.BIGINT);
- } else if (
- SqlTypeUtil.isApproximateNumeric(type)
- && (type.getSqlTypeName() != SqlTypeName.DOUBLE)) {
- return new BasicSqlType(SqlTypeName.DOUBLE);
+ && type.getSqlTypeName() != SqlTypeName.BIGINT) {
+ return typeFactory.createSqlType(SqlTypeName.BIGINT);
+ } else if (SqlTypeUtil.isApproximateNumeric(type)
+ && type.getSqlTypeName() != SqlTypeName.DOUBLE) {
+ return typeFactory.createSqlType(SqlTypeName.DOUBLE);
} else {
return type;
}
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/test/java/net/hydromatic/optiq/impl/clone/ArrayTableTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/net/hydromatic/optiq/impl/clone/ArrayTableTest.java b/core/src/test/java/net/hydromatic/optiq/impl/clone/ArrayTableTest.java
index b2f4f59..534e9c2 100644
--- a/core/src/test/java/net/hydromatic/optiq/impl/clone/ArrayTableTest.java
+++ b/core/src/test/java/net/hydromatic/optiq/impl/clone/ArrayTableTest.java
@@ -23,6 +23,7 @@ import net.hydromatic.optiq.jdbc.JavaTypeFactoryImpl;
import org.eigenbase.reltype.RelDataType;
import org.eigenbase.reltype.RelDataTypeImpl;
+import org.eigenbase.reltype.RelDataTypeSystem;
import org.junit.Test;
@@ -281,7 +282,8 @@ public class ArrayTableTest {
}
@Test public void testLoadSorted() {
- final JavaTypeFactoryImpl typeFactory = new JavaTypeFactoryImpl();
+ final JavaTypeFactoryImpl typeFactory =
+ new JavaTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
final RelDataType rowType =
typeFactory.builder()
.add("empid", typeFactory.createType(int.class))
@@ -316,7 +318,8 @@ public class ArrayTableTest {
* column #0. The algorithm needs to go back and permute the values of
* column #0 after it discovers that column #1 is unique and sorts by it. */
@Test public void testLoadSorted2() {
- final JavaTypeFactoryImpl typeFactory = new JavaTypeFactoryImpl();
+ final JavaTypeFactoryImpl typeFactory =
+ new JavaTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
final RelDataType rowType =
typeFactory.builder()
.add("deptno", typeFactory.createType(int.class))
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/test/java/net/hydromatic/optiq/test/MaterializationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/net/hydromatic/optiq/test/MaterializationTest.java b/core/src/test/java/net/hydromatic/optiq/test/MaterializationTest.java
index 314a919..3b4629d 100644
--- a/core/src/test/java/net/hydromatic/optiq/test/MaterializationTest.java
+++ b/core/src/test/java/net/hydromatic/optiq/test/MaterializationTest.java
@@ -22,6 +22,7 @@ import net.hydromatic.optiq.prepare.Prepare;
import org.eigenbase.relopt.SubstitutionVisitor;
import org.eigenbase.reltype.RelDataType;
+import org.eigenbase.reltype.RelDataTypeSystem;
import org.eigenbase.rex.*;
import org.eigenbase.sql.fun.SqlStdOperatorTable;
@@ -46,7 +47,8 @@ public class MaterializationTest {
OptiqAssert.checkResultContains(
"EnumerableTableAccessRel(table=[[hr, m0]])");
- final JavaTypeFactoryImpl typeFactory = new JavaTypeFactoryImpl();
+ final JavaTypeFactoryImpl typeFactory =
+ new JavaTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
final RexBuilder rexBuilder = new RexBuilder(typeFactory);
@Test public void testFilter() {
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/test/java/net/hydromatic/optiq/tools/FrameworksTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/net/hydromatic/optiq/tools/FrameworksTest.java b/core/src/test/java/net/hydromatic/optiq/tools/FrameworksTest.java
index 1f0cb33..ed4f381 100644
--- a/core/src/test/java/net/hydromatic/optiq/tools/FrameworksTest.java
+++ b/core/src/test/java/net/hydromatic/optiq/tools/FrameworksTest.java
@@ -21,16 +21,21 @@ import net.hydromatic.optiq.Table;
import net.hydromatic.optiq.impl.AbstractTable;
import net.hydromatic.optiq.rules.java.EnumerableConvention;
import net.hydromatic.optiq.rules.java.JavaRules;
+import net.hydromatic.optiq.server.OptiqServerStatement;
import org.eigenbase.rel.FilterRel;
import org.eigenbase.rel.RelNode;
import org.eigenbase.relopt.*;
import org.eigenbase.reltype.RelDataType;
import org.eigenbase.reltype.RelDataTypeFactory;
+import org.eigenbase.reltype.RelDataTypeSystem;
+import org.eigenbase.reltype.RelDataTypeSystemImpl;
import org.eigenbase.rex.RexBuilder;
+import org.eigenbase.rex.RexLiteral;
import org.eigenbase.rex.RexNode;
import org.eigenbase.sql.SqlExplainLevel;
import org.eigenbase.sql.fun.SqlStdOperatorTable;
+import org.eigenbase.sql.type.SqlTypeName;
import org.eigenbase.util.Util;
import org.junit.Test;
@@ -110,6 +115,69 @@ public class FrameworksTest {
SchemaPlus rootSchema = Frameworks.createRootSchema(false);
assertThat(rootSchema.getSubSchemaNames().size(), equalTo(0));
}
+
+ /** Tests that validation (specifically, inferring the result of adding
+ * two DECIMAL(19, 0) values together) happens differently with a type system
+ * that allows a larger maximum precision for decimals.
+ *
+ * <p>Test case for
+ * <a href="https://issues.apache.org/jira/browse/OPTIQ-413">OPTIQ-413</a>,
+ * "Add RelDataTypeSystem plugin, allowing different max precision of a
+ * DECIMAL".
+ *
+ * <p>Also tests the plugin system, by specifying implementations of a
+ * plugin interface with public and private constructors. */
+ @Test public void testTypeSystem() {
+ checkTypeSystem(19, Frameworks.newConfigBuilder().build());
+ checkTypeSystem(25, Frameworks.newConfigBuilder()
+ .typeSystem(HiveLikeTypeSystem.INSTANCE).build());
+ checkTypeSystem(31, Frameworks.newConfigBuilder()
+ .typeSystem(new HiveLikeTypeSystem2()).build());
+ }
+
+ private void checkTypeSystem(final int expected, FrameworkConfig config) {
+ Frameworks.withPrepare(
+ new Frameworks.PrepareAction<Void>(config) {
+ @Override public Void apply(RelOptCluster cluster,
+ RelOptSchema relOptSchema, SchemaPlus rootSchema,
+ OptiqServerStatement statement) {
+ final RelDataType type =
+ cluster.getTypeFactory()
+ .createSqlType(SqlTypeName.DECIMAL, 30, 2);
+ final RexLiteral literal =
+ cluster.getRexBuilder().makeExactLiteral(BigDecimal.ONE, type);
+ final RexNode call =
+ cluster.getRexBuilder().makeCall(SqlStdOperatorTable.PLUS,
+ literal,
+ literal);
+ assertEquals(expected, call.getType().getPrecision());
+ return null;
+ }
+ });
+ }
+
+ /** Dummy type system, similar to Hive's, accessed via an INSTANCE member. */
+ public static class HiveLikeTypeSystem extends RelDataTypeSystemImpl {
+ public static final RelDataTypeSystem INSTANCE = new HiveLikeTypeSystem();
+
+ private HiveLikeTypeSystem() {}
+
+ @Override public int getMaxNumericPrecision() {
+ assert super.getMaxNumericPrecision() == 19;
+ return 25;
+ }
+ }
+
+ /** Dummy type system, similar to Hive's, accessed via a public default
+ * constructor. */
+ public static class HiveLikeTypeSystem2 extends RelDataTypeSystemImpl {
+ public HiveLikeTypeSystem2() {}
+
+ @Override public int getMaxNumericPrecision() {
+ assert super.getMaxNumericPrecision() == 19;
+ return 38;
+ }
+ }
}
// End FrameworksTest.java
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/test/java/org/eigenbase/relopt/RelOptUtilTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/eigenbase/relopt/RelOptUtilTest.java b/core/src/test/java/org/eigenbase/relopt/RelOptUtilTest.java
index f08c14c..65e8b5f 100644
--- a/core/src/test/java/org/eigenbase/relopt/RelOptUtilTest.java
+++ b/core/src/test/java/org/eigenbase/relopt/RelOptUtilTest.java
@@ -36,7 +36,8 @@ public class RelOptUtilTest {
//~ Methods ----------------------------------------------------------------
@Test public void testTypeDump() {
- RelDataTypeFactory typeFactory = new SqlTypeFactoryImpl();
+ RelDataTypeFactory typeFactory =
+ new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
RelDataType t1 =
typeFactory.builder()
.add("f0", SqlTypeName.DECIMAL, 5, 2)
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/test/java/org/eigenbase/relopt/volcano/VolcanoPlannerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/eigenbase/relopt/volcano/VolcanoPlannerTest.java b/core/src/test/java/org/eigenbase/relopt/volcano/VolcanoPlannerTest.java
index 0a060ef..125fdb5 100644
--- a/core/src/test/java/org/eigenbase/relopt/volcano/VolcanoPlannerTest.java
+++ b/core/src/test/java/org/eigenbase/relopt/volcano/VolcanoPlannerTest.java
@@ -60,7 +60,8 @@ public class VolcanoPlannerTest {
static RelOptCluster newCluster(VolcanoPlanner planner) {
RelOptQuery query = new RelOptQuery(planner);
- RelDataTypeFactory typeFactory = new SqlTypeFactoryImpl();
+ RelDataTypeFactory typeFactory =
+ new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
return query.createCluster(
typeFactory,
new RexBuilder(typeFactory));
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/test/java/org/eigenbase/sql/test/DefaultSqlTestFactory.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/eigenbase/sql/test/DefaultSqlTestFactory.java b/core/src/test/java/org/eigenbase/sql/test/DefaultSqlTestFactory.java
index a83a61b..c2538f5 100644
--- a/core/src/test/java/org/eigenbase/sql/test/DefaultSqlTestFactory.java
+++ b/core/src/test/java/org/eigenbase/sql/test/DefaultSqlTestFactory.java
@@ -17,6 +17,7 @@
package org.eigenbase.sql.test;
import org.eigenbase.reltype.RelDataTypeFactory;
+import org.eigenbase.reltype.RelDataTypeSystem;
import org.eigenbase.sql.SqlOperatorTable;
import org.eigenbase.sql.advise.SqlAdvisor;
import org.eigenbase.sql.fun.SqlStdOperatorTable;
@@ -74,7 +75,8 @@ public class DefaultSqlTestFactory implements SqlTestFactory {
public SqlValidator getValidator(SqlTestFactory factory) {
final SqlOperatorTable operatorTable = factory.createOperatorTable();
final boolean caseSensitive = (Boolean) factory.get("caseSensitive");
- final RelDataTypeFactory typeFactory = new SqlTypeFactoryImpl();
+ final RelDataTypeFactory typeFactory =
+ new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
return SqlValidatorUtil.newValidator(operatorTable,
new MockCatalogReader(typeFactory, caseSensitive).init(),
typeFactory);
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/test/java/org/eigenbase/sql/test/SqlAdvisorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/eigenbase/sql/test/SqlAdvisorTest.java b/core/src/test/java/org/eigenbase/sql/test/SqlAdvisorTest.java
index 2f0797b..a707234 100644
--- a/core/src/test/java/org/eigenbase/sql/test/SqlAdvisorTest.java
+++ b/core/src/test/java/org/eigenbase/sql/test/SqlAdvisorTest.java
@@ -1176,9 +1176,9 @@ public class SqlAdvisorTest extends SqlValidatorTestCase {
}
@Override
- public SqlValidator getValidator(
- SqlTestFactory factory) {
- final RelDataTypeFactory typeFactory = new SqlTypeFactoryImpl();
+ public SqlValidator getValidator(SqlTestFactory factory) {
+ final RelDataTypeFactory typeFactory =
+ new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
final SqlConformance conformance = (SqlConformance) get("conformance");
final boolean caseSensitive = (Boolean) factory.get("caseSensitive");
return new SqlAdvisorValidator(
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/test/java/org/eigenbase/sql/test/SqlOperatorBaseTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/eigenbase/sql/test/SqlOperatorBaseTest.java b/core/src/test/java/org/eigenbase/sql/test/SqlOperatorBaseTest.java
index 6f3cc18..6ef09a4 100644
--- a/core/src/test/java/org/eigenbase/sql/test/SqlOperatorBaseTest.java
+++ b/core/src/test/java/org/eigenbase/sql/test/SqlOperatorBaseTest.java
@@ -24,6 +24,7 @@ import java.text.*;
import java.util.*;
import java.util.regex.*;
+import org.eigenbase.reltype.RelDataType;
import org.eigenbase.sql.*;
import org.eigenbase.sql.fun.*;
import org.eigenbase.sql.parser.*;
@@ -4815,8 +4816,10 @@ public abstract class SqlOperatorBaseTest {
if (!enable) {
return;
}
- for (BasicSqlType type : SqlLimitsTest.getTypes()) {
- for (Object o : getValues(type, true)) {
+ final List<RelDataType> types =
+ SqlLimitsTest.getTypes(tester.getValidator().getTypeFactory());
+ for (RelDataType type : types) {
+ for (Object o : getValues((BasicSqlType) type, true)) {
SqlLiteral literal =
type.getSqlTypeName().createLiteral(o, SqlParserPos.ZERO);
SqlString literalString =
@@ -4863,8 +4866,10 @@ public abstract class SqlOperatorBaseTest {
*/
@Test public void testLiteralBeyondLimit() {
tester.setFor(SqlStdOperatorTable.CAST);
- for (BasicSqlType type : SqlLimitsTest.getTypes()) {
- for (Object o : getValues(type, false)) {
+ final List<RelDataType> types =
+ SqlLimitsTest.getTypes(tester.getValidator().getTypeFactory());
+ for (RelDataType type : types) {
+ for (Object o : getValues((BasicSqlType) type, false)) {
SqlLiteral literal =
type.getSqlTypeName().createLiteral(o, SqlParserPos.ZERO);
SqlString literalString =
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/test/java/org/eigenbase/test/RexProgramTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/eigenbase/test/RexProgramTest.java b/core/src/test/java/org/eigenbase/test/RexProgramTest.java
index 184f1e6..c21168c 100644
--- a/core/src/test/java/org/eigenbase/test/RexProgramTest.java
+++ b/core/src/test/java/org/eigenbase/test/RexProgramTest.java
@@ -61,7 +61,7 @@ public class RexProgramTest {
@Before
public void setUp() {
- typeFactory = new JavaTypeFactoryImpl();
+ typeFactory = new JavaTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
rexBuilder = new RexBuilder(typeFactory);
}
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/test/java/org/eigenbase/test/RexTransformerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/eigenbase/test/RexTransformerTest.java b/core/src/test/java/org/eigenbase/test/RexTransformerTest.java
index 788c859..95f0a58 100644
--- a/core/src/test/java/org/eigenbase/test/RexTransformerTest.java
+++ b/core/src/test/java/org/eigenbase/test/RexTransformerTest.java
@@ -47,7 +47,7 @@ public class RexTransformerTest {
@Before
public void setUp() {
- typeFactory = new JavaTypeFactoryImpl();
+ typeFactory = new JavaTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
rexBuilder = new RexBuilder(typeFactory);
boolRelDataType = typeFactory.createSqlType(SqlTypeName.BOOLEAN);
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/test/java/org/eigenbase/test/SargTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/eigenbase/test/SargTest.java b/core/src/test/java/org/eigenbase/test/SargTest.java
index 5f77c03..57230ad 100644
--- a/core/src/test/java/org/eigenbase/test/SargTest.java
+++ b/core/src/test/java/org/eigenbase/test/SargTest.java
@@ -76,7 +76,8 @@ public class SargTest {
public void setUp() {
// create some reusable fixtures
- RelDataTypeFactory typeFactory = new SqlTypeFactoryImpl();
+ RelDataTypeFactory typeFactory =
+ new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
intType = typeFactory.createSqlType(SqlTypeName.INTEGER);
intType = typeFactory.createTypeWithNullability(intType, true);
stringType = typeFactory.createSqlType(SqlTypeName.VARCHAR, 20);
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/test/java/org/eigenbase/test/SqlLimitsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/eigenbase/test/SqlLimitsTest.java b/core/src/test/java/org/eigenbase/test/SqlLimitsTest.java
index e122148..cbc2ce2 100644
--- a/core/src/test/java/org/eigenbase/test/SqlLimitsTest.java
+++ b/core/src/test/java/org/eigenbase/test/SqlLimitsTest.java
@@ -20,10 +20,15 @@ import java.io.*;
import java.text.*;
import java.util.*;
+import org.eigenbase.reltype.RelDataType;
+import org.eigenbase.reltype.RelDataTypeFactory;
+import org.eigenbase.reltype.RelDataTypeSystem;
import org.eigenbase.sql.*;
import org.eigenbase.sql.parser.*;
import org.eigenbase.sql.type.*;
+import net.hydromatic.optiq.jdbc.JavaTypeFactoryImpl;
+
import com.google.common.collect.ImmutableList;
import org.junit.BeforeClass;
@@ -35,33 +40,6 @@ import org.junit.Test;
public class SqlLimitsTest {
//~ Static fields/initializers ---------------------------------------------
- private static final List<BasicSqlType> TYPE_LIST =
- ImmutableList.of(
- new BasicSqlType(SqlTypeName.BOOLEAN),
- new BasicSqlType(SqlTypeName.TINYINT),
- new BasicSqlType(SqlTypeName.SMALLINT),
- new BasicSqlType(SqlTypeName.INTEGER),
- new BasicSqlType(SqlTypeName.BIGINT),
- new BasicSqlType(SqlTypeName.DECIMAL),
- new BasicSqlType(SqlTypeName.DECIMAL, 5),
- new BasicSqlType(SqlTypeName.DECIMAL, 6, 2),
- new BasicSqlType(SqlTypeName.DECIMAL,
- SqlTypeName.DECIMAL.getMaxPrecision(), 0),
- new BasicSqlType(SqlTypeName.DECIMAL,
- SqlTypeName.DECIMAL.getMaxPrecision(), 5),
-
- // todo: test IntervalDayTime and IntervalYearMonth
- // todo: test Float, Real, Double
-
- new BasicSqlType(SqlTypeName.CHAR, 5),
- new BasicSqlType(SqlTypeName.VARCHAR, 1),
- new BasicSqlType(SqlTypeName.VARCHAR, 20),
- new BasicSqlType(SqlTypeName.BINARY, 3),
- new BasicSqlType(SqlTypeName.VARBINARY, 4),
- new BasicSqlType(SqlTypeName.DATE),
- new BasicSqlType(SqlTypeName.TIME, 0),
- new BasicSqlType(SqlTypeName.TIMESTAMP, 0));
-
//~ Constructors -----------------------------------------------------------
public SqlLimitsTest() {
@@ -73,11 +51,33 @@ public class SqlLimitsTest {
return DiffRepository.lookup(SqlLimitsTest.class);
}
- /**
- * Returns a list of typical types.
- */
- public static List<BasicSqlType> getTypes() {
- return TYPE_LIST;
+ /** Returns a list of typical types. */
+ public static List<RelDataType> getTypes(RelDataTypeFactory typeFactory) {
+ final int maxPrecision =
+ typeFactory.getTypeSystem().getMaxPrecision(SqlTypeName.DECIMAL);
+ return ImmutableList.of(
+ typeFactory.createSqlType(SqlTypeName.BOOLEAN),
+ typeFactory.createSqlType(SqlTypeName.TINYINT),
+ typeFactory.createSqlType(SqlTypeName.SMALLINT),
+ typeFactory.createSqlType(SqlTypeName.INTEGER),
+ typeFactory.createSqlType(SqlTypeName.BIGINT),
+ typeFactory.createSqlType(SqlTypeName.DECIMAL),
+ typeFactory.createSqlType(SqlTypeName.DECIMAL, 5),
+ typeFactory.createSqlType(SqlTypeName.DECIMAL, 6, 2),
+ typeFactory.createSqlType(SqlTypeName.DECIMAL, maxPrecision, 0),
+ typeFactory.createSqlType(SqlTypeName.DECIMAL, maxPrecision, 5),
+
+ // todo: test IntervalDayTime and IntervalYearMonth
+ // todo: test Float, Real, Double
+
+ typeFactory.createSqlType(SqlTypeName.CHAR, 5),
+ typeFactory.createSqlType(SqlTypeName.VARCHAR, 1),
+ typeFactory.createSqlType(SqlTypeName.VARCHAR, 20),
+ typeFactory.createSqlType(SqlTypeName.BINARY, 3),
+ typeFactory.createSqlType(SqlTypeName.VARBINARY, 4),
+ typeFactory.createSqlType(SqlTypeName.DATE),
+ typeFactory.createSqlType(SqlTypeName.TIME, 0),
+ typeFactory.createSqlType(SqlTypeName.TIMESTAMP, 0));
}
@BeforeClass public static void setUSLocale() {
@@ -89,7 +89,9 @@ public class SqlLimitsTest {
@Test public void testPrintLimits() {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
- for (BasicSqlType type : TYPE_LIST) {
+ final List<RelDataType> types =
+ getTypes(new JavaTypeFactoryImpl(RelDataTypeSystem.DEFAULT));
+ for (RelDataType type : types) {
pw.println(type.toString());
printLimit(
pw,
@@ -163,11 +165,11 @@ public class SqlLimitsTest {
private void printLimit(
PrintWriter pw,
String desc,
- BasicSqlType type,
+ RelDataType type,
boolean sign,
SqlTypeName.Limit limit,
boolean beyond) {
- Object o = type.getLimit(sign, limit, beyond);
+ Object o = ((BasicSqlType) type).getLimit(sign, limit, beyond);
if (o == null) {
return;
}
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/test/java/org/eigenbase/test/SqlToRelTestBase.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/eigenbase/test/SqlToRelTestBase.java b/core/src/test/java/org/eigenbase/test/SqlToRelTestBase.java
index 9c22703..52cec3b 100644
--- a/core/src/test/java/org/eigenbase/test/SqlToRelTestBase.java
+++ b/core/src/test/java/org/eigenbase/test/SqlToRelTestBase.java
@@ -480,7 +480,7 @@ public abstract class SqlToRelTestBase {
}
protected RelDataTypeFactory createTypeFactory() {
- return new SqlTypeFactoryImpl();
+ return new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
}
protected final RelOptPlanner getPlanner() {
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/test/java/org/eigenbase/test/SqlValidatorFeatureTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/eigenbase/test/SqlValidatorFeatureTest.java b/core/src/test/java/org/eigenbase/test/SqlValidatorFeatureTest.java
index e4e58f0..bcc553e 100644
--- a/core/src/test/java/org/eigenbase/test/SqlValidatorFeatureTest.java
+++ b/core/src/test/java/org/eigenbase/test/SqlValidatorFeatureTest.java
@@ -124,7 +124,8 @@ public class SqlValidatorFeatureTest extends SqlValidatorTestCase {
@Override
public SqlValidator getValidator(SqlTestFactory factory) {
- final RelDataTypeFactory typeFactory = new SqlTypeFactoryImpl();
+ final RelDataTypeFactory typeFactory =
+ new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
SqlConformance conformance = (SqlConformance) get("conformance");
final boolean caseSensitive = (Boolean) get("caseSensitive");
return new FeatureValidator(
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/test/java/org/eigenbase/test/SqlValidatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/eigenbase/test/SqlValidatorTest.java b/core/src/test/java/org/eigenbase/test/SqlValidatorTest.java
index 3bb6beb..1cb6108 100644
--- a/core/src/test/java/org/eigenbase/test/SqlValidatorTest.java
+++ b/core/src/test/java/org/eigenbase/test/SqlValidatorTest.java
@@ -22,6 +22,7 @@ import java.util.List;
import java.util.Locale;
import java.util.logging.*;
+import org.eigenbase.reltype.RelDataTypeSystem;
import org.eigenbase.sql.*;
import org.eigenbase.sql.fun.SqlStdOperatorTable;
import org.eigenbase.sql.test.SqlTester;
@@ -3409,6 +3410,8 @@ public class SqlValidatorTest extends SqlValidatorTestCase {
// First check that min, max, and defaults are what we expect
// (values used in subtests depend on these being true to
// accurately test bounds)
+ final RelDataTypeSystem typeSystem =
+ getTester().getValidator().getTypeFactory().getTypeSystem();
assertTrue(
SqlTypeName.INTERVAL_YEAR_MONTH.getMinPrecision() == 1);
assertTrue(
@@ -3417,18 +3420,16 @@ public class SqlValidatorTest extends SqlValidatorTestCase {
SqlTypeName.INTERVAL_YEAR_MONTH.getMaxPrecision() == 10);
assertTrue(
SqlTypeName.INTERVAL_DAY_TIME.getMaxPrecision() == 10);
- assertTrue(
- SqlTypeName.INTERVAL_YEAR_MONTH.getDefaultPrecision() == 2);
- assertTrue(
- SqlTypeName.INTERVAL_DAY_TIME.getDefaultPrecision() == 2);
+ assertEquals(2,
+ typeSystem.getDefaultPrecision(SqlTypeName.INTERVAL_YEAR_MONTH));
+ assertEquals(2,
+ typeSystem.getDefaultPrecision(SqlTypeName.INTERVAL_DAY_TIME));
assertTrue(
SqlTypeName.INTERVAL_YEAR_MONTH.getMinScale() == 1);
assertTrue(
SqlTypeName.INTERVAL_DAY_TIME.getMinScale() == 1);
- assertTrue(
- SqlTypeName.INTERVAL_YEAR_MONTH.getMaxScale() == 9);
- assertTrue(
- SqlTypeName.INTERVAL_DAY_TIME.getMaxScale() == 9);
+ assertEquals(9, typeSystem.getMaxScale(SqlTypeName.INTERVAL_YEAR_MONTH));
+ assertEquals(9, typeSystem.getMaxScale(SqlTypeName.INTERVAL_DAY_TIME));
assertTrue(
SqlTypeName.INTERVAL_YEAR_MONTH.getDefaultScale() == 6);
assertTrue(
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/test/resources/org/eigenbase/test/SqlLimitsTest.xml
----------------------------------------------------------------------
diff --git a/core/src/test/resources/org/eigenbase/test/SqlLimitsTest.xml b/core/src/test/resources/org/eigenbase/test/SqlLimitsTest.xml
index 0ea34eb..956e51f 100644
--- a/core/src/test/resources/org/eigenbase/test/SqlLimitsTest.xml
+++ b/core/src/test/resources/org/eigenbase/test/SqlLimitsTest.xml
@@ -16,9 +16,9 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<Root>
- <TestCase name="testPrintLimits">
- <Resource name="output">
- <![CDATA[BOOLEAN
+ <TestCase name="testPrintLimits">
+ <Resource name="output">
+ <![CDATA[BOOLEAN
zero: false; as SQL: FALSE
max: true; as SQL: TRUE
@@ -58,7 +58,7 @@ BIGINT
max: 9223372036854775807; as SQL: 9223372036854775807
max + epsilon: 9223372036854775808; as SQL: 9223372036854775808
-DECIMAL
+DECIMAL(19, 0)
min - epsilon: -9223372036854775809; as SQL: -9223372036854775809
min: -9223372036854775808; as SQL: -9223372036854775808
zero - delta: -1; as SQL: -1
@@ -67,7 +67,7 @@ DECIMAL
max: 9223372036854775807; as SQL: 9223372036854775807
max + epsilon: 9223372036854775808; as SQL: 9223372036854775808
-DECIMAL(5)
+DECIMAL(5, 0)
min - epsilon: -100000; as SQL: -100000
min: -99999; as SQL: -99999
zero - delta: -1; as SQL: -1
@@ -148,6 +148,6 @@ TIMESTAMP(0)
max: Dec 31, 9999 11:59:59 PM; as SQL: TIMESTAMP '9999-12-31 23:59:59'
]]>
- </Resource>
- </TestCase>
+ </Resource>
+ </TestCase>
</Root>
[2/2] git commit: [OPTIQ-413] Add RelDataTypeSystem plugin,
allowing different max precision of a DECIMAL
Posted by jh...@apache.org.
[OPTIQ-413] Add RelDataTypeSystem plugin, allowing different max precision of a DECIMAL
Project: http://git-wip-us.apache.org/repos/asf/incubator-optiq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-optiq/commit/0fd4e3d9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-optiq/tree/0fd4e3d9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-optiq/diff/0fd4e3d9
Branch: refs/heads/master
Commit: 0fd4e3d9ea63fa67a97ea8ba73e46a12e31af2b1
Parents: a2cc356
Author: Julian Hyde <jh...@apache.org>
Authored: Thu Sep 18 12:05:22 2014 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Thu Sep 18 17:33:14 2014 -0700
----------------------------------------------------------------------
.../avatica/ConnectionConfigImpl.java | 59 +++++
.../hydromatic/avatica/ConnectionProperty.java | 4 +-
.../main/codegen/templates/CombinedParser.jj | 5 +-
.../optiq/config/OptiqConnectionConfig.java | 2 +
.../optiq/config/OptiqConnectionConfigImpl.java | 5 +
.../optiq/config/OptiqConnectionProperty.java | 7 +-
.../hydromatic/optiq/impl/jdbc/JdbcSchema.java | 3 +-
.../optiq/jdbc/JavaTypeFactoryImpl.java | 10 +-
.../optiq/jdbc/OptiqConnectionImpl.java | 12 +-
.../optiq/rules/java/RexToLixTranslator.java | 4 +-
.../hydromatic/optiq/tools/FrameworkConfig.java | 8 +
.../net/hydromatic/optiq/tools/Frameworks.java | 28 +-
.../eigenbase/rel/rules/ReduceDecimalsRule.java | 44 +++-
.../eigenbase/reltype/RelDataTypeFactory.java | 5 +
.../reltype/RelDataTypeFactoryImpl.java | 30 ++-
.../eigenbase/reltype/RelDataTypeSystem.java | 60 +++++
.../reltype/RelDataTypeSystemImpl.java | 98 +++++++
.../main/java/org/eigenbase/rex/RexBuilder.java | 9 +-
.../java/org/eigenbase/rex/RexExecutorImpl.java | 3 +-
.../org/eigenbase/sql/SqlIntervalQualifier.java | 258 ++++++++++---------
.../eigenbase/sql/SqlUnresolvedFunction.java | 6 +-
.../org/eigenbase/sql/parser/SqlParserUtil.java | 5 +-
.../org/eigenbase/sql/type/BasicSqlType.java | 41 +--
.../org/eigenbase/sql/type/IntervalSqlType.java | 45 ++--
.../org/eigenbase/sql/type/ReturnTypes.java | 18 +-
.../eigenbase/sql/type/SqlTypeFactoryImpl.java | 32 ++-
.../org/eigenbase/sql/type/SqlTypeName.java | 72 ++----
.../sql/validate/SqlValidatorImpl.java | 48 ++--
.../eigenbase/sql2rel/SqlToRelConverter.java | 11 +-
.../optiq/impl/clone/ArrayTableTest.java | 7 +-
.../optiq/test/MaterializationTest.java | 4 +-
.../hydromatic/optiq/tools/FrameworksTest.java | 68 +++++
.../org/eigenbase/relopt/RelOptUtilTest.java | 3 +-
.../relopt/volcano/VolcanoPlannerTest.java | 3 +-
.../sql/test/DefaultSqlTestFactory.java | 4 +-
.../org/eigenbase/sql/test/SqlAdvisorTest.java | 6 +-
.../eigenbase/sql/test/SqlOperatorBaseTest.java | 13 +-
.../java/org/eigenbase/test/RexProgramTest.java | 2 +-
.../org/eigenbase/test/RexTransformerTest.java | 2 +-
.../test/java/org/eigenbase/test/SargTest.java | 3 +-
.../java/org/eigenbase/test/SqlLimitsTest.java | 72 +++---
.../org/eigenbase/test/SqlToRelTestBase.java | 2 +-
.../eigenbase/test/SqlValidatorFeatureTest.java | 3 +-
.../org/eigenbase/test/SqlValidatorTest.java | 17 +-
.../org/eigenbase/test/SqlLimitsTest.xml | 14 +-
45 files changed, 775 insertions(+), 380 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/avatica/src/main/java/net/hydromatic/avatica/ConnectionConfigImpl.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/net/hydromatic/avatica/ConnectionConfigImpl.java b/avatica/src/main/java/net/hydromatic/avatica/ConnectionConfigImpl.java
index 89066eb..f406da2 100644
--- a/avatica/src/main/java/net/hydromatic/avatica/ConnectionConfigImpl.java
+++ b/avatica/src/main/java/net/hydromatic/avatica/ConnectionConfigImpl.java
@@ -16,6 +16,7 @@
*/
package net.hydromatic.avatica;
+import java.lang.reflect.Field;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
@@ -123,6 +124,31 @@ public class ConnectionConfigImpl implements ConnectionConfig {
//noinspection unchecked
return get_(enumConverter(enumClass), defaultValue.name());
}
+
+ /** Returns an instance of a plugin.
+ *
+ * <p>Throws if not set and no default.
+ * Also throws if the class does not implement the required interface,
+ * or if it does not have a public default constructor or an public static
+ * field called {@code #INSTANCE}. */
+ public <T> T getPlugin(Class<T> pluginClass, T defaultInstance) {
+ return getPlugin(pluginClass, (String) property.defaultValue(),
+ defaultInstance);
+ }
+
+ /** Returns an instance of a plugin, using a given class name if none is
+ * set.
+ *
+ * <p>Throws if not set and no default.
+ * Also throws if the class does not implement the required interface,
+ * or if it does not have a public default constructor or an public static
+ * field called {@code #INSTANCE}. */
+ public <T> T getPlugin(Class<T> pluginClass, String defaultClassName,
+ T defaultInstance) {
+ assert property.type() == ConnectionProperty.Type.PLUGIN;
+ return get_(pluginConverter(pluginClass, defaultInstance),
+ defaultClassName);
+ }
}
/** Callback to parse a property from string to its native type. */
@@ -165,6 +191,39 @@ public class ConnectionConfigImpl implements ConnectionConfig {
}
};
}
+
+ public static <T> Converter<T> pluginConverter(final Class<T> pluginClass,
+ final T defaultInstance) {
+ return new Converter<T>() {
+ public T apply(ConnectionProperty connectionProperty, String s) {
+ if (s == null) {
+ if (defaultInstance != null) {
+ return defaultInstance;
+ }
+ throw new RuntimeException("Required property '"
+ + connectionProperty.camelName() + "' not specified");
+ }
+ // First look for a C.INSTANCE field, then do new C().
+ try {
+ //noinspection unchecked
+ final Class<T> clazz = (Class) Class.forName(s);
+ assert pluginClass.isAssignableFrom(clazz);
+ try {
+ // We assume that if there is an INSTANCE field it is static and
+ // has the right type.
+ final Field field = clazz.getField("INSTANCE");
+ return pluginClass.cast(field.get(null));
+ } catch (NoSuchFieldException e) {
+ // ignore
+ }
+ return clazz.newInstance();
+ } catch (Exception e) {
+ throw new RuntimeException("Property '" + s
+ + "' not valid for plugin type " + pluginClass.getName(), e);
+ }
+ }
+ };
+ }
}
// End ConnectionConfigImpl.java
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/avatica/src/main/java/net/hydromatic/avatica/ConnectionProperty.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/net/hydromatic/avatica/ConnectionProperty.java b/avatica/src/main/java/net/hydromatic/avatica/ConnectionProperty.java
index 2dda49a..5fcdc50 100644
--- a/avatica/src/main/java/net/hydromatic/avatica/ConnectionProperty.java
+++ b/avatica/src/main/java/net/hydromatic/avatica/ConnectionProperty.java
@@ -46,13 +46,15 @@ public interface ConnectionProperty {
enum Type {
BOOLEAN,
STRING,
- ENUM;
+ ENUM,
+ PLUGIN;
public boolean valid(Object defaultValue) {
switch (this) {
case BOOLEAN:
return defaultValue instanceof Boolean;
case STRING:
+ case PLUGIN:
return defaultValue instanceof String;
default:
return defaultValue instanceof Enum;
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/codegen/templates/CombinedParser.jj
----------------------------------------------------------------------
diff --git a/core/src/main/codegen/templates/CombinedParser.jj b/core/src/main/codegen/templates/CombinedParser.jj
index 6e3101b..2ccad91 100644
--- a/core/src/main/codegen/templates/CombinedParser.jj
+++ b/core/src/main/codegen/templates/CombinedParser.jj
@@ -33,6 +33,7 @@ package ${parser.package};
import ${importStr};
</#list>
+import org.eigenbase.reltype.RelDataType;
import org.eigenbase.sql.*;
import org.eigenbase.sql.parser.*;
import org.eigenbase.sql.fun.*;
@@ -3118,8 +3119,8 @@ SqlIntervalQualifier IntervalQualifier() :
{
SqlIntervalQualifier.TimeUnit start;
SqlIntervalQualifier.TimeUnit end = null;
- int startPrec = SqlIntervalQualifier.getDefaultPrecisionId();
- int secondFracPrec = SqlIntervalQualifier.getDefaultPrecisionId();
+ int startPrec = RelDataType.PRECISION_NOT_SPECIFIED;
+ int secondFracPrec = RelDataType.PRECISION_NOT_SPECIFIED;
}
{
(
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/net/hydromatic/optiq/config/OptiqConnectionConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/net/hydromatic/optiq/config/OptiqConnectionConfig.java b/core/src/main/java/net/hydromatic/optiq/config/OptiqConnectionConfig.java
index a8a49ab..304a3cb 100644
--- a/core/src/main/java/net/hydromatic/optiq/config/OptiqConnectionConfig.java
+++ b/core/src/main/java/net/hydromatic/optiq/config/OptiqConnectionConfig.java
@@ -44,6 +44,8 @@ public interface OptiqConnectionConfig extends ConnectionConfig {
boolean caseSensitive();
/** @see net.hydromatic.optiq.config.OptiqConnectionProperty#SPARK */
boolean spark();
+ /** @see net.hydromatic.optiq.config.OptiqConnectionProperty#TYPE_SYSTEM */
+ <T> T typeSystem(Class<T> typeSystemClass, T defaultTypeSystem);
}
// End OptiqConnectionConfig.java
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/net/hydromatic/optiq/config/OptiqConnectionConfigImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/net/hydromatic/optiq/config/OptiqConnectionConfigImpl.java b/core/src/main/java/net/hydromatic/optiq/config/OptiqConnectionConfigImpl.java
index 719f33b..f08cc7c 100644
--- a/core/src/main/java/net/hydromatic/optiq/config/OptiqConnectionConfigImpl.java
+++ b/core/src/main/java/net/hydromatic/optiq/config/OptiqConnectionConfigImpl.java
@@ -82,6 +82,11 @@ public class OptiqConnectionConfigImpl extends ConnectionConfigImpl
public boolean spark() {
return OptiqConnectionProperty.SPARK.wrap(properties).getBoolean();
}
+
+ public <T> T typeSystem(Class<T> typeSystemClass, T defaultTypeSystem) {
+ return OptiqConnectionProperty.TYPE_SYSTEM.wrap(properties)
+ .getPlugin(typeSystemClass, defaultTypeSystem);
+ }
}
// End OptiqConnectionConfigImpl.java
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/net/hydromatic/optiq/config/OptiqConnectionProperty.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/net/hydromatic/optiq/config/OptiqConnectionProperty.java b/core/src/main/java/net/hydromatic/optiq/config/OptiqConnectionProperty.java
index ba3089c..5f2d85c 100644
--- a/core/src/main/java/net/hydromatic/optiq/config/OptiqConnectionProperty.java
+++ b/core/src/main/java/net/hydromatic/optiq/config/OptiqConnectionProperty.java
@@ -68,7 +68,12 @@ public enum OptiqConnectionProperty implements ConnectionProperty {
SPARK("spark", Type.BOOLEAN, false),
/** Timezone, for example 'gmt-3'. Default is the JVM's time zone. */
- TIMEZONE("timezone", Type.STRING, null);
+ TIMEZONE("timezone", Type.STRING, null),
+
+ /** Type system. The name of a class that implements
+ * {@code org.eigenbase.reltype.RelDataTypeSystem} and has a public default
+ * constructor or an {@code INSTANCE} constant. */
+ TYPE_SYSTEM("typeSystem", Type.PLUGIN, null);
private final String camelName;
private final Type type;
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/net/hydromatic/optiq/impl/jdbc/JdbcSchema.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/net/hydromatic/optiq/impl/jdbc/JdbcSchema.java b/core/src/main/java/net/hydromatic/optiq/impl/jdbc/JdbcSchema.java
index b1940df..0301489 100644
--- a/core/src/main/java/net/hydromatic/optiq/impl/jdbc/JdbcSchema.java
+++ b/core/src/main/java/net/hydromatic/optiq/impl/jdbc/JdbcSchema.java
@@ -240,7 +240,8 @@ public class JdbcSchema implements Schema {
// Temporary type factory, just for the duration of this method. Allowable
// because we're creating a proto-type, not a type; before being used, the
// proto-type will be copied into a real type factory.
- final RelDataTypeFactory typeFactory = new SqlTypeFactoryImpl();
+ final RelDataTypeFactory typeFactory =
+ new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
final RelDataTypeFactory.FieldInfoBuilder fieldInfo = typeFactory.builder();
while (resultSet.next()) {
final String columnName = resultSet.getString(4);
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/net/hydromatic/optiq/jdbc/JavaTypeFactoryImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/net/hydromatic/optiq/jdbc/JavaTypeFactoryImpl.java b/core/src/main/java/net/hydromatic/optiq/jdbc/JavaTypeFactoryImpl.java
index 3202221..67fb093 100644
--- a/core/src/main/java/net/hydromatic/optiq/jdbc/JavaTypeFactoryImpl.java
+++ b/core/src/main/java/net/hydromatic/optiq/jdbc/JavaTypeFactoryImpl.java
@@ -53,6 +53,14 @@ public class JavaTypeFactoryImpl
syntheticTypes =
new HashMap<List<Pair<Type, Boolean>>, SyntheticRecordType>();
+ public JavaTypeFactoryImpl() {
+ this(RelDataTypeSystem.DEFAULT);
+ }
+
+ public JavaTypeFactoryImpl(RelDataTypeSystem typeSystem) {
+ super(typeSystem);
+ }
+
public RelDataType createStructType(Class type) {
List<RelDataTypeField> list = new ArrayList<RelDataTypeField>();
for (Field field : type.getFields()) {
@@ -178,7 +186,7 @@ public class JavaTypeFactoryImpl
}
if (type instanceof JavaType) {
return createTypeWithNullability(
- new BasicSqlType(type.getSqlTypeName()),
+ createSqlType(type.getSqlTypeName()),
type.isNullable());
}
return type;
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/net/hydromatic/optiq/jdbc/OptiqConnectionImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/net/hydromatic/optiq/jdbc/OptiqConnectionImpl.java b/core/src/main/java/net/hydromatic/optiq/jdbc/OptiqConnectionImpl.java
index d5c8592..80d77d3 100644
--- a/core/src/main/java/net/hydromatic/optiq/jdbc/OptiqConnectionImpl.java
+++ b/core/src/main/java/net/hydromatic/optiq/jdbc/OptiqConnectionImpl.java
@@ -35,6 +35,7 @@ import net.hydromatic.optiq.runtime.Hook;
import net.hydromatic.optiq.server.OptiqServer;
import net.hydromatic.optiq.server.OptiqServerStatement;
+import org.eigenbase.reltype.RelDataTypeSystem;
import org.eigenbase.sql.advise.SqlAdvisor;
import org.eigenbase.sql.advise.SqlAdvisorValidator;
import org.eigenbase.sql.fun.SqlStdOperatorTable;
@@ -83,13 +84,18 @@ abstract class OptiqConnectionImpl
String url, Properties info, OptiqRootSchema rootSchema,
JavaTypeFactory typeFactory) {
super(driver, factory, url, info);
+ OptiqConnectionConfig cfg = new OptiqConnectionConfigImpl(info);
this.prepareFactory = driver.prepareFactory;
- this.typeFactory =
- typeFactory != null ? typeFactory : new JavaTypeFactoryImpl();
+ if (typeFactory != null) {
+ this.typeFactory = typeFactory;
+ } else {
+ final RelDataTypeSystem typeSystem =
+ cfg.typeSystem(RelDataTypeSystem.class, RelDataTypeSystem.DEFAULT);
+ this.typeFactory = new JavaTypeFactoryImpl(typeSystem);
+ }
this.rootSchema =
rootSchema != null ? rootSchema : OptiqSchema.createRootSchema(true);
- OptiqConnectionConfig cfg = new OptiqConnectionConfigImpl(info);
this.properties.put(InternalProperty.CASE_SENSITIVE, cfg.caseSensitive());
this.properties.put(InternalProperty.UNQUOTED_CASING, cfg.unquotedCasing());
this.properties.put(InternalProperty.QUOTED_CASING, cfg.quotedCasing());
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/net/hydromatic/optiq/rules/java/RexToLixTranslator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/net/hydromatic/optiq/rules/java/RexToLixTranslator.java b/core/src/main/java/net/hydromatic/optiq/rules/java/RexToLixTranslator.java
index 369f9b1..4c13cfd 100644
--- a/core/src/main/java/net/hydromatic/optiq/rules/java/RexToLixTranslator.java
+++ b/core/src/main/java/net/hydromatic/optiq/rules/java/RexToLixTranslator.java
@@ -251,7 +251,9 @@ public class RexToLixTranslator {
BuiltinMethod.INTERVAL_DAY_TIME_TO_STRING.method,
operand,
Expressions.constant(interval.foo()),
- Expressions.constant(interval.getFractionalSecondPrecision())));
+ Expressions.constant(
+ interval.getFractionalSecondPrecision(
+ typeFactory.getTypeSystem()))));
break;
case BOOLEAN:
convert = RexImpTable.optimize2(
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/net/hydromatic/optiq/tools/FrameworkConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/net/hydromatic/optiq/tools/FrameworkConfig.java b/core/src/main/java/net/hydromatic/optiq/tools/FrameworkConfig.java
index 4e9cd84..98d0739 100644
--- a/core/src/main/java/net/hydromatic/optiq/tools/FrameworkConfig.java
+++ b/core/src/main/java/net/hydromatic/optiq/tools/FrameworkConfig.java
@@ -22,6 +22,7 @@ import net.hydromatic.optiq.config.Lex;
import org.eigenbase.relopt.Context;
import org.eigenbase.relopt.RelOptCostFactory;
import org.eigenbase.relopt.RelTraitDef;
+import org.eigenbase.reltype.RelDataTypeSystem;
import org.eigenbase.sql.SqlOperatorTable;
import org.eigenbase.sql.parser.SqlParserImplFactory;
import org.eigenbase.sql2rel.SqlRexConvertletTable;
@@ -31,6 +32,8 @@ import com.google.common.collect.ImmutableList;
/**
* Interface that describes how to configure planning sessions generated
* using the Frameworks tools.
+ *
+ * @see Frameworks#newConfigBuilder()
*/
public interface FrameworkConfig {
/**
@@ -107,6 +110,11 @@ public interface FrameworkConfig {
* calling {@link org.eigenbase.relopt.RelOptPlanner#getContext()}.
*/
Context getContext();
+
+ /**
+ * Returns the type system.
+ */
+ RelDataTypeSystem getTypeSystem();
}
// End FrameworkConfig.java
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/net/hydromatic/optiq/tools/Frameworks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/net/hydromatic/optiq/tools/Frameworks.java b/core/src/main/java/net/hydromatic/optiq/tools/Frameworks.java
index d08c29c..62b6f3f 100644
--- a/core/src/main/java/net/hydromatic/optiq/tools/Frameworks.java
+++ b/core/src/main/java/net/hydromatic/optiq/tools/Frameworks.java
@@ -18,6 +18,7 @@ package net.hydromatic.optiq.tools;
import net.hydromatic.optiq.SchemaPlus;
import net.hydromatic.optiq.config.Lex;
+import net.hydromatic.optiq.config.OptiqConnectionProperty;
import net.hydromatic.optiq.jdbc.OptiqConnection;
import net.hydromatic.optiq.jdbc.OptiqSchema;
import net.hydromatic.optiq.prepare.OptiqPrepareImpl;
@@ -29,6 +30,7 @@ import org.eigenbase.relopt.RelOptCluster;
import org.eigenbase.relopt.RelOptCostFactory;
import org.eigenbase.relopt.RelOptSchema;
import org.eigenbase.relopt.RelTraitDef;
+import org.eigenbase.reltype.RelDataTypeSystem;
import org.eigenbase.sql.SqlOperatorTable;
import org.eigenbase.sql.fun.SqlStdOperatorTable;
import org.eigenbase.sql.parser.SqlParserImplFactory;
@@ -42,6 +44,7 @@ import com.google.common.collect.ImmutableList;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.List;
+import java.util.Properties;
/**
* Tools for invoking Optiq functionality without initializing a container /
@@ -134,8 +137,13 @@ public class Frameworks {
public static <R> R withPrepare(PrepareAction<R> action) {
try {
Class.forName("net.hydromatic.optiq.jdbc.Driver");
+ final Properties info = new Properties();
+ if (action.config.getTypeSystem() != RelDataTypeSystem.DEFAULT) {
+ info.setProperty(OptiqConnectionProperty.TYPE_SYSTEM.camelName(),
+ action.config.getTypeSystem().getClass().getName());
+ }
Connection connection =
- DriverManager.getConnection("jdbc:optiq:");
+ DriverManager.getConnection("jdbc:optiq:", info);
OptiqConnection optiqConnection =
connection.unwrap(OptiqConnection.class);
final OptiqServerStatement statement =
@@ -175,12 +183,14 @@ public class Frameworks {
private SchemaPlus defaultSchema;
private RelOptCostFactory costFactory;
private SqlParserImplFactory parserFactory = SqlParserImpl.FACTORY;
+ private RelDataTypeSystem typeSystem = RelDataTypeSystem.DEFAULT;
private ConfigBuilder() {}
public FrameworkConfig build() {
return new StdFrameworkConfig(context, convertletTable, operatorTable,
- programs, traitDefs, lex, defaultSchema, costFactory, parserFactory);
+ programs, traitDefs, lex, defaultSchema, costFactory, parserFactory,
+ typeSystem);
}
public ConfigBuilder context(Context c) {
@@ -250,6 +260,11 @@ public class Frameworks {
this.parserFactory = Preconditions.checkNotNull(parserFactory);
return this;
}
+
+ public ConfigBuilder typeSystem(RelDataTypeSystem typeSystem) {
+ this.typeSystem = Preconditions.checkNotNull(typeSystem);
+ return this;
+ }
}
/**
@@ -266,6 +281,7 @@ public class Frameworks {
private final SchemaPlus defaultSchema;
private final RelOptCostFactory costFactory;
private final SqlParserImplFactory parserFactory;
+ private final RelDataTypeSystem typeSystem;
public StdFrameworkConfig(Context context,
SqlRexConvertletTable convertletTable,
@@ -275,7 +291,8 @@ public class Frameworks {
Lex lex,
SchemaPlus defaultSchema,
RelOptCostFactory costFactory,
- SqlParserImplFactory parserFactory) {
+ SqlParserImplFactory parserFactory,
+ RelDataTypeSystem typeSystem) {
this.context = context;
this.convertletTable = convertletTable;
this.operatorTable = operatorTable;
@@ -285,6 +302,7 @@ public class Frameworks {
this.defaultSchema = defaultSchema;
this.costFactory = costFactory;
this.parserFactory = parserFactory;
+ this.typeSystem = typeSystem;
}
public Lex getLex() {
@@ -322,6 +340,10 @@ public class Frameworks {
public SqlOperatorTable getOperatorTable() {
return operatorTable;
}
+
+ public RelDataTypeSystem getTypeSystem() {
+ return typeSystem;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/org/eigenbase/rel/rules/ReduceDecimalsRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/rules/ReduceDecimalsRule.java b/core/src/main/java/org/eigenbase/rel/rules/ReduceDecimalsRule.java
index 1a9325d..d89561d 100644
--- a/core/src/main/java/org/eigenbase/rel/rules/ReduceDecimalsRule.java
+++ b/core/src/main/java/org/eigenbase/rel/rules/ReduceDecimalsRule.java
@@ -336,7 +336,9 @@ public class ReduceDecimalsRule extends RelOptRule {
* @return 10^scale as an exact numeric value
*/
protected RexNode makeScaleFactor(int scale) {
- assert (scale > 0) && (scale < SqlTypeName.MAX_NUMERIC_PRECISION);
+ assert scale > 0;
+ assert scale
+ < builder.getTypeFactory().getTypeSystem().getMaxNumericPrecision();
return makeExactLiteral(powerOfTen(scale));
}
@@ -364,7 +366,9 @@ public class ReduceDecimalsRule extends RelOptRule {
* @return 10^scale / 2 as an exact numeric value
*/
protected RexNode makeRoundFactor(int scale) {
- assert (scale > 0) && (scale < SqlTypeName.MAX_NUMERIC_PRECISION);
+ assert scale > 0;
+ assert scale
+ < builder.getTypeFactory().getTypeSystem().getMaxNumericPrecision();
return makeExactLiteral(powerOfTen(scale) / 2);
}
@@ -372,7 +376,9 @@ public class ReduceDecimalsRule extends RelOptRule {
* Calculates a power of ten, as a long value
*/
protected long powerOfTen(int scale) {
- assert (scale >= 0) && (scale < SqlTypeName.MAX_NUMERIC_PRECISION);
+ assert scale >= 0;
+ assert scale
+ < builder.getTypeFactory().getTypeSystem().getMaxNumericPrecision();
return BigInteger.TEN.pow(scale).longValue();
}
@@ -400,7 +406,9 @@ public class ReduceDecimalsRule extends RelOptRule {
* @return value * 10^scale as an exact numeric value
*/
protected RexNode scaleUp(RexNode value, int scale) {
- assert (scale >= 0) && (scale < SqlTypeName.MAX_NUMERIC_PRECISION);
+ assert scale >= 0;
+ assert scale
+ < builder.getTypeFactory().getTypeSystem().getMaxNumericPrecision();
if (scale == 0) {
return value;
}
@@ -422,8 +430,9 @@ public class ReduceDecimalsRule extends RelOptRule {
* exact numeric value
*/
protected RexNode scaleDown(RexNode value, int scale) {
- int maxPrecision = SqlTypeName.MAX_NUMERIC_PRECISION;
- assert (scale >= 0) && (scale <= maxPrecision);
+ final int maxPrecision =
+ builder.getTypeFactory().getTypeSystem().getMaxNumericPrecision();
+ assert scale >= 0 && scale <= maxPrecision;
if (scale == 0) {
return value;
}
@@ -462,12 +471,13 @@ public class ReduceDecimalsRule extends RelOptRule {
* double precision arithmetic.
*
* @param value the integer representation of a decimal
- * @param scale a value from zero to {@link
- * SqlTypeName#MAX_NUMERIC_PRECISION MAX_NUMERIC_PRECISION}
+ * @param scale a value from zero to max precision
* @return value/10^scale as a double precision value
*/
protected RexNode scaleDownDouble(RexNode value, int scale) {
- assert (scale >= 0) && (scale <= SqlTypeName.MAX_NUMERIC_PRECISION);
+ assert scale >= 0;
+ assert scale
+ <= builder.getTypeFactory().getTypeSystem().getMaxNumericPrecision();
RexNode cast = ensureType(real8, value);
if (scale == 0) {
return cast;
@@ -495,8 +505,10 @@ public class ReduceDecimalsRule extends RelOptRule {
* corresponding to the input value
*/
protected RexNode ensureScale(RexNode value, int scale, int required) {
- int maxPrecision = SqlTypeName.MAX_NUMERIC_PRECISION;
- assert (scale <= maxPrecision) && (required <= maxPrecision);
+ final RelDataTypeSystem typeSystem =
+ builder.getTypeFactory().getTypeSystem();
+ final int maxPrecision = typeSystem.getMaxNumericPrecision();
+ assert scale <= maxPrecision && required <= maxPrecision;
assert required >= scale;
if (scale == required) {
return value;
@@ -509,7 +521,7 @@ public class ReduceDecimalsRule extends RelOptRule {
}
// TODO: make a validator exception for this
- if (scaleDiff >= SqlTypeName.MAX_NUMERIC_PRECISION) {
+ if (scaleDiff >= maxPrecision) {
throw Util.needToImplement(
"Source type with scale " + scale
+ " cannot be converted to target type with scale "
@@ -1002,11 +1014,13 @@ public class ReduceDecimalsRule extends RelOptRule {
RexNode decValue = call.operands.get(0);
int scale = decValue.getType().getScale();
RexNode value = decodeValue(decValue);
+ final RelDataTypeSystem typeSystem =
+ builder.getTypeFactory().getTypeSystem();
RexNode rewrite;
if (scale == 0) {
rewrite = decValue;
- } else if (scale == SqlTypeName.MAX_NUMERIC_PRECISION) {
+ } else if (scale == typeSystem.getMaxNumericPrecision()) {
rewrite =
makeCase(
makeIsNegative(value),
@@ -1049,11 +1063,13 @@ public class ReduceDecimalsRule extends RelOptRule {
RexNode decValue = call.operands.get(0);
int scale = decValue.getType().getScale();
RexNode value = decodeValue(decValue);
+ final RelDataTypeSystem typeSystem =
+ builder.getTypeFactory().getTypeSystem();
RexNode rewrite;
if (scale == 0) {
rewrite = decValue;
- } else if (scale == SqlTypeName.MAX_NUMERIC_PRECISION) {
+ } else if (scale == typeSystem.getMaxNumericPrecision()) {
rewrite =
makeCase(
makeIsPositive(value),
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/org/eigenbase/reltype/RelDataTypeFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/reltype/RelDataTypeFactory.java b/core/src/main/java/org/eigenbase/reltype/RelDataTypeFactory.java
index ab26365..0d9fd06 100644
--- a/core/src/main/java/org/eigenbase/reltype/RelDataTypeFactory.java
+++ b/core/src/main/java/org/eigenbase/reltype/RelDataTypeFactory.java
@@ -40,6 +40,11 @@ public interface RelDataTypeFactory {
//~ Methods ----------------------------------------------------------------
/**
+ * Returns the type system.
+ */
+ RelDataTypeSystem getTypeSystem();
+
+ /**
* Creates a type which corresponds to a Java class.
*
* @param clazz the Java class used to define the type
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/org/eigenbase/reltype/RelDataTypeFactoryImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/reltype/RelDataTypeFactoryImpl.java b/core/src/main/java/org/eigenbase/reltype/RelDataTypeFactoryImpl.java
index db9ceda..80d066c 100644
--- a/core/src/main/java/org/eigenbase/reltype/RelDataTypeFactoryImpl.java
+++ b/core/src/main/java/org/eigenbase/reltype/RelDataTypeFactoryImpl.java
@@ -88,13 +88,30 @@ public abstract class RelDataTypeFactoryImpl implements RelDataTypeFactory {
.put(Timestamp.class, SqlTypeFamily.TIMESTAMP)
.build();
+ protected final RelDataTypeSystem typeSystem;
+
//~ Constructors -----------------------------------------------------------
+ /** Creates a type factory with default type system.
+ *
+ * @deprecated Will be removed after optiq-0.9.1.
+ */
protected RelDataTypeFactoryImpl() {
+ this(RelDataTypeSystem.DEFAULT);
+ Bug.upgrade("optiq-0.9.1");
+ }
+
+ /** Creates a type factory. */
+ protected RelDataTypeFactoryImpl(RelDataTypeSystem typeSystem) {
+ this.typeSystem = Preconditions.checkNotNull(typeSystem);
}
//~ Methods ----------------------------------------------------------------
+ public RelDataTypeSystem getTypeSystem() {
+ return typeSystem;
+ }
+
// implement RelDataTypeFactory
public RelDataType createJavaType(Class clazz) {
final JavaType javaType =
@@ -450,12 +467,12 @@ public abstract class RelDataTypeFactoryImpl implements RelDataTypeFactory {
int s2 = type2.getScale();
int scale = s1 + s2;
- scale = Math.min(scale, SqlTypeName.MAX_NUMERIC_SCALE);
+ scale = Math.min(scale, typeSystem.getMaxNumericScale());
int precision = p1 + p2;
precision =
Math.min(
precision,
- SqlTypeName.MAX_NUMERIC_PRECISION);
+ typeSystem.getMaxNumericPrecision());
RelDataType ret;
ret =
@@ -511,20 +528,21 @@ public abstract class RelDataTypeFactoryImpl implements RelDataTypeFactory {
int s1 = type1.getScale();
int s2 = type2.getScale();
+ final int maxNumericPrecision = typeSystem.getMaxNumericPrecision();
int dout =
Math.min(
p1 - s1 + s2,
- SqlTypeName.MAX_NUMERIC_PRECISION);
+ maxNumericPrecision);
int scale = Math.max(6, s1 + p2 + 1);
scale =
Math.min(
scale,
- SqlTypeName.MAX_NUMERIC_PRECISION - dout);
- scale = Math.min(scale, SqlTypeName.MAX_NUMERIC_SCALE);
+ maxNumericPrecision - dout);
+ scale = Math.min(scale, getTypeSystem().getMaxNumericScale());
int precision = dout + scale;
- assert precision <= SqlTypeName.MAX_NUMERIC_PRECISION;
+ assert precision <= maxNumericPrecision;
assert precision > 0;
RelDataType ret;
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/org/eigenbase/reltype/RelDataTypeSystem.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/reltype/RelDataTypeSystem.java b/core/src/main/java/org/eigenbase/reltype/RelDataTypeSystem.java
new file mode 100644
index 0000000..e72722f
--- /dev/null
+++ b/core/src/main/java/org/eigenbase/reltype/RelDataTypeSystem.java
@@ -0,0 +1,60 @@
+/*
+ * 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.eigenbase.reltype;
+
+import org.eigenbase.sql.type.SqlTypeName;
+
+/**
+ * Type system.
+ *
+ * <p>Provides behaviors concerning type limits and behaviors. For example,
+ * in the default system, a DECIMAL can have maximum precision 19, but Hive
+ * overrides to 38.
+ *
+ * <p>The default implementation is {@link #DEFAULT}.
+ */
+public interface RelDataTypeSystem {
+ /** Default type system. */
+ RelDataTypeSystem DEFAULT = new RelDataTypeSystemImpl() { };
+
+ /** Returns the maximum scale of a given type. */
+ int getMaxScale(SqlTypeName typeName);
+
+ /**
+ * Returns default precision for this type if supported, otherwise -1 if
+ * precision is either unsupported or must be specified explicitly.
+ *
+ * @return Default precision
+ */
+ int getDefaultPrecision(SqlTypeName typeName);
+
+ /**
+ * Returns the maximum precision (or length) allowed for this type, or -1 if
+ * precision/length are not applicable for this type.
+ *
+ * @return Maximum allowed precision
+ */
+ int getMaxPrecision(SqlTypeName typeName);
+
+ /** Returns the maximum scale of a NUMERIC or DECIMAL type. */
+ int getMaxNumericScale();
+
+ /** Returns the maximum precision of a NUMERIC or DECIMAL type. */
+ int getMaxNumericPrecision();
+}
+
+// End RelDataTypeFactory.java
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/org/eigenbase/reltype/RelDataTypeSystemImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/reltype/RelDataTypeSystemImpl.java b/core/src/main/java/org/eigenbase/reltype/RelDataTypeSystemImpl.java
new file mode 100644
index 0000000..b158974
--- /dev/null
+++ b/core/src/main/java/org/eigenbase/reltype/RelDataTypeSystemImpl.java
@@ -0,0 +1,98 @@
+/*
+ * 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.eigenbase.reltype;
+
+import org.eigenbase.sql.type.SqlTypeName;
+
+/** Default implementation of {@link org.eigenbase.reltype.RelDataTypeSystem},
+ * providing parameters from the SQL standard.
+ *
+ * <p>To implement other type systems, create a derived class and override
+ * values as needed.
+ *
+ * <table border='1'>
+ * <tr><td>Parameter</td> <td>Value</td></tr>
+ * <tr><td>MAX_NUMERIC_SCALE</td><td>19</td></tr>
+ * </table>
+ */
+public abstract class RelDataTypeSystemImpl implements RelDataTypeSystem {
+ public int getMaxScale(SqlTypeName typeName) {
+ switch (typeName) {
+ case DECIMAL:
+ return getMaxNumericScale();
+ case INTERVAL_DAY_TIME:
+ case INTERVAL_YEAR_MONTH:
+ return SqlTypeName.MAX_INTERVAL_FRACTIONAL_SECOND_PRECISION;
+ default:
+ return -1;
+ }
+ }
+
+ public int getDefaultPrecision(SqlTypeName typeName) {
+ switch (typeName) {
+ case CHAR:
+ case BINARY:
+ case VARCHAR:
+ case VARBINARY:
+ return 1;
+ case TIME:
+ return 0;
+ case TIMESTAMP:
+ // TODO jvs 26-July-2004: should be 6 for microseconds,
+ // but we can't support that yet
+ return 0;
+ case DECIMAL:
+ return getMaxNumericPrecision();
+ case INTERVAL_DAY_TIME:
+ case INTERVAL_YEAR_MONTH:
+ return SqlTypeName.DEFAULT_INTERVAL_START_PRECISION;
+ default:
+ return -1;
+ }
+ }
+
+ public int getMaxPrecision(SqlTypeName typeName) {
+ switch (typeName) {
+ case DECIMAL:
+ return getMaxNumericPrecision();
+ case VARCHAR:
+ case CHAR:
+ return 65536;
+ case VARBINARY:
+ case BINARY:
+ return 65536;
+ case TIME:
+ case TIMESTAMP:
+ return SqlTypeName.MAX_DATETIME_PRECISION;
+ case INTERVAL_DAY_TIME:
+ case INTERVAL_YEAR_MONTH:
+ return SqlTypeName.MAX_INTERVAL_START_PRECISION;
+ default:
+ return -1;
+ }
+ }
+
+ public int getMaxNumericScale() {
+ return 19;
+ }
+
+ public int getMaxNumericPrecision() {
+ return 19;
+ }
+}
+
+// End RelDataTypeSystemImpl.java
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/org/eigenbase/rex/RexBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rex/RexBuilder.java b/core/src/main/java/org/eigenbase/rex/RexBuilder.java
index d393a16..251af45 100644
--- a/core/src/main/java/org/eigenbase/rex/RexBuilder.java
+++ b/core/src/main/java/org/eigenbase/rex/RexBuilder.java
@@ -529,7 +529,8 @@ public class RexBuilder {
if (endUnit == TimeUnit.SECOND) {
scale = Math.min(
intervalType.getIntervalQualifier()
- .getFractionalSecondPrecision(), 3);
+ .getFractionalSecondPrecision(typeFactory.getTypeSystem()),
+ 3);
}
BigDecimal multiplier = BigDecimal.valueOf(endUnit.multiplier)
.divide(BigDecimal.TEN.pow(scale));
@@ -560,7 +561,8 @@ public class RexBuilder {
if (endUnit == TimeUnit.SECOND) {
scale = Math.min(
intervalType.getIntervalQualifier()
- .getFractionalSecondPrecision(), 3);
+ .getFractionalSecondPrecision(typeFactory.getTypeSystem()),
+ 3);
}
BigDecimal multiplier = BigDecimal.valueOf(endUnit.multiplier)
.divide(BigDecimal.TEN.pow(scale));
@@ -798,7 +800,8 @@ public class RexBuilder {
RelDataType relType;
int scale = bd.scale();
long l = bd.unscaledValue().longValue();
- assert (scale >= 0) && (scale <= SqlTypeName.MAX_NUMERIC_SCALE);
+ assert scale >= 0;
+ assert scale <= typeFactory.getTypeSystem().getMaxNumericScale() : scale;
assert BigDecimal.valueOf(l, scale).equals(bd);
if (scale == 0) {
if ((l >= Integer.MIN_VALUE) && (l <= Integer.MAX_VALUE)) {
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/org/eigenbase/rex/RexExecutorImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rex/RexExecutorImpl.java b/core/src/main/java/org/eigenbase/rex/RexExecutorImpl.java
index b187344..da34a55 100644
--- a/core/src/main/java/org/eigenbase/rex/RexExecutorImpl.java
+++ b/core/src/main/java/org/eigenbase/rex/RexExecutorImpl.java
@@ -61,7 +61,8 @@ public class RexExecutorImpl implements RelOptPlanner.Executor {
programBuilder.addProject(
node, "c" + programBuilder.getProjectList().size());
}
- final JavaTypeFactoryImpl javaTypeFactory = new JavaTypeFactoryImpl();
+ final JavaTypeFactoryImpl javaTypeFactory =
+ new JavaTypeFactoryImpl(rexBuilder.getTypeFactory().getTypeSystem());
final BlockBuilder blockBuilder = new BlockBuilder();
final ParameterExpression root0_ =
Expressions.parameter(Object.class, "root0");
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/org/eigenbase/sql/SqlIntervalQualifier.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/sql/SqlIntervalQualifier.java b/core/src/main/java/org/eigenbase/sql/SqlIntervalQualifier.java
index 2d3eb7c..406ed57 100644
--- a/core/src/main/java/org/eigenbase/sql/SqlIntervalQualifier.java
+++ b/core/src/main/java/org/eigenbase/sql/SqlIntervalQualifier.java
@@ -20,6 +20,8 @@ import java.math.BigDecimal;
import java.util.*;
import java.util.regex.*;
+import org.eigenbase.reltype.RelDataType;
+import org.eigenbase.reltype.RelDataTypeSystem;
import org.eigenbase.sql.parser.*;
import org.eigenbase.sql.type.*;
import org.eigenbase.sql.util.*;
@@ -29,6 +31,7 @@ import org.eigenbase.util14.DateTimeUtil;
import net.hydromatic.optiq.runtime.SqlFunctions;
+import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import static org.eigenbase.util.Static.RESOURCE;
@@ -83,7 +86,6 @@ import static org.eigenbase.util.Static.RESOURCE;
public class SqlIntervalQualifier extends SqlNode {
//~ Static fields/initializers ---------------------------------------------
- private static final int USE_DEFAULT_PRECISION = -1;
private static final BigDecimal ZERO = BigDecimal.ZERO;
private static final BigDecimal THOUSAND = BigDecimal.valueOf(1000);
private static final BigDecimal INT_MAX_VALUE_PLUS_ONE =
@@ -204,9 +206,6 @@ public class SqlIntervalQualifier extends SqlNode {
private final TimeUnitRange timeUnitRange;
private final int fractionalSecondPrecision;
- private final boolean useDefaultStartPrecision;
- private final boolean useDefaultFractionalSecondPrecision;
-
//~ Constructors -----------------------------------------------------------
public SqlIntervalQualifier(
@@ -216,39 +215,10 @@ public class SqlIntervalQualifier extends SqlNode {
int fractionalSecondPrecision,
SqlParserPos pos) {
super(pos);
- assert null != startUnit;
-
- this.timeUnitRange = TimeUnitRange.of(startUnit, endUnit);
-
- // if unspecified, start precision = 2
- if (startPrecision == USE_DEFAULT_PRECISION) {
- useDefaultStartPrecision = true;
- if (this.isYearMonth()) {
- this.startPrecision =
- SqlTypeName.INTERVAL_YEAR_MONTH.getDefaultPrecision();
- } else {
- this.startPrecision =
- SqlTypeName.INTERVAL_DAY_TIME.getDefaultPrecision();
- }
- } else {
- useDefaultStartPrecision = false;
- this.startPrecision = startPrecision;
- }
-
- // unspecified fractional second precision = 6
- if (fractionalSecondPrecision == USE_DEFAULT_PRECISION) {
- useDefaultFractionalSecondPrecision = true;
- if (this.isYearMonth()) {
- this.fractionalSecondPrecision =
- SqlTypeName.INTERVAL_YEAR_MONTH.getDefaultScale();
- } else {
- this.fractionalSecondPrecision =
- SqlTypeName.INTERVAL_DAY_TIME.getDefaultScale();
- }
- } else {
- useDefaultFractionalSecondPrecision = false;
- this.fractionalSecondPrecision = fractionalSecondPrecision;
- }
+ this.timeUnitRange =
+ TimeUnitRange.of(Preconditions.checkNotNull(startUnit), endUnit);
+ this.startPrecision = startPrecision;
+ this.fractionalSecondPrecision = fractionalSecondPrecision;
}
public SqlIntervalQualifier(
@@ -257,14 +227,20 @@ public class SqlIntervalQualifier extends SqlNode {
SqlParserPos pos) {
this(
startUnit,
- USE_DEFAULT_PRECISION,
+ RelDataType.PRECISION_NOT_SPECIFIED,
endUnit,
- USE_DEFAULT_PRECISION,
+ RelDataType.PRECISION_NOT_SPECIFIED,
pos);
}
//~ Methods ----------------------------------------------------------------
+ public SqlTypeName typeName() {
+ return isYearMonth()
+ ? SqlTypeName.INTERVAL_YEAR_MONTH
+ : SqlTypeName.INTERVAL_DAY_TIME;
+ }
+
public SqlFunctions.TimeUnitRange foo() {
return SqlFunctions.TimeUnitRange.valueOf(timeUnitRange.name());
}
@@ -289,33 +265,34 @@ public class SqlIntervalQualifier extends SqlNode {
return true;
}
- public static int getDefaultPrecisionId() {
- return USE_DEFAULT_PRECISION;
+ public int getStartPrecision(RelDataTypeSystem typeSystem) {
+ if (startPrecision == RelDataType.PRECISION_NOT_SPECIFIED) {
+ return typeSystem.getDefaultPrecision(typeName());
+ } else {
+ return startPrecision;
+ }
}
- public int getStartPrecision() {
+ public int getStartPrecisionPreservingDefault() {
return startPrecision;
}
- public int getStartPrecisionPreservingDefault() {
- if (useDefaultStartPrecision) {
- return USE_DEFAULT_PRECISION;
- } else {
- return startPrecision;
- }
+ private boolean useDefaultStartPrecision() {
+ return startPrecision == RelDataType.PRECISION_NOT_SPECIFIED;
}
public static int combineStartPrecisionPreservingDefault(
+ RelDataTypeSystem typeSystem,
SqlIntervalQualifier qual1,
SqlIntervalQualifier qual2) {
- if (qual1.getStartPrecision()
- > qual2.getStartPrecision()) {
+ final int start1 = qual1.getStartPrecision(typeSystem);
+ final int start2 = qual2.getStartPrecision(typeSystem);
+ if (start1 > start2) {
// qual1 is more precise, but if it has the default indicator
// set, we need to return that indicator so result will also
// use default
return qual1.getStartPrecisionPreservingDefault();
- } else if (qual1.getStartPrecision()
- < qual2.getStartPrecision()) {
+ } else if (start1 < start2) {
// qual2 is more precise, but if it has the default indicator
// set, we need to return that indicator so result will also
// use default
@@ -323,39 +300,47 @@ public class SqlIntervalQualifier extends SqlNode {
} else {
// they are equal. return default if both are default,
// otherwise return exact precision
- if (qual1.useDefaultStartPrecision
- && qual2.useDefaultStartPrecision) {
+ if (qual1.useDefaultStartPrecision()
+ && qual2.useDefaultStartPrecision()) {
return qual1.getStartPrecisionPreservingDefault();
} else {
- return qual1.getStartPrecision();
+ return start1;
}
}
}
- public int getFractionalSecondPrecision() {
- return fractionalSecondPrecision;
+ public int getFractionalSecondPrecision(RelDataTypeSystem typeSystem) {
+ if (fractionalSecondPrecision == RelDataType.PRECISION_NOT_SPECIFIED) {
+ return typeName().getDefaultScale();
+ } else {
+ return fractionalSecondPrecision;
+ }
}
public int getFractionalSecondPrecisionPreservingDefault() {
- if (useDefaultFractionalSecondPrecision) {
- return USE_DEFAULT_PRECISION;
+ if (useDefaultFractionalSecondPrecision()) {
+ return RelDataType.PRECISION_NOT_SPECIFIED;
} else {
return startPrecision;
}
}
+ private boolean useDefaultFractionalSecondPrecision() {
+ return fractionalSecondPrecision == RelDataType.PRECISION_NOT_SPECIFIED;
+ }
+
public static int combineFractionalSecondPrecisionPreservingDefault(
+ RelDataTypeSystem typeSystem,
SqlIntervalQualifier qual1,
SqlIntervalQualifier qual2) {
- if (qual1.getFractionalSecondPrecision()
- > qual2.getFractionalSecondPrecision()) {
+ final int p1 = qual1.getFractionalSecondPrecision(typeSystem);
+ final int p2 = qual2.getFractionalSecondPrecision(typeSystem);
+ if (p1 > p2) {
// qual1 is more precise, but if it has the default indicator
// set, we need to return that indicator so result will also
// use default
return qual1.getFractionalSecondPrecisionPreservingDefault();
- } else if (
- qual1.getFractionalSecondPrecision()
- < qual2.getFractionalSecondPrecision()) {
+ } else if (p1 < p2) {
// qual2 is more precise, but if it has the default indicator
// set, we need to return that indicator so result will also
// use default
@@ -363,11 +348,11 @@ public class SqlIntervalQualifier extends SqlNode {
} else {
// they are equal. return default if both are default,
// otherwise return exact precision
- if (qual1.useDefaultFractionalSecondPrecision
- && qual2.useDefaultFractionalSecondPrecision) {
+ if (qual1.useDefaultFractionalSecondPrecision()
+ && qual2.useDefaultFractionalSecondPrecision()) {
return qual1.getFractionalSecondPrecisionPreservingDefault();
} else {
- return qual1.getFractionalSecondPrecision();
+ return p1;
}
}
}
@@ -381,29 +366,30 @@ public class SqlIntervalQualifier extends SqlNode {
}
public SqlNode clone(SqlParserPos pos) {
- return new SqlIntervalQualifier(
- timeUnitRange.startUnit,
- useDefaultStartPrecision ? USE_DEFAULT_PRECISION
- : startPrecision,
- timeUnitRange.endUnit,
- useDefaultFractionalSecondPrecision ? USE_DEFAULT_PRECISION
- : fractionalSecondPrecision,
- pos);
+ return new SqlIntervalQualifier(timeUnitRange.startUnit, startPrecision,
+ timeUnitRange.endUnit, fractionalSecondPrecision, pos);
}
public void unparse(
SqlWriter writer,
int leftPrec,
int rightPrec) {
+ unparse(RelDataTypeSystem.DEFAULT, writer);
+ }
+
+ public void unparse(RelDataTypeSystem typeSystem, SqlWriter writer) {
final String start = timeUnitRange.startUnit.name();
+ final int fractionalSecondPrecision =
+ getFractionalSecondPrecision(typeSystem);
+ final int startPrecision = getStartPrecision(typeSystem);
if (timeUnitRange.startUnit == TimeUnit.SECOND) {
- if (!useDefaultFractionalSecondPrecision) {
+ if (!useDefaultFractionalSecondPrecision()) {
final SqlWriter.Frame frame = writer.startFunCall(start);
writer.print(startPrecision);
writer.sep(",", true);
- writer.print(fractionalSecondPrecision);
+ writer.print(getFractionalSecondPrecision(typeSystem));
writer.endList(frame);
- } else if (!useDefaultStartPrecision) {
+ } else if (!useDefaultStartPrecision()) {
final SqlWriter.Frame frame = writer.startFunCall(start);
writer.print(startPrecision);
writer.endList(frame);
@@ -411,7 +397,7 @@ public class SqlIntervalQualifier extends SqlNode {
writer.keyword(start);
}
} else {
- if (!useDefaultStartPrecision) {
+ if (!useDefaultStartPrecision()) {
final SqlWriter.Frame frame = writer.startFunCall(start);
writer.print(startPrecision);
writer.endList(frame);
@@ -423,7 +409,7 @@ public class SqlIntervalQualifier extends SqlNode {
writer.keyword("TO");
final String end = timeUnitRange.endUnit.name();
if ((TimeUnit.SECOND == timeUnitRange.endUnit)
- && (!useDefaultFractionalSecondPrecision)) {
+ && (!useDefaultFractionalSecondPrecision())) {
final SqlWriter.Frame frame = writer.startFunCall(end);
writer.print(fractionalSecondPrecision);
writer.endList(frame);
@@ -474,21 +460,23 @@ public class SqlIntervalQualifier extends SqlNode {
return unsignedValue;
}
- private boolean isLeadFieldInRange(BigDecimal value, TimeUnit unit) {
+ private boolean isLeadFieldInRange(RelDataTypeSystem typeSystem,
+ BigDecimal value, TimeUnit unit) {
// we should never get handed a negative field value
assert value.compareTo(ZERO) >= 0;
// Leading fields are only restricted by startPrecision.
+ final int startPrecision = getStartPrecision(typeSystem);
return startPrecision < POWERS10.length
? value.compareTo(POWERS10[startPrecision]) < 0
: value.compareTo(INT_MAX_VALUE_PLUS_ONE) < 0;
}
- private void checkLeadFieldInRange(
- int sign, BigDecimal value, TimeUnit unit, SqlParserPos pos) {
- if (!isLeadFieldInRange(value, unit)) {
+ private void checkLeadFieldInRange(RelDataTypeSystem typeSystem, int sign,
+ BigDecimal value, TimeUnit unit, SqlParserPos pos) {
+ if (!isLeadFieldInRange(typeSystem, value, unit)) {
throw fieldExceedsPrecisionException(
- pos, sign, value, unit, startPrecision);
+ pos, sign, value, unit, getStartPrecision(typeSystem));
}
}
@@ -581,7 +569,7 @@ public class SqlIntervalQualifier extends SqlNode {
* @throws EigenbaseContextException if the interval value is illegal.
*/
private int[] evaluateIntervalLiteralAsYear(
- int sign,
+ RelDataTypeSystem typeSystem, int sign,
String value,
String originalValue,
SqlParserPos pos) {
@@ -600,7 +588,7 @@ public class SqlIntervalQualifier extends SqlNode {
}
// Validate individual fields
- checkLeadFieldInRange(sign, year, TimeUnit.YEAR, pos);
+ checkLeadFieldInRange(typeSystem, sign, year, TimeUnit.YEAR, pos);
// package values up for return
return fillIntervalValueArray(sign, year, ZERO);
@@ -615,7 +603,7 @@ public class SqlIntervalQualifier extends SqlNode {
* @throws EigenbaseContextException if the interval value is illegal.
*/
private int[] evaluateIntervalLiteralAsYearToMonth(
- int sign,
+ RelDataTypeSystem typeSystem, int sign,
String value,
String originalValue,
SqlParserPos pos) {
@@ -636,7 +624,7 @@ public class SqlIntervalQualifier extends SqlNode {
}
// Validate individual fields
- checkLeadFieldInRange(sign, year, TimeUnit.YEAR, pos);
+ checkLeadFieldInRange(typeSystem, sign, year, TimeUnit.YEAR, pos);
if (!(isSecondaryFieldInRange(month, TimeUnit.MONTH))) {
throw invalidValueException(pos, originalValue);
}
@@ -654,7 +642,7 @@ public class SqlIntervalQualifier extends SqlNode {
* @throws EigenbaseContextException if the interval value is illegal.
*/
private int[] evaluateIntervalLiteralAsMonth(
- int sign,
+ RelDataTypeSystem typeSystem, int sign,
String value,
String originalValue,
SqlParserPos pos) {
@@ -673,7 +661,7 @@ public class SqlIntervalQualifier extends SqlNode {
}
// Validate individual fields
- checkLeadFieldInRange(sign, month, TimeUnit.MONTH, pos);
+ checkLeadFieldInRange(typeSystem, sign, month, TimeUnit.MONTH, pos);
// package values up for return
return fillIntervalValueArray(sign, ZERO, month);
@@ -688,7 +676,7 @@ public class SqlIntervalQualifier extends SqlNode {
* @throws EigenbaseContextException if the interval value is illegal.
*/
private int[] evaluateIntervalLiteralAsDay(
- int sign,
+ RelDataTypeSystem typeSystem, int sign,
String value,
String originalValue,
SqlParserPos pos) {
@@ -707,7 +695,7 @@ public class SqlIntervalQualifier extends SqlNode {
}
// Validate individual fields
- checkLeadFieldInRange(sign, day, TimeUnit.DAY, pos);
+ checkLeadFieldInRange(typeSystem, sign, day, TimeUnit.DAY, pos);
// package values up for return
return fillIntervalValueArray(sign, day, ZERO, ZERO, ZERO, ZERO);
@@ -722,7 +710,7 @@ public class SqlIntervalQualifier extends SqlNode {
* @throws EigenbaseContextException if the interval value is illegal.
*/
private int[] evaluateIntervalLiteralAsDayToHour(
- int sign,
+ RelDataTypeSystem typeSystem, int sign,
String value,
String originalValue,
SqlParserPos pos) {
@@ -743,7 +731,7 @@ public class SqlIntervalQualifier extends SqlNode {
}
// Validate individual fields
- checkLeadFieldInRange(sign, day, TimeUnit.DAY, pos);
+ checkLeadFieldInRange(typeSystem, sign, day, TimeUnit.DAY, pos);
if (!(isSecondaryFieldInRange(hour, TimeUnit.HOUR))) {
throw invalidValueException(pos, originalValue);
}
@@ -761,7 +749,7 @@ public class SqlIntervalQualifier extends SqlNode {
* @throws EigenbaseContextException if the interval value is illegal.
*/
private int[] evaluateIntervalLiteralAsDayToMinute(
- int sign,
+ RelDataTypeSystem typeSystem, int sign,
String value,
String originalValue,
SqlParserPos pos) {
@@ -784,7 +772,7 @@ public class SqlIntervalQualifier extends SqlNode {
}
// Validate individual fields
- checkLeadFieldInRange(sign, day, TimeUnit.DAY, pos);
+ checkLeadFieldInRange(typeSystem, sign, day, TimeUnit.DAY, pos);
if (!(isSecondaryFieldInRange(hour, TimeUnit.HOUR))
|| !(isSecondaryFieldInRange(minute, TimeUnit.MINUTE))) {
throw invalidValueException(pos, originalValue);
@@ -803,7 +791,7 @@ public class SqlIntervalQualifier extends SqlNode {
* @throws EigenbaseContextException if the interval value is illegal.
*/
private int[] evaluateIntervalLiteralAsDayToSecond(
- int sign,
+ RelDataTypeSystem typeSystem, int sign,
String value,
String originalValue,
SqlParserPos pos) {
@@ -817,6 +805,8 @@ public class SqlIntervalQualifier extends SqlNode {
// validate as DAY(startPrecision) TO MINUTE,
// e.g. 'DD HH:MM:SS' or 'DD HH:MM:SS.SSS'
// Note: must check two patterns, since fractional second is optional
+ final int fractionalSecondPrecision =
+ getFractionalSecondPrecision(typeSystem);
String intervalPatternWithFracSec =
"(\\d+) (\\d{1,2}):(\\d{1,2}):(\\d{1,2})\\.(\\d{1,"
+ fractionalSecondPrecision + "})";
@@ -849,7 +839,7 @@ public class SqlIntervalQualifier extends SqlNode {
}
// Validate individual fields
- checkLeadFieldInRange(sign, day, TimeUnit.DAY, pos);
+ checkLeadFieldInRange(typeSystem, sign, day, TimeUnit.DAY, pos);
if (!(isSecondaryFieldInRange(hour, TimeUnit.HOUR))
|| !(isSecondaryFieldInRange(minute, TimeUnit.MINUTE))
|| !(isSecondaryFieldInRange(second, TimeUnit.SECOND))
@@ -876,7 +866,7 @@ public class SqlIntervalQualifier extends SqlNode {
* @throws EigenbaseContextException if the interval value is illegal.
*/
private int[] evaluateIntervalLiteralAsHour(
- int sign,
+ RelDataTypeSystem typeSystem, int sign,
String value,
String originalValue,
SqlParserPos pos) {
@@ -895,7 +885,7 @@ public class SqlIntervalQualifier extends SqlNode {
}
// Validate individual fields
- checkLeadFieldInRange(sign, hour, TimeUnit.HOUR, pos);
+ checkLeadFieldInRange(typeSystem, sign, hour, TimeUnit.HOUR, pos);
// package values up for return
return fillIntervalValueArray(sign, ZERO, hour, ZERO, ZERO, ZERO);
@@ -911,7 +901,7 @@ public class SqlIntervalQualifier extends SqlNode {
* @throws EigenbaseContextException if the interval value is illegal.
*/
private int[] evaluateIntervalLiteralAsHourToMinute(
- int sign,
+ RelDataTypeSystem typeSystem, int sign,
String value,
String originalValue,
SqlParserPos pos) {
@@ -932,7 +922,7 @@ public class SqlIntervalQualifier extends SqlNode {
}
// Validate individual fields
- checkLeadFieldInRange(sign, hour, TimeUnit.HOUR, pos);
+ checkLeadFieldInRange(typeSystem, sign, hour, TimeUnit.HOUR, pos);
if (!(isSecondaryFieldInRange(minute, TimeUnit.MINUTE))) {
throw invalidValueException(pos, originalValue);
}
@@ -951,7 +941,7 @@ public class SqlIntervalQualifier extends SqlNode {
* @throws EigenbaseContextException if the interval value is illegal.
*/
private int[] evaluateIntervalLiteralAsHourToSecond(
- int sign,
+ RelDataTypeSystem typeSystem, int sign,
String value,
String originalValue,
SqlParserPos pos) {
@@ -964,6 +954,8 @@ public class SqlIntervalQualifier extends SqlNode {
// validate as HOUR(startPrecision) TO SECOND,
// e.g. 'HH:MM:SS' or 'HH:MM:SS.SSS'
// Note: must check two patterns, since fractional second is optional
+ final int fractionalSecondPrecision =
+ getFractionalSecondPrecision(typeSystem);
String intervalPatternWithFracSec =
"(\\d+):(\\d{1,2}):(\\d{1,2})\\.(\\d{1,"
+ fractionalSecondPrecision + "})";
@@ -995,7 +987,7 @@ public class SqlIntervalQualifier extends SqlNode {
}
// Validate individual fields
- checkLeadFieldInRange(sign, hour, TimeUnit.HOUR, pos);
+ checkLeadFieldInRange(typeSystem, sign, hour, TimeUnit.HOUR, pos);
if (!(isSecondaryFieldInRange(minute, TimeUnit.MINUTE))
|| !(isSecondaryFieldInRange(second, TimeUnit.SECOND))
|| !(isFractionalSecondFieldInRange(secondFrac))) {
@@ -1021,7 +1013,7 @@ public class SqlIntervalQualifier extends SqlNode {
* @throws EigenbaseContextException if the interval value is illegal.
*/
private int[] evaluateIntervalLiteralAsMinute(
- int sign,
+ RelDataTypeSystem typeSystem, int sign,
String value,
String originalValue,
SqlParserPos pos) {
@@ -1040,7 +1032,7 @@ public class SqlIntervalQualifier extends SqlNode {
}
// Validate individual fields
- checkLeadFieldInRange(sign, minute, TimeUnit.MINUTE, pos);
+ checkLeadFieldInRange(typeSystem, sign, minute, TimeUnit.MINUTE, pos);
// package values up for return
return fillIntervalValueArray(sign, ZERO, ZERO, minute, ZERO, ZERO);
@@ -1056,7 +1048,7 @@ public class SqlIntervalQualifier extends SqlNode {
* @throws EigenbaseContextException if the interval value is illegal.
*/
private int[] evaluateIntervalLiteralAsMinuteToSecond(
- int sign,
+ RelDataTypeSystem typeSystem, int sign,
String value,
String originalValue,
SqlParserPos pos) {
@@ -1068,6 +1060,8 @@ public class SqlIntervalQualifier extends SqlNode {
// validate as MINUTE(startPrecision) TO SECOND,
// e.g. 'MM:SS' or 'MM:SS.SSS'
// Note: must check two patterns, since fractional second is optional
+ final int fractionalSecondPrecision =
+ getFractionalSecondPrecision(typeSystem);
String intervalPatternWithFracSec =
"(\\d+):(\\d{1,2})\\.(\\d{1," + fractionalSecondPrecision + "})";
String intervalPatternWithoutFracSec =
@@ -1097,7 +1091,7 @@ public class SqlIntervalQualifier extends SqlNode {
}
// Validate individual fields
- checkLeadFieldInRange(sign, minute, TimeUnit.MINUTE, pos);
+ checkLeadFieldInRange(typeSystem, sign, minute, TimeUnit.MINUTE, pos);
if (!(isSecondaryFieldInRange(second, TimeUnit.SECOND))
|| !(isFractionalSecondFieldInRange(secondFrac))) {
throw invalidValueException(pos, originalValue);
@@ -1122,6 +1116,7 @@ public class SqlIntervalQualifier extends SqlNode {
* @throws EigenbaseContextException if the interval value is illegal.
*/
private int[] evaluateIntervalLiteralAsSecond(
+ RelDataTypeSystem typeSystem,
int sign,
String value,
String originalValue,
@@ -1133,6 +1128,8 @@ public class SqlIntervalQualifier extends SqlNode {
// validate as SECOND(startPrecision, fractionalSecondPrecision)
// e.g. 'SS' or 'SS.SSS'
// Note: must check two patterns, since fractional second is optional
+ final int fractionalSecondPrecision =
+ getFractionalSecondPrecision(typeSystem);
String intervalPatternWithFracSec =
"(\\d+)\\.(\\d{1," + fractionalSecondPrecision + "})";
String intervalPatternWithoutFracSec =
@@ -1161,7 +1158,7 @@ public class SqlIntervalQualifier extends SqlNode {
}
// Validate individual fields
- checkLeadFieldInRange(sign, second, TimeUnit.SECOND, pos);
+ checkLeadFieldInRange(typeSystem, sign, second, TimeUnit.SECOND, pos);
if (!(isFractionalSecondFieldInRange(secondFrac))) {
throw invalidValueException(pos, originalValue);
}
@@ -1183,7 +1180,8 @@ public class SqlIntervalQualifier extends SqlNode {
* @return field values, never null
* @throws EigenbaseContextException if the interval value is illegal
*/
- public int[] evaluateIntervalLiteral(String value, SqlParserPos pos) {
+ public int[] evaluateIntervalLiteral(String value, SqlParserPos pos,
+ RelDataTypeSystem typeSystem) {
// save original value for if we have to throw
final String value0 = value;
@@ -1207,31 +1205,43 @@ public class SqlIntervalQualifier extends SqlNode {
// well as explicit or implicit precision and range.
switch (timeUnitRange) {
case YEAR:
- return evaluateIntervalLiteralAsYear(sign, value, value0, pos);
+ return evaluateIntervalLiteralAsYear(typeSystem, sign, value, value0,
+ pos);
case YEAR_TO_MONTH:
- return evaluateIntervalLiteralAsYearToMonth(sign, value, value0, pos);
+ return evaluateIntervalLiteralAsYearToMonth(typeSystem, sign, value,
+ value0, pos);
case MONTH:
- return evaluateIntervalLiteralAsMonth(sign, value, value0, pos);
+ return evaluateIntervalLiteralAsMonth(typeSystem, sign, value, value0,
+ pos);
case DAY:
- return evaluateIntervalLiteralAsDay(sign, value, value0, pos);
+ return evaluateIntervalLiteralAsDay(typeSystem, sign, value, value0, pos);
case DAY_TO_HOUR:
- return evaluateIntervalLiteralAsDayToHour(sign, value, value0, pos);
+ return evaluateIntervalLiteralAsDayToHour(typeSystem, sign, value, value0,
+ pos);
case DAY_TO_MINUTE:
- return evaluateIntervalLiteralAsDayToMinute(sign, value, value0, pos);
+ return evaluateIntervalLiteralAsDayToMinute(typeSystem, sign, value,
+ value0, pos);
case DAY_TO_SECOND:
- return evaluateIntervalLiteralAsDayToSecond(sign, value, value0, pos);
+ return evaluateIntervalLiteralAsDayToSecond(typeSystem, sign, value,
+ value0, pos);
case HOUR:
- return evaluateIntervalLiteralAsHour(sign, value, value0, pos);
+ return evaluateIntervalLiteralAsHour(typeSystem, sign, value, value0,
+ pos);
case HOUR_TO_MINUTE:
- return evaluateIntervalLiteralAsHourToMinute(sign, value, value0, pos);
+ return evaluateIntervalLiteralAsHourToMinute(typeSystem, sign, value,
+ value0, pos);
case HOUR_TO_SECOND:
- return evaluateIntervalLiteralAsHourToSecond(sign, value, value0, pos);
+ return evaluateIntervalLiteralAsHourToSecond(typeSystem, sign, value,
+ value0, pos);
case MINUTE:
- return evaluateIntervalLiteralAsMinute(sign, value, value0, pos);
+ return evaluateIntervalLiteralAsMinute(typeSystem, sign, value, value0,
+ pos);
case MINUTE_TO_SECOND:
- return evaluateIntervalLiteralAsMinuteToSecond(sign, value, value0, pos);
+ return evaluateIntervalLiteralAsMinuteToSecond(typeSystem, sign, value,
+ value0, pos);
case SECOND:
- return evaluateIntervalLiteralAsSecond(sign, value, value0, pos);
+ return evaluateIntervalLiteralAsSecond(typeSystem, sign, value, value0,
+ pos);
default:
throw invalidValueException(pos, value0);
}
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/org/eigenbase/sql/SqlUnresolvedFunction.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/sql/SqlUnresolvedFunction.java b/core/src/main/java/org/eigenbase/sql/SqlUnresolvedFunction.java
index a8a5ac6..a607022 100644
--- a/core/src/main/java/org/eigenbase/sql/SqlUnresolvedFunction.java
+++ b/core/src/main/java/org/eigenbase/sql/SqlUnresolvedFunction.java
@@ -19,7 +19,6 @@ package org.eigenbase.sql;
import java.util.List;
import org.eigenbase.reltype.RelDataType;
-import org.eigenbase.sql.type.BasicSqlType;
import org.eigenbase.sql.type.SqlOperandTypeChecker;
import org.eigenbase.sql.type.SqlOperandTypeInference;
import org.eigenbase.sql.type.SqlReturnTypeInference;
@@ -64,9 +63,8 @@ public class SqlUnresolvedFunction extends SqlFunction {
* fail.
*/
@Override
- public RelDataType inferReturnType(
- SqlOperatorBinding opBinding) {
- return new BasicSqlType(SqlTypeName.ANY);
+ public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
+ return opBinding.getTypeFactory().createSqlType(SqlTypeName.ANY);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/org/eigenbase/sql/parser/SqlParserUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/sql/parser/SqlParserUtil.java b/core/src/main/java/org/eigenbase/sql/parser/SqlParserUtil.java
index 30fe3d4..1297f35 100644
--- a/core/src/main/java/org/eigenbase/sql/parser/SqlParserUtil.java
+++ b/core/src/main/java/org/eigenbase/sql/parser/SqlParserUtil.java
@@ -22,6 +22,7 @@ import java.text.*;
import java.util.*;
import java.util.logging.*;
+import org.eigenbase.reltype.RelDataTypeSystem;
import org.eigenbase.sql.*;
import org.eigenbase.trace.*;
import org.eigenbase.util.*;
@@ -135,7 +136,7 @@ public final class SqlParserUtil {
int[] ret;
try {
ret = intervalQualifier.evaluateIntervalLiteral(literal,
- intervalQualifier.getParserPosition());
+ intervalQualifier.getParserPosition(), RelDataTypeSystem.DEFAULT);
assert ret != null;
} catch (EigenbaseContextException e) {
throw Util.newInternal(
@@ -177,7 +178,7 @@ public final class SqlParserUtil {
int[] ret;
try {
ret = intervalQualifier.evaluateIntervalLiteral(literal,
- intervalQualifier.getParserPosition());
+ intervalQualifier.getParserPosition(), RelDataTypeSystem.DEFAULT);
assert ret != null;
} catch (EigenbaseContextException e) {
throw Util.newInternal(
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/org/eigenbase/sql/type/BasicSqlType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/sql/type/BasicSqlType.java b/core/src/main/java/org/eigenbase/sql/type/BasicSqlType.java
index ab79e8f..796f45b 100644
--- a/core/src/main/java/org/eigenbase/sql/type/BasicSqlType.java
+++ b/core/src/main/java/org/eigenbase/sql/type/BasicSqlType.java
@@ -18,6 +18,7 @@ package org.eigenbase.sql.type;
import java.nio.charset.*;
+import org.eigenbase.reltype.RelDataTypeSystem;
import org.eigenbase.sql.*;
import org.eigenbase.util.*;
@@ -30,8 +31,9 @@ public class BasicSqlType extends AbstractSqlType {
//~ Instance fields --------------------------------------------------------
- private int precision;
- private int scale;
+ private final int precision;
+ private final int scale;
+ private final RelDataTypeSystem typeSystem;
private SqlCollation collation;
private SerializableCharset wrappedCharset;
@@ -43,12 +45,11 @@ public class BasicSqlType extends AbstractSqlType {
*
* @param typeName Type name
*/
- public BasicSqlType(SqlTypeName typeName) {
- super(typeName, false, null);
+ public BasicSqlType(RelDataTypeSystem typeSystem, SqlTypeName typeName) {
+ this(typeSystem, typeName, false, PRECISION_NOT_SPECIFIED,
+ SCALE_NOT_SPECIFIED);
assert typeName.allowsPrecScale(false, false)
: "typeName.allowsPrecScale(false,false), typeName=" + typeName.name();
- this.precision = PRECISION_NOT_SPECIFIED;
- this.scale = SCALE_NOT_SPECIFIED;
computeDigest();
}
@@ -57,14 +58,11 @@ public class BasicSqlType extends AbstractSqlType {
*
* @param typeName Type name
*/
- public BasicSqlType(
- SqlTypeName typeName,
+ public BasicSqlType(RelDataTypeSystem typeSystem, SqlTypeName typeName,
int precision) {
- super(typeName, false, null);
+ this(typeSystem, typeName, false, precision, SCALE_NOT_SPECIFIED);
assert typeName.allowsPrecScale(true, false)
: "typeName.allowsPrecScale(true, false)";
- this.precision = precision;
- this.scale = SCALE_NOT_SPECIFIED;
computeDigest();
}
@@ -73,15 +71,24 @@ public class BasicSqlType extends AbstractSqlType {
*
* @param typeName Type name
*/
- public BasicSqlType(
+ public BasicSqlType(RelDataTypeSystem typeSystem, SqlTypeName typeName,
+ int precision, int scale) {
+ this(typeSystem, typeName, false, precision, scale);
+ assert typeName.allowsPrecScale(true, true);
+ computeDigest();
+ }
+
+ /** Internal constructor. */
+ private BasicSqlType(
+ RelDataTypeSystem typeSystem,
SqlTypeName typeName,
+ boolean nullable,
int precision,
int scale) {
- super(typeName, false, null);
- assert typeName.allowsPrecScale(true, true);
+ super(typeName, nullable, null);
+ this.typeSystem = typeSystem;
this.precision = precision;
this.scale = scale;
- computeDigest();
}
//~ Methods ----------------------------------------------------------------
@@ -137,7 +144,7 @@ public class BasicSqlType extends AbstractSqlType {
case BIGINT:
return 19;
case DECIMAL:
- return SqlTypeName.MAX_NUMERIC_PRECISION;
+ return RelDataTypeSystem.DEFAULT.getMaxNumericPrecision(); // FIXME
case REAL:
return 7;
case FLOAT:
@@ -205,7 +212,7 @@ public class BasicSqlType extends AbstractSqlType {
// since (for instance) TIME is equivalent to TIME(0).
if (withDetail) {
// -1 means there is no default value for precision
- if (typeName.getDefaultPrecision() > -1) {
+ if (typeSystem.getDefaultPrecision(typeName) > -1) {
printPrecision = true;
}
if (typeName.getDefaultScale() > -1) {
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/org/eigenbase/sql/type/IntervalSqlType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/sql/type/IntervalSqlType.java b/core/src/main/java/org/eigenbase/sql/type/IntervalSqlType.java
index c3141f7..c82671c 100644
--- a/core/src/main/java/org/eigenbase/sql/type/IntervalSqlType.java
+++ b/core/src/main/java/org/eigenbase/sql/type/IntervalSqlType.java
@@ -19,6 +19,8 @@ package org.eigenbase.sql.type;
import org.eigenbase.reltype.*;
import org.eigenbase.sql.*;
import org.eigenbase.sql.parser.*;
+import org.eigenbase.sql.pretty.SqlPrettyWriter;
+import org.eigenbase.sql.util.SqlString;
/**
* IntervalSqlType represents a standard SQL datetime interval type.
@@ -26,6 +28,7 @@ import org.eigenbase.sql.parser.*;
public class IntervalSqlType extends AbstractSqlType {
//~ Instance fields --------------------------------------------------------
+ private final RelDataTypeSystem typeSystem;
private SqlIntervalQualifier intervalQualifier;
//~ Constructors -----------------------------------------------------------
@@ -34,14 +37,15 @@ public class IntervalSqlType extends AbstractSqlType {
* Constructs an IntervalSqlType. This should only be called from a factory
* method.
*/
- public IntervalSqlType(
+ public IntervalSqlType(RelDataTypeSystem typeSystem,
SqlIntervalQualifier intervalQualifier,
boolean isNullable) {
- super(
- intervalQualifier.isYearMonth() ? SqlTypeName.INTERVAL_YEAR_MONTH
+ super(intervalQualifier.isYearMonth()
+ ? SqlTypeName.INTERVAL_YEAR_MONTH
: SqlTypeName.INTERVAL_DAY_TIME,
isNullable,
null);
+ this.typeSystem = typeSystem;
this.intervalQualifier = intervalQualifier;
computeDigest();
}
@@ -51,7 +55,15 @@ public class IntervalSqlType extends AbstractSqlType {
// implement RelDataTypeImpl
protected void generateTypeString(StringBuilder sb, boolean withDetail) {
sb.append("INTERVAL ");
- sb.append(intervalQualifier.toString());
+ SqlDialect dialect = null;
+ dialect = SqlDialect.DUMMY;
+ SqlPrettyWriter writer = new SqlPrettyWriter(dialect);
+ writer.setAlwaysUseParentheses(false);
+ writer.setSelectListItemsOnSeparateLines(false);
+ writer.setIndentation(0);
+ intervalQualifier.unparse(writer, 0, 0);
+ final String sql = writer.toString();
+ sb.append(new SqlString(dialect, sql).getSql());
}
// implement RelDataType
@@ -88,10 +100,10 @@ public class IntervalSqlType extends AbstractSqlType {
int secondPrec =
this.intervalQualifier.getStartPrecisionPreservingDefault();
int fracPrec =
- SqlIntervalQualifier
- .combineFractionalSecondPrecisionPreservingDefault(
- this.intervalQualifier,
- that.intervalQualifier);
+ SqlIntervalQualifier.combineFractionalSecondPrecisionPreservingDefault(
+ typeSystem,
+ this.intervalQualifier,
+ that.intervalQualifier);
if (thisStart.ordinal() > thatStart.ordinal()) {
thisEnd = thisStart;
@@ -101,17 +113,15 @@ public class IntervalSqlType extends AbstractSqlType {
} else if (thisStart.ordinal() == thatStart.ordinal()) {
secondPrec =
SqlIntervalQualifier.combineStartPrecisionPreservingDefault(
+ typeFactory.getTypeSystem(),
this.intervalQualifier,
that.intervalQualifier);
- } else if (
- (null == thisEnd)
- || (thisEnd.ordinal() < thatStart.ordinal())) {
+ } else if (null == thisEnd || thisEnd.ordinal() < thatStart.ordinal()) {
thisEnd = thatStart;
}
if (null != thatEnd) {
- if ((null == thisEnd)
- || (thisEnd.ordinal() < thatEnd.ordinal())) {
+ if (null == thisEnd || thisEnd.ordinal() < thatEnd.ordinal()) {
thisEnd = thatEnd;
}
}
@@ -131,17 +141,14 @@ public class IntervalSqlType extends AbstractSqlType {
return (IntervalSqlType) intervalType;
}
- // implement RelDataType
- public int getPrecision() {
- return intervalQualifier.getStartPrecision();
+ @Override public int getPrecision() {
+ return intervalQualifier.getStartPrecision(typeSystem);
}
@Override
public int getScale() {
- // TODO Auto-generated method stub
- return intervalQualifier.getFractionalSecondPrecision();
+ return intervalQualifier.getFractionalSecondPrecision(typeSystem);
}
-
}
// End IntervalSqlType.java
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/org/eigenbase/sql/type/ReturnTypes.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/sql/type/ReturnTypes.java b/core/src/main/java/org/eigenbase/sql/type/ReturnTypes.java
index 573c36c..55c2893 100644
--- a/core/src/main/java/org/eigenbase/sql/type/ReturnTypes.java
+++ b/core/src/main/java/org/eigenbase/sql/type/ReturnTypes.java
@@ -468,23 +468,21 @@ public abstract class ReturnTypes {
int s1 = type1.getScale();
int s2 = type2.getScale();
+ final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
int scale = Math.max(s1, s2);
- assert scale <= SqlTypeName.MAX_NUMERIC_SCALE;
+ final RelDataTypeSystem typeSystem = typeFactory.getTypeSystem();
+ assert scale <= typeSystem.getMaxNumericScale();
int precision = Math.max(p1 - s1, p2 - s2) + scale + 1;
precision =
Math.min(
precision,
- SqlTypeName.MAX_NUMERIC_PRECISION);
+ typeSystem.getMaxNumericPrecision());
assert precision > 0;
- RelDataType ret;
- ret =
- opBinding.getTypeFactory().createSqlType(
- SqlTypeName.DECIMAL,
- precision,
- scale);
-
- return ret;
+ return typeFactory.createSqlType(
+ SqlTypeName.DECIMAL,
+ precision,
+ scale);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/0fd4e3d9/core/src/main/java/org/eigenbase/sql/type/SqlTypeFactoryImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/sql/type/SqlTypeFactoryImpl.java b/core/src/main/java/org/eigenbase/sql/type/SqlTypeFactoryImpl.java
index 71ccbf9..04110b8 100644
--- a/core/src/main/java/org/eigenbase/sql/type/SqlTypeFactoryImpl.java
+++ b/core/src/main/java/org/eigenbase/sql/type/SqlTypeFactoryImpl.java
@@ -24,13 +24,14 @@ import org.eigenbase.sql.*;
import org.eigenbase.util.*;
/**
- * SqlTypeFactoryImpl provides a default implementation of {@link
- * RelDataTypeFactory} which supports SQL types.
+ * SqlTypeFactoryImpl provides a default implementation of
+ * {@link RelDataTypeFactory} which supports SQL types.
*/
public class SqlTypeFactoryImpl extends RelDataTypeFactoryImpl {
//~ Constructors -----------------------------------------------------------
- public SqlTypeFactoryImpl() {
+ public SqlTypeFactoryImpl(RelDataTypeSystem typeSystem) {
+ super(typeSystem);
}
//~ Methods ----------------------------------------------------------------
@@ -38,10 +39,10 @@ public class SqlTypeFactoryImpl extends RelDataTypeFactoryImpl {
// implement RelDataTypeFactory
public RelDataType createSqlType(SqlTypeName typeName) {
if (typeName.allowsPrec()) {
- return createSqlType(typeName, typeName.getDefaultPrecision());
+ return createSqlType(typeName, typeSystem.getDefaultPrecision(typeName));
}
assertBasic(typeName);
- RelDataType newType = new BasicSqlType(typeName);
+ RelDataType newType = new BasicSqlType(typeSystem, typeName);
return canonize(newType);
}
@@ -55,7 +56,7 @@ public class SqlTypeFactoryImpl extends RelDataTypeFactoryImpl {
assertBasic(typeName);
assert (precision >= 0)
|| (precision == RelDataType.PRECISION_NOT_SPECIFIED);
- RelDataType newType = new BasicSqlType(typeName, precision);
+ RelDataType newType = new BasicSqlType(typeSystem, typeName, precision);
newType = SqlTypeUtil.addCharsetAndCollation(newType, this);
return canonize(newType);
}
@@ -68,7 +69,8 @@ public class SqlTypeFactoryImpl extends RelDataTypeFactoryImpl {
assertBasic(typeName);
assert (precision >= 0)
|| (precision == RelDataType.PRECISION_NOT_SPECIFIED);
- RelDataType newType = new BasicSqlType(typeName, precision, scale);
+ RelDataType newType =
+ new BasicSqlType(typeSystem, typeName, precision, scale);
newType = SqlTypeUtil.addCharsetAndCollation(newType, this);
return canonize(newType);
}
@@ -100,7 +102,8 @@ public class SqlTypeFactoryImpl extends RelDataTypeFactoryImpl {
// implement RelDataTypeFactory
public RelDataType createSqlIntervalType(
SqlIntervalQualifier intervalQualifier) {
- RelDataType newType = new IntervalSqlType(intervalQualifier, false);
+ RelDataType newType =
+ new IntervalSqlType(typeSystem, intervalQualifier, false);
return canonize(newType);
}
@@ -339,23 +342,24 @@ public class SqlTypeFactoryImpl extends RelDataTypeFactoryImpl {
int p2 = type.getPrecision();
int s1 = resultType.getScale();
int s2 = type.getScale();
+ final int maxPrecision = typeSystem.getMaxNumericPrecision();
+ final int maxScale = typeSystem.getMaxNumericScale();
int dout = Math.max(p1 - s1, p2 - s2);
dout =
Math.min(
dout,
- SqlTypeName.MAX_NUMERIC_PRECISION);
+ maxPrecision);
int scale = Math.max(s1, s2);
scale =
Math.min(
scale,
- SqlTypeName.MAX_NUMERIC_PRECISION - dout);
- scale =
- Math.min(scale, SqlTypeName.MAX_NUMERIC_SCALE);
+ maxPrecision - dout);
+ scale = Math.min(scale, maxScale);
int precision = dout + scale;
- assert precision <= SqlTypeName.MAX_NUMERIC_PRECISION;
+ assert precision <= maxPrecision;
assert precision > 0;
resultType =
@@ -461,7 +465,7 @@ public class SqlTypeFactoryImpl extends RelDataTypeFactoryImpl {
}
private RelDataType copyIntervalType(RelDataType type, boolean nullable) {
- return new IntervalSqlType(
+ return new IntervalSqlType(typeSystem,
type.getIntervalQualifier(),
nullable);
}