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/11/14 22:32:57 UTC
[49/58] [abbrv] [partial] incubator-calcite git commit: [CALCITE-306]
Standardize code style for "import package.*; "
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableCalc.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableCalc.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableCalc.java
new file mode 100644
index 0000000..69afcb4
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableCalc.java
@@ -0,0 +1,221 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.adapter.java.JavaTypeFactory;
+import org.apache.calcite.linq4j.Enumerator;
+import org.apache.calcite.linq4j.tree.BlockBuilder;
+import org.apache.calcite.linq4j.tree.BlockStatement;
+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.MemberDeclaration;
+import org.apache.calcite.linq4j.tree.ParameterExpression;
+import org.apache.calcite.linq4j.tree.Types;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.Calc;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexProgram;
+import org.apache.calcite.util.BuiltInMethod;
+import org.apache.calcite.util.Pair;
+
+import com.google.common.collect.ImmutableList;
+
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.List;
+
+import static org.apache.calcite.adapter.enumerable.EnumUtils.BRIDGE_METHODS;
+import static org.apache.calcite.adapter.enumerable.EnumUtils.NO_EXPRS;
+import static org.apache.calcite.adapter.enumerable.EnumUtils.NO_PARAMS;
+
+/** Implementation of {@link org.apache.calcite.rel.core.Calc} in
+ * {@link org.apache.calcite.adapter.enumerable.EnumerableConvention enumerable calling convention}. */
+public class EnumerableCalc extends Calc implements EnumerableRel {
+ public EnumerableCalc(
+ RelOptCluster cluster,
+ RelTraitSet traitSet,
+ RelNode child,
+ RelDataType rowType,
+ RexProgram program,
+ List<RelCollation> collationList) {
+ super(cluster, traitSet, child, rowType, program, collationList);
+ assert getConvention() instanceof EnumerableConvention;
+ assert !program.containsAggs();
+ }
+
+ @Override public EnumerableCalc copy(RelTraitSet traitSet, RelNode child,
+ RexProgram program, List<RelCollation> collationList) {
+ // we do not need to copy program; it is immutable
+ return new EnumerableCalc(getCluster(), traitSet, child,
+ program.getOutputRowType(), program, collationList);
+ }
+
+ public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
+ final JavaTypeFactory typeFactory = implementor.getTypeFactory();
+ final BlockBuilder builder = new BlockBuilder();
+ final EnumerableRel child = (EnumerableRel) getInput();
+
+ final Result result =
+ implementor.visitChild(this, 0, child, pref);
+
+ final PhysType physType =
+ PhysTypeImpl.of(
+ typeFactory, getRowType(), pref.prefer(result.format));
+
+ // final Enumerable<Employee> inputEnumerable = <<child adapter>>;
+ // return new Enumerable<IntString>() {
+ // Enumerator<IntString> enumerator() {
+ // return new Enumerator<IntString>() {
+ // public void reset() {
+ // ...
+ Type outputJavaType = physType.getJavaRowType();
+ final Type enumeratorType =
+ Types.of(
+ Enumerator.class, outputJavaType);
+ Type inputJavaType = result.physType.getJavaRowType();
+ ParameterExpression inputEnumerator =
+ Expressions.parameter(
+ Types.of(
+ Enumerator.class, inputJavaType),
+ "inputEnumerator");
+ Expression input =
+ RexToLixTranslator.convert(
+ Expressions.call(
+ inputEnumerator,
+ BuiltInMethod.ENUMERATOR_CURRENT.method),
+ inputJavaType);
+
+ BlockStatement moveNextBody;
+ if (program.getCondition() == null) {
+ moveNextBody =
+ Blocks.toFunctionBlock(
+ Expressions.call(
+ inputEnumerator,
+ BuiltInMethod.ENUMERATOR_MOVE_NEXT.method));
+ } else {
+ final BlockBuilder builder2 = new BlockBuilder();
+ Expression condition =
+ RexToLixTranslator.translateCondition(
+ program,
+ typeFactory,
+ builder2,
+ new RexToLixTranslator.InputGetterImpl(
+ Collections.singletonList(
+ Pair.of(input, result.physType))));
+ builder2.add(
+ Expressions.ifThen(
+ condition,
+ Expressions.return_(
+ null, Expressions.constant(true))));
+ moveNextBody =
+ Expressions.block(
+ Expressions.while_(
+ Expressions.call(
+ inputEnumerator,
+ BuiltInMethod.ENUMERATOR_MOVE_NEXT.method),
+ builder2.toBlock()),
+ Expressions.return_(
+ null,
+ Expressions.constant(false)));
+ }
+
+ final BlockBuilder builder3 = new BlockBuilder();
+ List<Expression> expressions =
+ RexToLixTranslator.translateProjects(
+ program,
+ typeFactory,
+ builder3,
+ physType,
+ new RexToLixTranslator.InputGetterImpl(
+ Collections.singletonList(
+ Pair.of(input, result.physType))));
+ builder3.add(
+ Expressions.return_(
+ null, physType.record(expressions)));
+ BlockStatement currentBody =
+ builder3.toBlock();
+
+ final Expression inputEnumerable =
+ builder.append(
+ "inputEnumerable", result.block, false);
+ final Expression body =
+ Expressions.new_(
+ enumeratorType,
+ NO_EXPRS,
+ Expressions.<MemberDeclaration>list(
+ Expressions.fieldDecl(
+ Modifier.PUBLIC
+ | Modifier.FINAL,
+ inputEnumerator,
+ Expressions.call(
+ inputEnumerable,
+ BuiltInMethod.ENUMERABLE_ENUMERATOR.method)),
+ EnumUtils.overridingMethodDecl(
+ BuiltInMethod.ENUMERATOR_RESET.method,
+ NO_PARAMS,
+ Blocks.toFunctionBlock(
+ Expressions.call(
+ inputEnumerator,
+ BuiltInMethod.ENUMERATOR_RESET.method))),
+ EnumUtils.overridingMethodDecl(
+ BuiltInMethod.ENUMERATOR_MOVE_NEXT.method,
+ NO_PARAMS,
+ moveNextBody),
+ EnumUtils.overridingMethodDecl(
+ BuiltInMethod.ENUMERATOR_CLOSE.method,
+ NO_PARAMS,
+ Blocks.toFunctionBlock(
+ Expressions.call(
+ inputEnumerator,
+ BuiltInMethod.ENUMERATOR_CLOSE.method))),
+ Expressions.methodDecl(
+ Modifier.PUBLIC,
+ BRIDGE_METHODS
+ ? Object.class
+ : outputJavaType,
+ "current",
+ NO_PARAMS,
+ currentBody)));
+ builder.add(
+ Expressions.return_(
+ null,
+ Expressions.new_(
+ BuiltInMethod.ABSTRACT_ENUMERABLE_CTOR.constructor,
+ // TODO: generics
+ // Collections.singletonList(inputRowType),
+ NO_EXPRS,
+ ImmutableList.<MemberDeclaration>of(
+ Expressions.methodDecl(
+ Modifier.PUBLIC,
+ enumeratorType,
+ BuiltInMethod.ENUMERABLE_ENUMERATOR.method.getName(),
+ NO_PARAMS,
+ Blocks.toFunctionBlock(body))))));
+ return implementor.result(physType, builder.toBlock());
+ }
+
+ public RexProgram getProgram() {
+ return program;
+ }
+}
+
+// End EnumerableCalc.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableCalcRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableCalcRule.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableCalcRule.java
new file mode 100644
index 0000000..05d907a
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableCalcRule.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.plan.Convention;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.convert.ConverterRule;
+import org.apache.calcite.rel.logical.LogicalCalc;
+import org.apache.calcite.rex.RexMultisetUtil;
+import org.apache.calcite.rex.RexProgram;
+
+/**
+ * Rule to convert a {@link org.apache.calcite.rel.logical.LogicalCalc} to an
+ * {@link EnumerableCalc}.
+ */
+class EnumerableCalcRule extends ConverterRule {
+ EnumerableCalcRule() {
+ super(LogicalCalc.class, Convention.NONE, EnumerableConvention.INSTANCE,
+ "EnumerableCalcRule");
+ }
+
+ public RelNode convert(RelNode rel) {
+ final LogicalCalc calc = (LogicalCalc) rel;
+
+ // If there's a multiset, let FarragoMultisetSplitter work on it
+ // first.
+ final RexProgram program = calc.getProgram();
+ if (EnumUtils.B
+ && RexMultisetUtil.containsMultiset(program)
+ || program.containsAggs()) {
+ return null;
+ }
+
+ return new EnumerableCalc(
+ rel.getCluster(),
+ rel.getTraitSet().replace(EnumerableConvention.INSTANCE),
+ convert(
+ calc.getInput(),
+ calc.getInput().getTraitSet()
+ .replace(EnumerableConvention.INSTANCE)),
+ calc.getRowType(),
+ program,
+ calc.getCollationList());
+ }
+}
+
+// End EnumerableCalcRule.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableCollect.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableCollect.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableCollect.java
new file mode 100644
index 0000000..99c2a1a
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableCollect.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.linq4j.tree.BlockBuilder;
+import org.apache.calcite.linq4j.tree.Expression;
+import org.apache.calcite.linq4j.tree.Expressions;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.Collect;
+import org.apache.calcite.util.BuiltInMethod;
+
+/** Implementation of {@link org.apache.calcite.rel.core.Collect} in
+ * {@link org.apache.calcite.adapter.enumerable.EnumerableConvention enumerable calling convention}. */
+public class EnumerableCollect extends Collect implements EnumerableRel {
+ public EnumerableCollect(RelOptCluster cluster, RelTraitSet traitSet,
+ RelNode child, String fieldName) {
+ super(cluster, traitSet, child, fieldName);
+ assert getConvention() instanceof EnumerableConvention;
+ assert getConvention() == child.getConvention();
+ }
+
+ @Override public EnumerableCollect copy(RelTraitSet traitSet,
+ RelNode newInput) {
+ return new EnumerableCollect(getCluster(), traitSet, newInput, fieldName);
+ }
+
+ public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
+ final BlockBuilder builder = new BlockBuilder();
+ final EnumerableRel child = (EnumerableRel) getInput();
+ final Result result = implementor.visitChild(this, 0, child, pref);
+ final PhysType physType =
+ PhysTypeImpl.of(
+ implementor.getTypeFactory(),
+ getRowType(),
+ result.format);
+
+ // final Enumerable<Employee> child = <<child adapter>>;
+ // final List<Employee> list = child.toList();
+ Expression child_ =
+ builder.append(
+ "child", result.block);
+ Expression list_ =
+ builder.append("list",
+ Expressions.call(child_,
+ BuiltInMethod.ENUMERABLE_TO_LIST.method));
+
+ builder.add(
+ Expressions.return_(null,
+ Expressions.call(
+ BuiltInMethod.SINGLETON_ENUMERABLE.method, list_)));
+ return implementor.result(physType, builder.toBlock());
+ }
+}
+
+// End EnumerableCollect.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableCollectRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableCollectRule.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableCollectRule.java
new file mode 100644
index 0000000..4ab49b4
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableCollectRule.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.plan.Convention;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.convert.ConverterRule;
+import org.apache.calcite.rel.core.Collect;
+
+/**
+ * Rule to convert an {@link org.apache.calcite.rel.core.Collect} to an
+ * {@link EnumerableCollect}.
+ */
+class EnumerableCollectRule extends ConverterRule {
+ EnumerableCollectRule() {
+ super(Collect.class, Convention.NONE, EnumerableConvention.INSTANCE,
+ "EnumerableCollectRule");
+ }
+
+ public RelNode convert(RelNode rel) {
+ final Collect collect = (Collect) rel;
+ final RelTraitSet traitSet =
+ collect.getTraitSet().replace(EnumerableConvention.INSTANCE);
+ final RelNode input = collect.getInput();
+ return new EnumerableCollect(
+ rel.getCluster(),
+ traitSet,
+ convert(input,
+ input.getTraitSet().replace(EnumerableConvention.INSTANCE)),
+ collect.getFieldName());
+ }
+}
+
+// End EnumerableCollectRule.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableConvention.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableConvention.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableConvention.java
index 7a5cceb..a8ad841 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableConvention.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableConvention.java
@@ -14,19 +14,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.hydromatic.optiq.rules.java;
+package org.apache.calcite.adapter.enumerable;
-import org.eigenbase.relopt.*;
+import org.apache.calcite.plan.Convention;
+import org.apache.calcite.plan.ConventionTraitDef;
+import org.apache.calcite.plan.RelOptPlanner;
+import org.apache.calcite.plan.RelTrait;
+import org.apache.calcite.plan.RelTraitDef;
/**
* Family of calling conventions that return results as an
- * {@link net.hydromatic.linq4j.Enumerable}.
+ * {@link org.apache.calcite.linq4j.Enumerable}.
*/
public enum EnumerableConvention implements Convention {
INSTANCE;
- @Override
- public String toString() {
+ @Override public String toString() {
return getName();
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableEmptyRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableEmptyRule.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableEmptyRule.java
new file mode 100644
index 0000000..8f57d84
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableEmptyRule.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.plan.Convention;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.convert.ConverterRule;
+import org.apache.calcite.rel.core.Empty;
+import org.apache.calcite.rex.RexLiteral;
+
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+/** Planner rule that converts an {@link org.apache.calcite.rel.core.Empty}
+ * relational expression
+ * {@link org.apache.calcite.adapter.enumerable.EnumerableConvention enumerable calling convention}. */
+public class EnumerableEmptyRule extends ConverterRule {
+ EnumerableEmptyRule() {
+ super(Empty.class, Convention.NONE, EnumerableConvention.INSTANCE,
+ "EnumerableEmptyRule");
+ }
+
+ public RelNode convert(RelNode rel) {
+ Empty empty = (Empty) rel;
+ return new EnumerableValues(
+ empty.getCluster(),
+ empty.getRowType(),
+ ImmutableList.<List<RexLiteral>>of(),
+ empty.getTraitSet().replace(EnumerableConvention.INSTANCE));
+ }
+}
+
+// End EnumerableEmptyRule.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableFilter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableFilter.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableFilter.java
new file mode 100644
index 0000000..ae68216
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableFilter.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.Filter;
+import org.apache.calcite.rex.RexNode;
+
+/** Implementation of {@link org.apache.calcite.rel.core.Filter} in
+ * {@link org.apache.calcite.adapter.enumerable.EnumerableConvention enumerable calling convention}. */
+public class EnumerableFilter
+ extends Filter
+ implements EnumerableRel {
+ public EnumerableFilter(
+ RelOptCluster cluster,
+ RelTraitSet traitSet,
+ RelNode child,
+ RexNode condition) {
+ super(cluster, traitSet, child, condition);
+ assert getConvention() instanceof EnumerableConvention;
+ }
+
+ public EnumerableFilter copy(RelTraitSet traitSet, RelNode input,
+ RexNode condition) {
+ return new EnumerableFilter(getCluster(), traitSet, input, condition);
+ }
+
+ public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
+ // EnumerableCalc is always better
+ throw new UnsupportedOperationException();
+ }
+}
+
+// End EnumerableFilter.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableFilterRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableFilterRule.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableFilterRule.java
new file mode 100644
index 0000000..81bbaf2
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableFilterRule.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.plan.Convention;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.convert.ConverterRule;
+import org.apache.calcite.rel.logical.LogicalFilter;
+import org.apache.calcite.rex.RexMultisetUtil;
+import org.apache.calcite.rex.RexOver;
+
+/**
+ * Rule to convert a {@link org.apache.calcite.rel.logical.LogicalFilter} to an
+ * {@link EnumerableFilter}.
+ */
+class EnumerableFilterRule extends ConverterRule {
+ EnumerableFilterRule() {
+ super(LogicalFilter.class, Convention.NONE, EnumerableConvention.INSTANCE,
+ "EnumerableFilterRule");
+ }
+
+ public RelNode convert(RelNode rel) {
+ final LogicalFilter filter = (LogicalFilter) rel;
+
+ if (EnumUtils.B
+ && RexMultisetUtil.containsMultiset(filter.getCondition(), true)
+ || RexOver.containsOver(filter.getCondition())) {
+ return null;
+ }
+
+ return new EnumerableFilter(
+ rel.getCluster(),
+ rel.getTraitSet().replace(EnumerableConvention.INSTANCE),
+ convert(
+ filter.getInput(),
+ filter.getInput().getTraitSet()
+ .replace(EnumerableConvention.INSTANCE)),
+ filter.getCondition());
+ }
+}
+
+// End EnumerableFilterRule.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableFilterToCalcRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableFilterToCalcRule.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableFilterToCalcRule.java
new file mode 100644
index 0000000..901dc6b
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableFilterToCalcRule.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptRuleCall;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexBuilder;
+import org.apache.calcite.rex.RexProgram;
+import org.apache.calcite.rex.RexProgramBuilder;
+
+import com.google.common.collect.ImmutableList;
+
+/** Variant of {@link org.apache.calcite.rel.rules.FilterToCalcRule} for
+ * {@link org.apache.calcite.adapter.enumerable.EnumerableConvention enumerable calling convention}. */
+public class EnumerableFilterToCalcRule extends RelOptRule {
+ EnumerableFilterToCalcRule() {
+ super(operand(EnumerableFilter.class, any()));
+ }
+
+ public void onMatch(RelOptRuleCall call) {
+ final EnumerableFilter filter = call.rel(0);
+ final RelNode rel = filter.getInput();
+
+ // Create a program containing a filter.
+ final RexBuilder rexBuilder = filter.getCluster().getRexBuilder();
+ final RelDataType inputRowType = rel.getRowType();
+ final RexProgramBuilder programBuilder =
+ new RexProgramBuilder(inputRowType, rexBuilder);
+ programBuilder.addIdentity();
+ programBuilder.addCondition(filter.getCondition());
+ final RexProgram program = programBuilder.getProgram();
+
+ final EnumerableCalc calc =
+ new EnumerableCalc(
+ filter.getCluster(),
+ filter.getTraitSet(),
+ rel,
+ inputRowType,
+ program,
+ ImmutableList.<RelCollation>of());
+ call.transformTo(calc);
+ }
+}
+
+// End EnumerableFilterToCalcRule.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableInterpreter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableInterpreter.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableInterpreter.java
new file mode 100644
index 0000000..64b0c6f
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableInterpreter.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.adapter.java.JavaTypeFactory;
+import org.apache.calcite.interpreter.Interpreter;
+import org.apache.calcite.linq4j.tree.BlockBuilder;
+import org.apache.calcite.linq4j.tree.Expression;
+import org.apache.calcite.linq4j.tree.Expressions;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelOptCost;
+import org.apache.calcite.plan.RelOptPlanner;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.SingleRel;
+import org.apache.calcite.util.BuiltInMethod;
+
+import java.util.List;
+
+/** Relational expression that executes its children using an interpreter.
+ *
+ * <p>Although quite a few kinds of {@link org.apache.calcite.rel.RelNode} can
+ * be interpreted, this is only created by default for
+ * {@link org.apache.calcite.schema.FilterableTable} and
+ * {@link org.apache.calcite.schema.ProjectableFilterableTable}.
+ */
+public class EnumerableInterpreter extends SingleRel
+ implements EnumerableRel {
+ private final double factor;
+
+ /** Creates an EnumerableInterpreterRel. */
+ public EnumerableInterpreter(RelOptCluster cluster,
+ RelTraitSet traitSet, RelNode input, double factor) {
+ super(cluster, traitSet, input);
+ this.factor = factor;
+ }
+
+ @Override public RelOptCost computeSelfCost(RelOptPlanner planner) {
+ return super.computeSelfCost(planner).multiplyBy(factor);
+ }
+
+ @Override public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
+ return new EnumerableInterpreter(getCluster(), traitSet, sole(inputs),
+ factor);
+ }
+
+ public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
+ final JavaTypeFactory typeFactory = implementor.getTypeFactory();
+ final BlockBuilder builder = new BlockBuilder();
+ final PhysType physType =
+ PhysTypeImpl.of(typeFactory, getRowType(), JavaRowFormat.ARRAY);
+ final Expression interpreter_ = builder.append("interpreter",
+ Expressions.new_(Interpreter.class,
+ implementor.getRootExpression(),
+ implementor.stash(getInput(), RelNode.class)));
+ final Expression sliced_ =
+ getRowType().getFieldCount() == 1
+ ? Expressions.call(BuiltInMethod.SLICE0.method, interpreter_)
+ : interpreter_;
+ builder.add(sliced_);
+ return implementor.result(physType, builder.toBlock());
+ }
+}
+
+// End EnumerableInterpreter.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableIntersect.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableIntersect.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableIntersect.java
new file mode 100644
index 0000000..6c74c17
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableIntersect.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.linq4j.Ord;
+import org.apache.calcite.linq4j.tree.BlockBuilder;
+import org.apache.calcite.linq4j.tree.Expression;
+import org.apache.calcite.linq4j.tree.Expressions;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.Intersect;
+import org.apache.calcite.util.BuiltInMethod;
+
+import java.util.List;
+
+/** Implementation of {@link org.apache.calcite.rel.core.Intersect} in
+ * {@link org.apache.calcite.adapter.enumerable.EnumerableConvention enumerable calling convention}. */
+public class EnumerableIntersect extends Intersect implements EnumerableRel {
+ public EnumerableIntersect(RelOptCluster cluster, RelTraitSet traitSet,
+ List<RelNode> inputs, boolean all) {
+ super(cluster, traitSet, inputs, all);
+ assert !all;
+ }
+
+ public EnumerableIntersect copy(RelTraitSet traitSet, List<RelNode> inputs,
+ boolean all) {
+ return new EnumerableIntersect(getCluster(), traitSet, inputs, all);
+ }
+
+ public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
+ final BlockBuilder builder = new BlockBuilder();
+ Expression intersectExp = null;
+ for (Ord<RelNode> ord : Ord.zip(inputs)) {
+ EnumerableRel input = (EnumerableRel) ord.e;
+ final Result result = implementor.visitChild(this, ord.i, input, pref);
+ Expression childExp =
+ builder.append(
+ "child" + ord.i,
+ result.block);
+
+ if (intersectExp == null) {
+ intersectExp = childExp;
+ } else {
+ intersectExp =
+ Expressions.call(
+ intersectExp,
+ all
+ ? BuiltInMethod.CONCAT.method
+ : BuiltInMethod.INTERSECT.method,
+ childExp);
+ }
+
+ // Once the first input has chosen its format, ask for the same for
+ // other inputs.
+ pref = pref.of(result.format);
+ }
+
+ builder.add(intersectExp);
+ final PhysType physType =
+ PhysTypeImpl.of(
+ implementor.getTypeFactory(),
+ getRowType(),
+ pref.prefer(JavaRowFormat.CUSTOM));
+ return implementor.result(physType, builder.toBlock());
+ }
+}
+
+// End EnumerableIntersect.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableIntersectRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableIntersectRule.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableIntersectRule.java
new file mode 100644
index 0000000..f906d47
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableIntersectRule.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.plan.Convention;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.convert.ConverterRule;
+import org.apache.calcite.rel.logical.LogicalIntersect;
+
+/**
+ * Rule to convert a
+ * {@link org.apache.calcite.rel.logical.LogicalIntersect} to an
+ * {@link EnumerableIntersect}.
+ */
+class EnumerableIntersectRule extends ConverterRule {
+ EnumerableIntersectRule() {
+ super(LogicalIntersect.class, Convention.NONE,
+ EnumerableConvention.INSTANCE, "EnumerableIntersectRule");
+ }
+
+ public RelNode convert(RelNode rel) {
+ final LogicalIntersect intersect = (LogicalIntersect) rel;
+ if (intersect.all) {
+ return null; // INTERSECT ALL not implemented
+ }
+ final EnumerableConvention out = EnumerableConvention.INSTANCE;
+ final RelTraitSet traitSet = intersect.getTraitSet().replace(out);
+ return new EnumerableIntersect(rel.getCluster(), traitSet,
+ convertList(intersect.getInputs(), out), false);
+ }
+}
+
+// End EnumerableIntersectRule.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoin.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoin.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoin.java
new file mode 100644
index 0000000..4508c5a
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoin.java
@@ -0,0 +1,221 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.linq4j.Ord;
+import org.apache.calcite.linq4j.function.Function2;
+import org.apache.calcite.linq4j.tree.BlockBuilder;
+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.plan.RelOptCluster;
+import org.apache.calcite.plan.RelOptCost;
+import org.apache.calcite.plan.RelOptPlanner;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.InvalidRelException;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.JoinInfo;
+import org.apache.calcite.rel.core.JoinRelType;
+import org.apache.calcite.rel.metadata.RelMetadataQuery;
+import org.apache.calcite.rel.rules.EquiJoin;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.util.BuiltInMethod;
+import org.apache.calcite.util.ImmutableIntList;
+import org.apache.calcite.util.Util;
+
+import com.google.common.collect.ImmutableList;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/** Implementation of {@link org.apache.calcite.rel.core.Join} in
+ * {@link org.apache.calcite.adapter.enumerable.EnumerableConvention enumerable calling convention}. */
+public class EnumerableJoin extends EquiJoin implements EnumerableRel {
+ EnumerableJoin(
+ RelOptCluster cluster,
+ RelTraitSet traits,
+ RelNode left,
+ RelNode right,
+ RexNode condition,
+ ImmutableIntList leftKeys,
+ ImmutableIntList rightKeys,
+ JoinRelType joinType,
+ Set<String> variablesStopped)
+ throws InvalidRelException {
+ super(
+ cluster,
+ traits,
+ left,
+ right,
+ condition,
+ leftKeys,
+ rightKeys,
+ joinType,
+ variablesStopped);
+ }
+
+ @Override public EnumerableJoin copy(RelTraitSet traitSet, RexNode condition,
+ RelNode left, RelNode right, JoinRelType joinType,
+ boolean semiJoinDone) {
+ final JoinInfo joinInfo = JoinInfo.of(left, right, condition);
+ assert joinInfo.isEqui();
+ try {
+ return new EnumerableJoin(getCluster(), traitSet, left, right,
+ condition, joinInfo.leftKeys, joinInfo.rightKeys, joinType,
+ variablesStopped);
+ } catch (InvalidRelException e) {
+ // Semantic error not possible. Must be a bug. Convert to
+ // internal error.
+ throw new AssertionError(e);
+ }
+ }
+
+ @Override public RelOptCost computeSelfCost(RelOptPlanner planner) {
+ double rowCount = RelMetadataQuery.getRowCount(this);
+
+ // Joins can be flipped, and for many algorithms, both versions are viable
+ // and have the same cost. To make the results stable between versions of
+ // the planner, make one of the versions slightly more expensive.
+ switch (joinType) {
+ case RIGHT:
+ rowCount = addEpsilon(rowCount);
+ break;
+ default:
+ if (left.getId() > right.getId()) {
+ rowCount = addEpsilon(rowCount);
+ }
+ }
+
+ // Cheaper if the smaller number of rows is coming from the LHS.
+ // Model this by adding L log L to the cost.
+ final double rightRowCount = right.getRows();
+ final double leftRowCount = left.getRows();
+ if (Double.isInfinite(leftRowCount)) {
+ rowCount = leftRowCount;
+ } else {
+ rowCount += Util.nLogN(leftRowCount);
+ }
+ if (Double.isInfinite(rightRowCount)) {
+ rowCount = rightRowCount;
+ } else {
+ rowCount += rightRowCount;
+ }
+ return planner.getCostFactory().makeCost(rowCount, 0, 0);
+ }
+
+ private double addEpsilon(double d) {
+ assert d >= 0d;
+ final double d0 = d;
+ if (d < 10) {
+ // For small d, adding 1 would change the value significantly.
+ d *= 1.001d;
+ if (d != d0) {
+ return d;
+ }
+ }
+ // For medium d, add 1. Keeps integral values integral.
+ ++d;
+ if (d != d0) {
+ return d;
+ }
+ // For large d, adding 1 might not change the value. Add .1%.
+ // If d is NaN, this still will probably not change the value. That's OK.
+ d *= 1.001d;
+ return d;
+ }
+
+ public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
+ BlockBuilder builder = new BlockBuilder();
+ final Result leftResult =
+ implementor.visitChild(this, 0, (EnumerableRel) left, pref);
+ Expression leftExpression =
+ builder.append(
+ "left", leftResult.block);
+ final Result rightResult =
+ implementor.visitChild(this, 1, (EnumerableRel) right, pref);
+ Expression rightExpression =
+ builder.append(
+ "right", rightResult.block);
+ final PhysType physType =
+ PhysTypeImpl.of(
+ implementor.getTypeFactory(), getRowType(), pref.preferArray());
+ final PhysType keyPhysType =
+ leftResult.physType.project(
+ leftKeys, JavaRowFormat.LIST);
+ return implementor.result(
+ physType,
+ builder.append(
+ Expressions.call(
+ leftExpression,
+ BuiltInMethod.JOIN.method,
+ Expressions.list(
+ rightExpression,
+ leftResult.physType.generateAccessor(leftKeys),
+ rightResult.physType.generateAccessor(rightKeys),
+ generateSelector(
+ physType,
+ ImmutableList.of(
+ leftResult.physType, rightResult.physType)))
+ .append(
+ Util.first(keyPhysType.comparer(),
+ Expressions.constant(null)))
+ .append(Expressions.constant(
+ joinType.generatesNullsOnLeft()))
+ .append(Expressions.constant(
+ joinType.generatesNullsOnRight())))).toBlock());
+ }
+
+ Expression generateSelector(PhysType physType,
+ List<PhysType> inputPhysTypes) {
+ // A parameter for each input.
+ final List<ParameterExpression> parameters =
+ new ArrayList<ParameterExpression>();
+
+ // Generate all fields.
+ final List<Expression> expressions =
+ new ArrayList<Expression>();
+ for (Ord<PhysType> ord : Ord.zip(inputPhysTypes)) {
+ final PhysType inputPhysType =
+ ord.e.makeNullable(joinType.generatesNullsOn(ord.i));
+ final ParameterExpression parameter =
+ Expressions.parameter(inputPhysType.getJavaRowType(),
+ EnumUtils.LEFT_RIGHT[ord.i]);
+ parameters.add(parameter);
+ final int fieldCount = inputPhysType.getRowType().getFieldCount();
+ for (int i = 0; i < fieldCount; i++) {
+ Expression expression =
+ inputPhysType.fieldReference(parameter, i,
+ physType.getJavaFieldType(i));
+ if (joinType.generatesNullsOn(ord.i)) {
+ expression =
+ Expressions.condition(
+ Expressions.equal(parameter, Expressions.constant(null)),
+ Expressions.constant(null),
+ expression);
+ }
+ expressions.add(expression);
+ }
+ }
+ return Expressions.lambda(
+ Function2.class,
+ physType.record(expressions),
+ parameters);
+ }
+}
+
+// End EnumerableJoin.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoinRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoinRule.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoinRule.java
new file mode 100644
index 0000000..915b635
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableJoinRule.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.plan.Convention;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.rel.InvalidRelException;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.convert.ConverterRule;
+import org.apache.calcite.rel.core.JoinInfo;
+import org.apache.calcite.rel.core.JoinRelType;
+import org.apache.calcite.rel.logical.LogicalJoin;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Planner rule that converts a
+ * {@link org.apache.calcite.rel.logical.LogicalJoin} relational expression
+ * {@link org.apache.calcite.adapter.enumerable.EnumerableConvention enumerable calling convention}. */
+class EnumerableJoinRule extends ConverterRule {
+ EnumerableJoinRule() {
+ super(
+ LogicalJoin.class,
+ Convention.NONE,
+ EnumerableConvention.INSTANCE,
+ "EnumerableJoinRule");
+ }
+
+ @Override public RelNode convert(RelNode rel) {
+ LogicalJoin join = (LogicalJoin) rel;
+ List<RelNode> newInputs = new ArrayList<RelNode>();
+ for (RelNode input : join.getInputs()) {
+ if (!(input.getConvention() instanceof EnumerableConvention)) {
+ input =
+ convert(
+ input,
+ input.getTraitSet()
+ .replace(EnumerableConvention.INSTANCE));
+ }
+ newInputs.add(input);
+ }
+ final RelNode left = newInputs.get(0);
+ final RelNode right = newInputs.get(1);
+ final JoinInfo info = JoinInfo.of(left, right, join.getCondition());
+ if (!info.isEqui() && join.getJoinType() != JoinRelType.INNER) {
+ // EnumerableJoinRel only supports equi-join. We can put a filter on top
+ // if it is an inner join.
+ return null;
+ }
+ final RelOptCluster cluster = join.getCluster();
+ RelNode newRel;
+ try {
+ newRel = new EnumerableJoin(
+ cluster,
+ join.getTraitSet().replace(EnumerableConvention.INSTANCE),
+ left,
+ right,
+ info.getEquiCondition(left, right, cluster.getRexBuilder()),
+ info.leftKeys,
+ info.rightKeys,
+ join.getJoinType(),
+ join.getVariablesStopped());
+ } catch (InvalidRelException e) {
+ EnumerableRules.LOGGER.fine(e.toString());
+ return null;
+ }
+ if (!info.isEqui()) {
+ newRel = new EnumerableFilter(cluster, newRel.getTraitSet(),
+ newRel, info.getRemaining(cluster.getRexBuilder()));
+ }
+ return newRel;
+ }
+}
+
+// End EnumerableJoinRule.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableLimit.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableLimit.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableLimit.java
new file mode 100644
index 0000000..bdbeaad
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableLimit.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.linq4j.tree.BlockBuilder;
+import org.apache.calcite.linq4j.tree.Expression;
+import org.apache.calcite.linq4j.tree.Expressions;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.RelWriter;
+import org.apache.calcite.rel.SingleRel;
+import org.apache.calcite.rex.RexLiteral;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.util.BuiltInMethod;
+
+import java.util.List;
+
+/** Relational expression that applies a limit and/or offset to its input. */
+public class EnumerableLimit extends SingleRel implements EnumerableRel {
+ private final RexNode offset;
+ private final RexNode fetch;
+
+ public EnumerableLimit(
+ RelOptCluster cluster,
+ RelTraitSet traitSet,
+ RelNode child,
+ RexNode offset,
+ RexNode fetch) {
+ super(cluster, traitSet, child);
+ this.offset = offset;
+ this.fetch = fetch;
+ assert getConvention() instanceof EnumerableConvention;
+ assert getConvention() == child.getConvention();
+ }
+
+ @Override public EnumerableLimit copy(
+ RelTraitSet traitSet,
+ List<RelNode> newInputs) {
+ return new EnumerableLimit(
+ getCluster(),
+ traitSet,
+ sole(newInputs),
+ offset,
+ fetch);
+ }
+
+ @Override public RelWriter explainTerms(RelWriter pw) {
+ return super.explainTerms(pw)
+ .itemIf("offset", offset, offset != null)
+ .itemIf("fetch", fetch, fetch != null);
+ }
+
+ public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
+ final BlockBuilder builder = new BlockBuilder();
+ final EnumerableRel child = (EnumerableRel) getInput();
+ final Result result = implementor.visitChild(this, 0, child, pref);
+ final PhysType physType =
+ PhysTypeImpl.of(
+ implementor.getTypeFactory(),
+ getRowType(),
+ result.format);
+
+ Expression v = builder.append("child", result.block);
+ if (offset != null) {
+ v = builder.append(
+ "offset",
+ Expressions.call(
+ v,
+ BuiltInMethod.SKIP.method,
+ Expressions.constant(RexLiteral.intValue(offset))));
+ }
+ if (fetch != null) {
+ v = builder.append(
+ "fetch",
+ Expressions.call(
+ v,
+ BuiltInMethod.TAKE.method,
+ Expressions.constant(RexLiteral.intValue(fetch))));
+ }
+
+ builder.add(
+ Expressions.return_(
+ null,
+ v));
+ return implementor.result(physType, builder.toBlock());
+ }
+}
+
+// End EnumerableLimit.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableLimitRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableLimitRule.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableLimitRule.java
new file mode 100644
index 0000000..4f8ab10
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableLimitRule.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptRuleCall;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.Sort;
+
+/**
+ * Rule to convert an {@link org.apache.calcite.rel.core.Sort} that has
+ * {@code offset} or {@code fetch} set to an
+ * {@link EnumerableLimit}
+ * on top of a "pure" {@code Sort} that has no offset or fetch.
+ */
+class EnumerableLimitRule extends RelOptRule {
+ EnumerableLimitRule() {
+ super(
+ operand(Sort.class, any()),
+ "EnumerableLimitRule");
+ }
+
+ @Override public void onMatch(RelOptRuleCall call) {
+ final Sort sort = call.rel(0);
+ if (sort.offset == null && sort.fetch == null) {
+ return;
+ }
+ final RelTraitSet traitSet =
+ sort.getTraitSet().replace(EnumerableConvention.INSTANCE);
+ RelNode input = sort.getInput();
+ if (!sort.getCollation().getFieldCollations().isEmpty()) {
+ // Create a sort with the same sort key, but no offset or fetch.
+ input = sort.copy(
+ sort.getTraitSet(),
+ input,
+ sort.getCollation(),
+ null,
+ null);
+ }
+ RelNode x = convert(
+ input,
+ input.getTraitSet().replace(EnumerableConvention.INSTANCE));
+ call.transformTo(
+ new EnumerableLimit(
+ sort.getCluster(),
+ traitSet,
+ x,
+ sort.offset,
+ sort.fetch));
+ }
+}
+
+// End EnumerableLimitRule.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMinus.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMinus.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMinus.java
new file mode 100644
index 0000000..c783cab
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMinus.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.linq4j.Ord;
+import org.apache.calcite.linq4j.tree.BlockBuilder;
+import org.apache.calcite.linq4j.tree.Expression;
+import org.apache.calcite.linq4j.tree.Expressions;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.Minus;
+import org.apache.calcite.util.BuiltInMethod;
+
+import java.util.List;
+
+/** Implementation of {@link org.apache.calcite.rel.core.Minus} in
+ * {@link org.apache.calcite.adapter.enumerable.EnumerableConvention enumerable calling convention}. */
+public class EnumerableMinus extends Minus implements EnumerableRel {
+ public EnumerableMinus(RelOptCluster cluster, RelTraitSet traitSet,
+ List<RelNode> inputs, boolean all) {
+ super(cluster, traitSet, inputs, all);
+ assert !all;
+ }
+
+ public EnumerableMinus copy(RelTraitSet traitSet, List<RelNode> inputs,
+ boolean all) {
+ return new EnumerableMinus(getCluster(), traitSet, inputs, all);
+ }
+
+ public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
+ final BlockBuilder builder = new BlockBuilder();
+ Expression minusExp = null;
+ for (Ord<RelNode> ord : Ord.zip(inputs)) {
+ EnumerableRel input = (EnumerableRel) ord.e;
+ final Result result = implementor.visitChild(this, ord.i, input, pref);
+ Expression childExp =
+ builder.append(
+ "child" + ord.i,
+ result.block);
+
+ if (minusExp == null) {
+ minusExp = childExp;
+ } else {
+ minusExp =
+ Expressions.call(
+ minusExp,
+ BuiltInMethod.EXCEPT.method,
+ childExp);
+ }
+
+ // Once the first input has chosen its format, ask for the same for
+ // other inputs.
+ pref = pref.of(result.format);
+ }
+
+ builder.add(minusExp);
+ final PhysType physType =
+ PhysTypeImpl.of(
+ implementor.getTypeFactory(),
+ getRowType(),
+ pref.prefer(JavaRowFormat.CUSTOM));
+ return implementor.result(physType, builder.toBlock());
+ }
+}
+
+// End EnumerableMinus.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMinusRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMinusRule.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMinusRule.java
new file mode 100644
index 0000000..4cbf263
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMinusRule.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.plan.Convention;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.convert.ConverterRule;
+import org.apache.calcite.rel.logical.LogicalMinus;
+
+/**
+ * Rule to convert an {@link org.apache.calcite.rel.logical.LogicalMinus} to an
+ * {@link EnumerableMinus}.
+ */
+class EnumerableMinusRule extends ConverterRule {
+ EnumerableMinusRule() {
+ super(LogicalMinus.class, Convention.NONE, EnumerableConvention.INSTANCE,
+ "EnumerableMinusRule");
+ }
+
+ public RelNode convert(RelNode rel) {
+ final LogicalMinus minus = (LogicalMinus) rel;
+ if (minus.all) {
+ return null; // EXCEPT ALL not implemented
+ }
+ final EnumerableConvention out = EnumerableConvention.INSTANCE;
+ final RelTraitSet traitSet =
+ rel.getTraitSet().replace(
+ EnumerableConvention.INSTANCE);
+ return new EnumerableMinus(rel.getCluster(), traitSet,
+ convertList(minus.getInputs(), out), false);
+ }
+}
+
+// End EnumerableMinusRule.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableOneRowRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableOneRowRule.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableOneRowRule.java
new file mode 100644
index 0000000..3602d7f
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableOneRowRule.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.plan.Convention;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.convert.ConverterRule;
+import org.apache.calcite.rel.logical.LogicalOneRow;
+import org.apache.calcite.rex.RexBuilder;
+
+import java.math.BigDecimal;
+import java.util.Collections;
+
+/** Planner rule that converts a
+ * {@link org.apache.calcite.rel.logical.LogicalOneRow} relational expression
+ * {@link org.apache.calcite.adapter.enumerable.EnumerableConvention enumerable calling convention}. */
+public class EnumerableOneRowRule extends ConverterRule {
+ EnumerableOneRowRule() {
+ super(LogicalOneRow.class, Convention.NONE, EnumerableConvention.INSTANCE,
+ "EnumerableOneRowRule");
+ }
+
+ public RelNode convert(RelNode rel) {
+ LogicalOneRow oneRow = (LogicalOneRow) rel;
+ RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
+ return new EnumerableValues(
+ oneRow.getCluster(),
+ oneRow.getRowType(),
+ Collections.singletonList(
+ Collections.singletonList(
+ rexBuilder.makeExactLiteral(BigDecimal.ZERO))),
+ oneRow.getTraitSet().replace(EnumerableConvention.INSTANCE));
+ }
+}
+
+// End EnumerableOneRowRule.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableProject.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableProject.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableProject.java
new file mode 100644
index 0000000..f145776
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableProject.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.Project;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexNode;
+
+import java.util.List;
+
+/** Implementation of {@link org.apache.calcite.rel.core.Project} in
+ * {@link org.apache.calcite.adapter.enumerable.EnumerableConvention enumerable calling convention}. */
+public class EnumerableProject extends Project implements EnumerableRel {
+ public EnumerableProject(
+ RelOptCluster cluster,
+ RelTraitSet traitSet,
+ RelNode child,
+ List<? extends RexNode> exps,
+ RelDataType rowType,
+ int flags) {
+ super(cluster, traitSet, child, exps, rowType, flags);
+ assert getConvention() instanceof EnumerableConvention;
+ }
+
+ public EnumerableProject copy(RelTraitSet traitSet, RelNode input,
+ List<RexNode> exps, RelDataType rowType) {
+ return new EnumerableProject(getCluster(), traitSet, input,
+ exps, rowType, flags);
+ }
+
+ public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
+ // EnumerableCalcRel is always better
+ throw new UnsupportedOperationException();
+ }
+}
+
+// End EnumerableProject.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableProjectRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableProjectRule.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableProjectRule.java
new file mode 100644
index 0000000..919856c
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableProjectRule.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.plan.Convention;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.convert.ConverterRule;
+import org.apache.calcite.rel.core.Project;
+import org.apache.calcite.rel.logical.LogicalProject;
+import org.apache.calcite.rex.RexMultisetUtil;
+import org.apache.calcite.rex.RexOver;
+
+/**
+ * Rule to convert a {@link org.apache.calcite.rel.logical.LogicalProject} to an
+ * {@link EnumerableProject}.
+ */
+class EnumerableProjectRule extends ConverterRule {
+ EnumerableProjectRule() {
+ super(LogicalProject.class, Convention.NONE, EnumerableConvention.INSTANCE,
+ "EnumerableProjectRule");
+ }
+
+ public RelNode convert(RelNode rel) {
+ final LogicalProject project = (LogicalProject) rel;
+
+ if (EnumUtils.B
+ && RexMultisetUtil.containsMultiset(project.getProjects(), true)
+ || RexOver.containsOver(project.getProjects(), null)) {
+ return null;
+ }
+
+ return new EnumerableProject(
+ rel.getCluster(),
+ rel.getTraitSet().replace(EnumerableConvention.INSTANCE),
+ convert(
+ project.getInput(),
+ project.getInput().getTraitSet()
+ .replace(EnumerableConvention.INSTANCE)),
+ project.getProjects(),
+ project.getRowType(),
+ Project.Flags.BOXED);
+ }
+}
+
+// End EnumerableProjectRule.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableProjectToCalcRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableProjectToCalcRule.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableProjectToCalcRule.java
new file mode 100644
index 0000000..988eb46
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableProjectToCalcRule.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptRuleCall;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexProgram;
+
+import com.google.common.collect.ImmutableList;
+
+/** Variant of {@link org.apache.calcite.rel.rules.ProjectToCalcRule} for
+ * {@link org.apache.calcite.adapter.enumerable.EnumerableConvention enumerable calling convention}. */
+public class EnumerableProjectToCalcRule extends RelOptRule {
+ EnumerableProjectToCalcRule() {
+ super(operand(EnumerableProject.class, any()));
+ }
+
+ public void onMatch(RelOptRuleCall call) {
+ final EnumerableProject project = call.rel(0);
+ final RelNode child = project.getInput();
+ final RelDataType rowType = project.getRowType();
+ final RexProgram program =
+ RexProgram.create(child.getRowType(),
+ project.getProjects(),
+ null,
+ project.getRowType(),
+ project.getCluster().getRexBuilder());
+ final EnumerableCalc calc =
+ new EnumerableCalc(
+ project.getCluster(),
+ project.getTraitSet(),
+ child,
+ rowType,
+ program,
+ ImmutableList.<RelCollation>of());
+ call.transformTo(calc);
+ }
+}
+
+// End EnumerableProjectToCalcRule.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableRel.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableRel.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableRel.java
index 5a69057..8c74f73 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableRel.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableRel.java
@@ -14,24 +14,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.hydromatic.optiq.rules.java;
-
-import net.hydromatic.linq4j.expressions.BlockStatement;
-
-import org.eigenbase.rel.ProjectRelBase;
-import org.eigenbase.rel.RelFactories;
-import org.eigenbase.rel.RelNode;
-import org.eigenbase.relopt.RelOptCluster;
-import org.eigenbase.reltype.RelDataType;
-import org.eigenbase.rex.RexNode;
-import org.eigenbase.rex.RexUtil;
-import org.eigenbase.sql.validate.SqlValidatorUtil;
+package org.apache.calcite.adapter.enumerable;
+
+import org.apache.calcite.linq4j.tree.BlockStatement;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.Project;
+import org.apache.calcite.rel.core.RelFactories;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexUtil;
+import org.apache.calcite.sql.validate.SqlValidatorUtil;
import java.util.List;
/**
* A relational expression of one of the
- * {@link net.hydromatic.optiq.rules.java.EnumerableConvention} calling
+ * {@link org.apache.calcite.adapter.enumerable.EnumerableConvention} calling
* conventions.
*/
public interface EnumerableRel
@@ -39,7 +38,7 @@ public interface EnumerableRel
RelFactories.FilterFactory FILTER_FACTORY =
new RelFactories.FilterFactory() {
public RelNode createFilter(RelNode child, RexNode condition) {
- return new JavaRules.EnumerableFilterRel(child.getCluster(),
+ return new EnumerableFilter(child.getCluster(),
child.getTraitSet(), child, condition);
}
};
@@ -54,9 +53,9 @@ public interface EnumerableRel
fieldNames == null ? null
: SqlValidatorUtil.uniquify(fieldNames,
SqlValidatorUtil.F_SUGGESTER));
- return new JavaRules.EnumerableProjectRel(cluster,
+ return new EnumerableProject(cluster,
child.getTraitSet(), child, exprs, rowType,
- ProjectRelBase.Flags.BOXED);
+ Project.Flags.BOXED);
}
};
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a0ba73cd/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableRelImplementor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableRelImplementor.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableRelImplementor.java
index 135582e..86637dc 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableRelImplementor.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableRelImplementor.java
@@ -14,19 +14,33 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.hydromatic.optiq.rules.java;
+package org.apache.calcite.adapter.enumerable;
-import net.hydromatic.linq4j.Enumerable;
-import net.hydromatic.linq4j.Queryable;
-import net.hydromatic.linq4j.expressions.*;
-
-import net.hydromatic.optiq.BuiltinMethod;
-import net.hydromatic.optiq.DataContext;
-import net.hydromatic.optiq.jdbc.JavaTypeFactoryImpl;
-import net.hydromatic.optiq.runtime.*;
-
-import org.eigenbase.rel.RelNode;
-import org.eigenbase.rex.RexBuilder;
+import org.apache.calcite.DataContext;
+import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
+import org.apache.calcite.linq4j.Enumerable;
+import org.apache.calcite.linq4j.Queryable;
+import org.apache.calcite.linq4j.tree.BlockBuilder;
+import org.apache.calcite.linq4j.tree.BlockStatement;
+import org.apache.calcite.linq4j.tree.Blocks;
+import org.apache.calcite.linq4j.tree.ClassDeclaration;
+import org.apache.calcite.linq4j.tree.ConditionalStatement;
+import org.apache.calcite.linq4j.tree.ConstantExpression;
+import org.apache.calcite.linq4j.tree.Expression;
+import org.apache.calcite.linq4j.tree.Expressions;
+import org.apache.calcite.linq4j.tree.MemberDeclaration;
+import org.apache.calcite.linq4j.tree.MethodCallExpression;
+import org.apache.calcite.linq4j.tree.NewArrayExpression;
+import org.apache.calcite.linq4j.tree.NewExpression;
+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.linq4j.tree.Visitor;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rex.RexBuilder;
+import org.apache.calcite.runtime.Bindable;
+import org.apache.calcite.runtime.Utilities;
+import org.apache.calcite.util.BuiltInMethod;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
@@ -34,10 +48,14 @@ import com.google.common.collect.Iterables;
import java.io.Serializable;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
/**
- * Subclass of {@link org.eigenbase.relopt.RelImplementor} for relational
+ * Subclass of {@link org.apache.calcite.plan.RelImplementor} for relational
* operators of {@link EnumerableConvention} calling convention.
*/
public class EnumerableRelImplementor extends JavaRelImplementor {
@@ -87,12 +105,12 @@ public class EnumerableRelImplementor extends JavaRelImplementor {
Expressions.methodDecl(
Modifier.PUBLIC,
Enumerable.class,
- BuiltinMethod.BINDABLE_BIND.method.getName(),
+ BuiltInMethod.BINDABLE_BIND.method.getName(),
Expressions.list(root0_),
block));
memberDeclarations.add(Expressions.methodDecl(Modifier.PUBLIC,
Type.class,
- BuiltinMethod.TYPED_GET_ELEMENT_TYPE.method.getName(),
+ BuiltInMethod.TYPED_GET_ELEMENT_TYPE.method.getName(),
Collections.<ParameterExpression>emptyList(),
Blocks.toFunctionBlock(Expressions.return_(null,
Expressions.constant(result.physType.getJavaRowType())))));
@@ -363,7 +381,7 @@ public class EnumerableRelImplementor extends JavaRelImplementor {
public Expression stash(RelNode child, Class clazz) {
final ParameterExpression x = register(child, clazz);
final Expression e = Expressions.call(getRootExpression(),
- BuiltinMethod.DATA_CONTEXT_GET.method, Expressions.constant(x.name));
+ BuiltInMethod.DATA_CONTEXT_GET.method, Expressions.constant(x.name));
return Expressions.convert_(e, clazz);
}
@@ -380,8 +398,7 @@ public class EnumerableRelImplementor extends JavaRelImplementor {
this.types = types;
}
- @Override
- public Expression visit(
+ @Override public Expression visit(
NewExpression newExpression,
List<Expression> arguments,
List<MemberDeclaration> memberDeclarations) {
@@ -392,8 +409,7 @@ public class EnumerableRelImplementor extends JavaRelImplementor {
memberDeclarations);
}
- @Override
- public Expression visit(NewArrayExpression newArrayExpression,
+ @Override public Expression visit(NewArrayExpression newArrayExpression,
int dimension, Expression bound, List<Expression> expressions) {
Type type = newArrayExpression.type;
for (;;) {