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 (;;) {