You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by vl...@apache.org on 2014/11/30 14:46:22 UTC
incubator-calcite git commit: [CALCITE-488] - Enumerable
where Holder is custom class with a single field does not work Calcite tries
to treat it as SCALAR due to "premature" JavaRowFormat.optimize
Repository: incubator-calcite
Updated Branches:
refs/heads/master 55aa593b7 -> 28fd9c8b9
[CALCITE-488] - Enumerable<Holder> where Holder is custom class with a single field does not work
Calcite tries to treat it as SCALAR due to "premature" JavaRowFormat.optimize
Project: http://git-wip-us.apache.org/repos/asf/incubator-calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-calcite/commit/28fd9c8b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-calcite/tree/28fd9c8b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-calcite/diff/28fd9c8b
Branch: refs/heads/master
Commit: 28fd9c8b991ff30d3657bc56a0f2c1b84261aac4
Parents: 55aa593
Author: Vladimir Sitnikov <si...@gmail.com>
Authored: Sun Nov 30 16:45:38 2014 +0300
Committer: Vladimir Sitnikov <si...@gmail.com>
Committed: Sun Nov 30 16:45:38 2014 +0300
----------------------------------------------------------------------
.../adapter/enumerable/EnumerableTableScan.java | 52 ++++++++------------
.../adapter/enumerable/JavaRowFormat.java | 31 ++++++++++++
.../org/apache/calcite/util/BuiltInMethod.java | 1 +
.../calcite/test/ReflectiveSchemaTest.java | 52 ++++++++++++++++++++
4 files changed, 105 insertions(+), 31 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/28fd9c8b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableScan.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableScan.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableScan.java
index 7eb30f1..641d9cf 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableScan.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableScan.java
@@ -17,7 +17,6 @@
package org.apache.calcite.adapter.enumerable;
import org.apache.calcite.interpreter.Row;
-import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
import org.apache.calcite.linq4j.Enumerable;
import org.apache.calcite.linq4j.Queryable;
import org.apache.calcite.linq4j.function.Function1;
@@ -25,6 +24,7 @@ import org.apache.calcite.linq4j.tree.Blocks;
import org.apache.calcite.linq4j.tree.Expression;
import org.apache.calcite.linq4j.tree.Expressions;
import org.apache.calcite.linq4j.tree.ParameterExpression;
+import org.apache.calcite.linq4j.tree.Primitive;
import org.apache.calcite.linq4j.tree.Types;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelOptTable;
@@ -82,38 +82,17 @@ public class EnumerableTableScan
}
private Expression toRows(PhysType physType, Expression expression) {
+ JavaRowFormat oldFormat = format();
+ if (physType.getFormat() == oldFormat) {
+ return expression;
+ }
final ParameterExpression row_ =
Expressions.parameter(elementType, "row");
- List<Expression> expressionList = new ArrayList<Expression>();
final int fieldCount = table.getRowType().getFieldCount();
- if (elementType == Row.class) {
- // Convert Enumerable<Row> to Enumerable<SyntheticRecord>
- for (int i = 0; i < fieldCount; i++) {
- expressionList.add(
- RexToLixTranslator.convert(
- Expressions.call(row_,
- BuiltInMethod.ROW_VALUE.method,
- Expressions.constant(i)),
- physType.getJavaFieldType(i)));
- }
- } else if (elementType == Object[].class
- && rowType.getFieldCount() == 1) {
- // Convert Enumerable<Object[]> to Enumerable<SyntheticRecord>
- for (int i = 0; i < fieldCount; i++) {
- expressionList.add(
- RexToLixTranslator.convert(
- Expressions.arrayIndex(row_, Expressions.constant(i)),
- physType.getJavaFieldType(i)));
- }
- } else if (elementType == Object.class) {
- if (!(physType.getJavaRowType()
- instanceof JavaTypeFactoryImpl.SyntheticRecordType)) {
- return expression;
- }
+ List<Expression> expressionList = new ArrayList<Expression>(fieldCount);
+ for (int i = 0; i < fieldCount; i++) {
expressionList.add(
- RexToLixTranslator.convert(row_, physType.getJavaFieldType(0)));
- } else {
- return expression;
+ oldFormat.field(row_, i, physType.getJavaFieldType(i)));
}
return Expressions.call(expression,
BuiltInMethod.SELECT.method,
@@ -124,9 +103,20 @@ public class EnumerableTableScan
private JavaRowFormat format() {
if (Object[].class.isAssignableFrom(elementType)) {
return JavaRowFormat.ARRAY;
- } else {
- return JavaRowFormat.CUSTOM;
}
+ if (Row.class.isAssignableFrom(elementType)) {
+ return JavaRowFormat.ROW;
+ }
+ int fieldCount = getRowType().getFieldCount();
+ if (fieldCount == 0) {
+ return JavaRowFormat.LIST;
+ }
+ if (fieldCount == 1 && (Object.class == elementType
+ || Primitive.is(elementType)
+ || Number.class.isAssignableFrom(elementType))) {
+ return JavaRowFormat.SCALAR;
+ }
+ return JavaRowFormat.CUSTOM;
}
@Override public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/28fd9c8b/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRowFormat.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRowFormat.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRowFormat.java
index 1144444..15dba2a 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRowFormat.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRowFormat.java
@@ -17,6 +17,7 @@
package org.apache.calcite.adapter.enumerable;
import org.apache.calcite.adapter.java.JavaTypeFactory;
+import org.apache.calcite.interpreter.Row;
import org.apache.calcite.linq4j.tree.Expression;
import org.apache.calcite.linq4j.tree.ExpressionType;
import org.apache.calcite.linq4j.tree.Expressions;
@@ -166,6 +167,36 @@ public enum JavaRowFormat {
}
},
+ /**
+ * See {@link org.apache.calcite.interpreter.Row}
+ */
+ ROW {
+ @Override
+ Type javaRowClass(JavaTypeFactory typeFactory, RelDataType type) {
+ return Row.class;
+ }
+
+ @Override
+ Type javaFieldClass(JavaTypeFactory typeFactory, RelDataType type,
+ int index) {
+ return Object.class;
+ }
+
+ @Override
+ public Expression record(Type javaRowClass, List<Expression> expressions) {
+ return Expressions.call(BuiltInMethod.ROW_AS_COPY.method, expressions);
+ }
+
+ @Override
+ public Expression field(Expression expression, int field, Type fieldType) {
+ return RexToLixTranslator.convert(
+ Expressions.call(expression,
+ BuiltInMethod.ROW_VALUE.method,
+ Expressions.constant(field)),
+ fieldType);
+ }
+ },
+
ARRAY {
Type javaRowClass(
JavaTypeFactory typeFactory,
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/28fd9c8b/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java b/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
index b60e980..98e0007 100644
--- a/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
+++ b/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
@@ -113,6 +113,7 @@ public enum BuiltInMethod {
DATA_CONTEXT_GET_ROOT_SCHEMA(DataContext.class, "getRootSchema"),
JDBC_SCHEMA_DATA_SOURCE(JdbcSchema.class, "getDataSource"),
ROW_VALUE(Row.class, "getObject", int.class),
+ ROW_AS_COPY(Row.class, "asCopy", Object[].class),
RESULT_SET_ENUMERABLE_OF(ResultSetEnumerable.class, "of", DataSource.class,
String.class, Function1.class),
JOIN(ExtendedEnumerable.class, "join", Enumerable.class, Function1.class,
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/28fd9c8b/core/src/test/java/org/apache/calcite/test/ReflectiveSchemaTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/ReflectiveSchemaTest.java b/core/src/test/java/org/apache/calcite/test/ReflectiveSchemaTest.java
index 0ff6ebc..30e2fb5 100644
--- a/core/src/test/java/org/apache/calcite/test/ReflectiveSchemaTest.java
+++ b/core/src/test/java/org/apache/calcite/test/ReflectiveSchemaTest.java
@@ -495,6 +495,40 @@ public class ReflectiveSchemaTest {
+ "empid=4; deptno=10; name=Abd; salary=0.0; commission=null\n");
}
+ /** Table with single field as Integer[] */
+ @Ignore(
+ "java.lang.AssertionError RelDataTypeImpl.getFieldList(RelDataTypeImpl.java:99)")
+ @Test public void testArrayOfBoxedPrimitives() {
+ CalciteAssert.that()
+ .with("s", new CatchallSchema())
+ .query("select * from \"s\".\"primesBoxed\"")
+ .returnsUnordered("value=1", "value=3", "value=7");
+ }
+
+ /** Table with single field as int[] */
+ @Ignore(
+ "java.lang.AssertionError RelDataTypeImpl.getFieldList(RelDataTypeImpl.java:99)")
+ @Test public void testArrayOfPrimitives() {
+ CalciteAssert.that()
+ .with("s", new CatchallSchema())
+ .query("select * from \"s\".\"primes\"")
+ .returnsUnordered("value=1", "value=3", "value=7");
+ }
+
+ @Test public void testCustomBoxedScalar() {
+ CalciteAssert.that()
+ .with("s", new ReflectiveSchemaTest.CatchallSchema())
+ .query("select \"value\" from \"s\".\"primesCustomBoxed\"")
+ .returnsUnordered("value=1", "value=3", "value=5");
+ }
+
+ @Test public void testCustomBoxedSalarCalc() {
+ CalciteAssert.that()
+ .with("s", new ReflectiveSchemaTest.CatchallSchema())
+ .query("select \"value\"*2 \"value\" from \"s\".\"primesCustomBoxed\"")
+ .returnsUnordered("value=2", "value=6", "value=10");
+ }
+
/** Extension to {@link Employee} with a {@code hireDate} column. */
public static class EmployeeWithHireDate extends Employee {
public final java.sql.Date hireDate;
@@ -638,6 +672,24 @@ public class ReflectiveSchemaTest {
new Employee(3, 10, "Abc", 0f, null),
new Employee(4, 10, "Abd", 0f, null),
};
+
+ public final Integer[] primesBoxed = new Integer[]{1, 3, 5};
+
+ public final int[] primes = new int[]{1, 3, 5};
+
+ public final IntHolder[] primesCustomBoxed =
+ new IntHolder[]{new IntHolder(1), new IntHolder(3), new IntHolder(5)};
+ }
+
+ /**
+ * Custom java class that holds just a single field.
+ */
+ public static class IntHolder {
+ public final int value;
+
+ public IntHolder(int value) {
+ this.value = value;
+ }
}
/** Schema that contains a table with a date column. */