You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@drill.apache.org by vo...@apache.org on 2021/08/05 17:23:22 UTC

[drill] 09/13: Fix project

This is an automated email from the ASF dual-hosted git repository.

volodymyr pushed a commit to branch mongo
in repository https://gitbox.apache.org/repos/asf/drill.git

commit b79f532d6261955e7ff0c84be2ce2bf410875cec
Author: Volodymyr Vysotskyi <vv...@gmail.com>
AuthorDate: Thu Jul 29 21:06:45 2021 +0300

    Fix project
---
 .../store/mongo/plan/MongoPluginImplementor.java   | 182 +++++++++--
 .../drill/exec/store/mongo/plan/MongoRules.java    | 356 ++-------------------
 .../drill/exec/store/mongo/TestMongoQueries.java   |  14 +-
 3 files changed, 191 insertions(+), 361 deletions(-)

diff --git a/contrib/storage-mongo/src/main/java/org/apache/drill/exec/store/mongo/plan/MongoPluginImplementor.java b/contrib/storage-mongo/src/main/java/org/apache/drill/exec/store/mongo/plan/MongoPluginImplementor.java
index 0fc30b4..d51447c 100644
--- a/contrib/storage-mongo/src/main/java/org/apache/drill/exec/store/mongo/plan/MongoPluginImplementor.java
+++ b/contrib/storage-mongo/src/main/java/org/apache/drill/exec/store/mongo/plan/MongoPluginImplementor.java
@@ -7,6 +7,7 @@ import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.type.RelDataTypeField;
 import org.apache.calcite.rex.RexLiteral;
 import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.sql.SqlKind;
 import org.apache.calcite.util.Pair;
 import org.apache.calcite.util.Util;
 import org.apache.drill.common.expression.LogicalExpression;
@@ -15,13 +16,13 @@ import org.apache.drill.exec.physical.base.GroupScan;
 import org.apache.drill.exec.planner.logical.DrillOptiq;
 import org.apache.drill.exec.planner.logical.DrillParseContext;
 import org.apache.drill.exec.planner.physical.PrelUtil;
+import org.apache.drill.exec.store.mongo.MongoAggregateUtils;
 import org.apache.drill.exec.store.mongo.MongoFilterBuilder;
 import org.apache.drill.exec.store.mongo.MongoGroupScan;
-import org.apache.drill.exec.store.mongo.MongoAggregateUtils;
 import org.apache.drill.exec.store.mongo.MongoScanSpec;
+import org.apache.drill.exec.store.plan.PluginImplementor;
 import org.apache.drill.exec.store.plan.rel.PluginAggregateRel;
 import org.apache.drill.exec.store.plan.rel.PluginFilterRel;
-import org.apache.drill.exec.store.plan.PluginImplementor;
 import org.apache.drill.exec.store.plan.rel.PluginLimitRel;
 import org.apache.drill.exec.store.plan.rel.PluginProjectRel;
 import org.apache.drill.exec.store.plan.rel.PluginSortRel;
@@ -71,6 +72,11 @@ public class MongoPluginImplementor implements PluginImplementor {
         new DrillParseContext(PrelUtil.getPlannerSettings(filter.getCluster().getPlanner())), filter.getInput(), filter.getCondition());
     MongoFilterBuilder mongoFilterBuilder = new MongoFilterBuilder(groupScan, conditionExp);
     if (runAggregate) {
+//      MongoRules.RexToMongoTranslator translator =
+//          new MongoRules.RexToMongoTranslator(
+//              (JavaTypeFactory) filter.getCluster().getTypeFactory(),
+//              MongoRules.mongoFieldNames(filter.getInput().getRowType()));
+//      Bson convertedFilterExpression = Aggregates.match(filter.getCondition().accept(translator).asDocument()).toBsonDocument();
       Bson convertedFilterExpression = Aggregates.match(mongoFilterBuilder.parseTree()).toBsonDocument();
       operations.add(convertedFilterExpression);
     } else {
@@ -78,6 +84,131 @@ public class MongoPluginImplementor implements PluginImplementor {
     }
   }
 
+//  private String translateMatch(RexNode condition) {
+//    Map<String, Object> map = new HashMap<>();
+//    map.put("$match", translateOr(condition));
+//    return builder.toJsonString(map);
+//  }
+//
+//  private Object translateOr(RexNode condition) {
+//    final RexNode condition2 =
+//        RexUtil.expandSearch(rexBuilder, null, condition);
+//
+//    List<Object> list = new ArrayList<>();
+//    for (RexNode node : RelOptUtil.disjunctions(condition2)) {
+//      list.add(translateAnd(node));
+//    }
+//    switch (list.size()) {
+//      case 1:
+//        return list.get(0);
+//      default:
+//        Map<String, Object> map = builder.map();
+//        map.put("$or", list);
+//        return map;
+//    }
+//  }
+//
+//  /** Translates a condition that may be an AND of other conditions. Gathers
+//   * together conditions that apply to the same field. */
+//  private Map<String, Object> translateAnd(RexNode node0) {
+//    eqMap.clear();
+//    multimap.clear();
+//    for (RexNode node : RelOptUtil.conjunctions(node0)) {
+//      translateMatch2(node);
+//    }
+//    Map<String, Object> map = builder.map();
+//    for (Map.Entry<String, RexLiteral> entry : eqMap.entrySet()) {
+//      multimap.removeAll(entry.getKey());
+//      map.put(entry.getKey(), literalValue(entry.getValue()));
+//    }
+//    for (Map.Entry<String, Collection<Pair<String, RexLiteral>>> entry
+//        : multimap.asMap().entrySet()) {
+//      Map<String, Object> map2 = builder.map();
+//      for (Pair<String, RexLiteral> s : entry.getValue()) {
+//        addPredicate(map2, s.left, literalValue(s.right));
+//      }
+//      map.put(entry.getKey(), map2);
+//    }
+//    return map;
+//  }
+//
+//  private Void translateMatch2(RexNode node) {
+//    switch (node.getKind()) {
+//      case EQUALS:
+//        return translateBinary(null, null, (RexCall) node);
+//      case LESS_THAN:
+//        return translateBinary("$lt", "$gt", (RexCall) node);
+//      case LESS_THAN_OR_EQUAL:
+//        return translateBinary("$lte", "$gte", (RexCall) node);
+//      case NOT_EQUALS:
+//        return translateBinary("$ne", "$ne", (RexCall) node);
+//      case GREATER_THAN:
+//        return translateBinary("$gt", "$lt", (RexCall) node);
+//      case GREATER_THAN_OR_EQUAL:
+//        return translateBinary("$gte", "$lte", (RexCall) node);
+//      default:
+//        throw new AssertionError("cannot translate " + node);
+//    }
+//  }
+//
+//  /** Translates a call to a binary operator, reversing arguments if
+//   * necessary. */
+//  private Void translateBinary(String op, String rop, RexCall call) {
+//    final RexNode left = call.operands.get(0);
+//    final RexNode right = call.operands.get(1);
+//    boolean b = translateBinary2(op, left, right);
+//    if (b) {
+//      return null;
+//    }
+//    b = translateBinary2(rop, right, left);
+//    if (b) {
+//      return null;
+//    }
+//    throw new AssertionError("cannot translate op " + op + " call " + call);
+//  }
+//
+//  /** Translates a call to a binary operator. Returns whether successful. */
+//  private boolean translateBinary2(String op, RexNode left, RexNode right) {
+//    switch (right.getKind()) {
+//      case LITERAL:
+//        break;
+//      default:
+//        return false;
+//    }
+//    final RexLiteral rightLiteral = (RexLiteral) right;
+//    switch (left.getKind()) {
+//      case INPUT_REF:
+//        final RexInputRef left1 = (RexInputRef) left;
+//        String name = fieldNames.get(left1.getIndex());
+//        translateOp2(op, name, rightLiteral);
+//        return true;
+//      case CAST:
+//        return translateBinary2(op, ((RexCall) left).operands.get(0), right);
+//      case ITEM:
+//        String itemName = MongoRules.isItem((RexCall) left);
+//        if (itemName != null) {
+//          translateOp2(op, itemName, rightLiteral);
+//          return true;
+//        }
+//        // fall through
+//      default:
+//        return false;
+//    }
+//  }
+//
+//  private void translateOp2(String op, String name, RexLiteral right) {
+//    if (op == null) {
+//      // E.g.: {deptno: 100}
+//      eqMap.put(name, right);
+//    } else {
+//      // E.g. {deptno: {$lt: 100}}
+//      // which may later be combined with other conditions:
+//      // E.g. {deptno: [$lt: 100, $gt: 50]}
+//      multimap.put(name, Pair.of(op, right));
+//    }
+//  }
+
+
   @Override
   public void implement(PluginLimitRel limit) throws IOException {
     runAggregate = true;
@@ -95,23 +226,26 @@ public class MongoPluginImplementor implements PluginImplementor {
 
   @Override
   public void implement(PluginProjectRel project) throws IOException {
-    runAggregate = true;
+    runAggregate = runAggregate || project.getProjects().stream()
+        .anyMatch(expression -> !expression.isA(SqlKind.INPUT_REF));
+
     visitChild(project.getInput());
 
-    MongoRules.RexToMongoTranslator translator =
-        new MongoRules.RexToMongoTranslator(
-            (JavaTypeFactory) project.getCluster().getTypeFactory(),
-            MongoRules.mongoFieldNames(project.getInput().getRowType()));
-    List<BsonElement> items = new ArrayList<>();
-    for (Pair<RexNode, String> pair : project.getNamedProjects()) {
-      String name = pair.right;
-      BsonValue expr = pair.left.accept(translator);
-      items.add(expr.equals(new BsonString("$" + name))
-          ? new BsonElement(MongoRules.maybeQuote(name), new BsonInt32(1))
-          : new BsonElement(MongoRules.maybeQuote(name), expr));
-    }
-    BsonDocument projection = Aggregates.project(new BsonDocument(items)).toBsonDocument();
     if (runAggregate) {
+      MongoRules.RexToMongoTranslator translator =
+          new MongoRules.RexToMongoTranslator(
+              (JavaTypeFactory) project.getCluster().getTypeFactory(),
+              MongoRules.mongoFieldNames(project.getInput().getRowType()));
+      List<BsonElement> items = new ArrayList<>();
+      for (Pair<RexNode, String> pair : project.getNamedProjects()) {
+        String name = pair.right;
+        BsonValue expr = pair.left.accept(translator);
+        items.add(expr.equals(new BsonString("$" + name))
+            ? new BsonElement(MongoRules.maybeQuote(name), new BsonInt32(1))
+            : new BsonElement(MongoRules.maybeQuote(name), expr));
+      }
+      BsonDocument projection = Aggregates.project(new BsonDocument(items)).toBsonDocument();
+
       operations.add(projection);
       List<String> outNames = MongoAggregateUtils.mongoFieldNames(project.getRowType());
       this.columns = outNames.stream()
@@ -123,22 +257,6 @@ public class MongoPluginImplementor implements PluginImplementor {
         .map(SchemaPath::getSimplePath)
         .collect(Collectors.toList());
     }
-//    implementor.add(op.left, op.right);
-
-//    List<String> outNames = MongoAggregateUtils.mongoFieldNames(project.getRowType());
-//    Document fields = new Document();
-//    fields.put(DrillMongoConstants.ID, 0);
-//    List<String> inNames = MongoAggregateUtils.mongoFieldNames(project.getInput().getRowType());
-//    for (int i = 0; i < outNames.size(); i++) {
-//      String fieldName = outNames.get(i);
-//      fields.put(fieldName, inNames.get(((RexInputRef) project.getChildExps().get(i)).getIndex()));
-//    }
-//
-//    operations.add(Aggregates.project(fields).toBsonDocument());
-
-//    this.columns = outNames.stream()
-//        .map(SchemaPath::getSimplePath)
-//        .collect(Collectors.toList());
   }
 
   @Override
diff --git a/contrib/storage-mongo/src/main/java/org/apache/drill/exec/store/mongo/plan/MongoRules.java b/contrib/storage-mongo/src/main/java/org/apache/drill/exec/store/mongo/plan/MongoRules.java
index 7f0daf3..953983b 100644
--- a/contrib/storage-mongo/src/main/java/org/apache/drill/exec/store/mongo/plan/MongoRules.java
+++ b/contrib/storage-mongo/src/main/java/org/apache/drill/exec/store/mongo/plan/MongoRules.java
@@ -110,12 +110,45 @@ public class MongoRules {
         new HashMap<>();
 
     static {
-      // Arithmetic
       MONGO_OPERATORS.put(SqlStdOperatorTable.DIVIDE, "$divide");
       MONGO_OPERATORS.put(SqlStdOperatorTable.MULTIPLY, "$multiply");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.ABS, "$abs");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.ACOS, "$acos");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.ASIN, "$asin");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.ATAN, "$atan");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.ATAN2, "$atan2");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.CEIL, "$ceil");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.CONCAT, "$concat");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.COS, "$cos");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.DAYOFMONTH, "$dayOfMonth");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.WEEK, "$isoWeek");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.YEAR, "$isoWeekYear");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.DAYOFWEEK, "$isoDayOfWeek");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.DAYOFYEAR, "$dayOfYear");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.RADIANS, "$degreesToRadians");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.DENSE_RANK, "$denseRank");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.EXP, "$exp");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.FLOOR, "$floor");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.HOUR, "$hour");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.LN, "$ln");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.LOG10, "$log10");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.MINUTE, "$minute");
       MONGO_OPERATORS.put(SqlStdOperatorTable.MOD, "$mod");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.MONTH, "$month");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.POWER, "$pow");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.DEGREES, "$radiansToDegrees");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.RAND, "$rand");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.REPLACE, "$replaceAll");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.ROUND, "$round");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.SECOND, "$second");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.SIN, "$sin");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.SQRT, "$sqrt");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.SUBSTRING, "$substr");
       MONGO_OPERATORS.put(SqlStdOperatorTable.PLUS, "$add");
       MONGO_OPERATORS.put(SqlStdOperatorTable.MINUS, "$subtract");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.TAN, "$tan");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.TRIM, "trim");
+      MONGO_OPERATORS.put(SqlStdOperatorTable.TRUNCATE, "$trunc");
       // Boolean
       MONGO_OPERATORS.put(SqlStdOperatorTable.AND, MongoOp.AND.getCompareOp());
       MONGO_OPERATORS.put(SqlStdOperatorTable.OR, MongoOp.OR.getCompareOp());
@@ -206,326 +239,5 @@ public class MongoRules {
       throw new IllegalArgumentException("Translation of " + call
           + " is not supported by MongoProject");
     }
-
-    private static String stripQuotes(String s) {
-      return s.startsWith("'") && s.endsWith("'")
-          ? s.substring(1, s.length() - 1)
-          : s;
-    }
-  }
-
-  /*
-
-  /**
-   * Rule to convert a {@link LogicalCalc} to an
-   * {@link MongoCalcRel}.
-   o/
-  public static class MongoCalcRule
-      extends MongoConverterRule {
-    private MongoCalcRule(MongoConvention out) {
-      super(
-          LogicalCalc.class,
-          Convention.NONE,
-          out,
-          "MongoCalcRule");
-    }
-
-    public RelNode convert(RelNode rel) {
-      final LogicalCalc calc = (LogicalCalc) rel;
-
-      // If there's a multiset, let FarragoMultisetSplitter work on it
-      // first.
-      if (RexMultisetUtil.containsMultiset(calc.getProgram())) {
-        return null;
-      }
-
-      return new MongoCalcRel(
-          rel.getCluster(),
-          rel.getTraitSet().replace(out),
-          convert(
-              calc.getChild(),
-              calc.getTraitSet().replace(out)),
-          calc.getProgram(),
-          Project.Flags.Boxed);
-    }
-  }
-
-  public static class MongoCalcRel extends SingleRel implements MongoRel {
-    private final RexProgram program;
-
-    /**
-     * Values defined in {@link org.apache.calcite.rel.core.Project.Flags}.
-     o/
-    protected int flags;
-
-    public MongoCalcRel(
-        RelOptCluster cluster,
-        RelTraitSet traitSet,
-        RelNode child,
-        RexProgram program,
-        int flags) {
-      super(cluster, traitSet, child);
-      assert getConvention() instanceof MongoConvention;
-      this.flags = flags;
-      this.program = program;
-      this.rowType = program.getOutputRowType();
-    }
-
-    public RelOptPlanWriter explainTerms(RelOptPlanWriter pw) {
-      return program.explainCalc(super.explainTerms(pw));
-    }
-
-    public double getRows() {
-      return LogicalFilter.estimateFilteredRows(
-          getChild(), program);
-    }
-
-    public RelOptCost computeSelfCost(RelOptPlanner planner) {
-      double dRows = RelMetadataQuery.getRowCount(this);
-      double dCpu =
-          RelMetadataQuery.getRowCount(getChild())
-              * program.getExprCount();
-      double dIo = 0;
-      return planner.makeCost(dRows, dCpu, dIo);
-    }
-
-    public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
-      return new MongoCalcRel(
-          getCluster(),
-          traitSet,
-          sole(inputs),
-          program.copy(),
-          getFlags());
-    }
-
-    public int getFlags() {
-      return flags;
-    }
-
-    public RexProgram getProgram() {
-      return program;
-    }
-
-    public SqlString implement(MongoImplementor implementor) {
-      final SqlBuilder buf = new SqlBuilder(implementor.dialect);
-      buf.append("SELECT ");
-      if (isStar(program)) {
-        buf.append("*");
-      } else {
-        for (Ord<RexLocalRef> ref : Ord.zip(program.getProjectList())) {
-          buf.append(ref.i == 0 ? "" : ", ");
-          expr(buf, program, ref.e);
-          alias(buf, null, getRowType().getFieldNames().get(ref.i));
-        }
-      }
-      implementor.newline(buf)
-          .append("FROM ");
-      implementor.subQuery(buf, 0, getChild(), "t");
-      if (program.getCondition() != null) {
-        implementor.newline(buf);
-        buf.append("WHERE ");
-        expr(buf, program, program.getCondition());
-      }
-      return buf.toSqlString();
-    }
-
-    private static boolean isStar(RexProgram program) {
-      int i = 0;
-      for (RexLocalRef ref : program.getProjectList()) {
-        if (ref.getIndex() != i++) {
-          return false;
-        }
-      }
-      return i == program.getInputRowType().getFieldCount();
-    }
-
-    private static void expr(
-        SqlBuilder buf, RexProgram program, RexNode rex) {
-      if (rex instanceof RexLocalRef) {
-        final int index = ((RexLocalRef) rex).getIndex();
-        expr(buf, program, program.getExprList().get(index));
-      } else if (rex instanceof RexInputRef) {
-        buf.identifier(
-            program.getInputRowType().getFieldNames().get(
-                ((RexInputRef) rex).getIndex()));
-      } else if (rex instanceof RexLiteral) {
-        toSql(buf, (RexLiteral) rex);
-      } else if (rex instanceof RexCall) {
-        final RexCall call = (RexCall) rex;
-        switch (call.getOperator().getSyntax()) {
-        case Binary:
-          expr(buf, program, call.getOperands().get(0));
-          buf.append(' ')
-              .append(call.getOperator().toString())
-              .append(' ');
-          expr(buf, program, call.getOperands().get(1));
-          break;
-        default:
-          throw new AssertionError(call.getOperator());
-        }
-      } else {
-        throw new AssertionError(rex);
-      }
-    }
-  }
-
-  private static SqlBuilder toSql(SqlBuilder buf, RexLiteral rex) {
-    switch (rex.getTypeName()) {
-    case CHAR:
-    case VARCHAR:
-      return buf.append(
-          new NlsString(rex.getValue2().toString(), null, null)
-              .asSql(false, false));
-    default:
-      return buf.append(rex.getValue2().toString());
-    }
-  }
-
-*/
-
-  /*
-  /**
-   * Rule to convert an {@link org.apache.calcite.rel.logical.LogicalIntersect}
-   * to an {@link MongoIntersectRel}.
-   o/
-  public static class MongoIntersectRule
-      extends MongoConverterRule {
-    private MongoIntersectRule(MongoConvention out) {
-      super(
-          LogicalIntersect.class,
-          Convention.NONE,
-          out,
-          "MongoIntersectRule");
-    }
-
-    public RelNode convert(RelNode rel) {
-      final LogicalIntersect intersect = (LogicalIntersect) rel;
-      if (intersect.all) {
-        return null; // INTERSECT ALL not implemented
-      }
-      final RelTraitSet traitSet =
-          intersect.getTraitSet().replace(out);
-      return new MongoIntersectRel(
-          rel.getCluster(),
-          traitSet,
-          convertList(intersect.getInputs(), traitSet),
-          intersect.all);
-    }
-  }
-
-  public static class MongoIntersectRel
-      extends Intersect
-      implements MongoRel {
-    public MongoIntersectRel(
-        RelOptCluster cluster,
-        RelTraitSet traitSet,
-        List<RelNode> inputs,
-        boolean all) {
-      super(cluster, traitSet, inputs, all);
-      assert !all;
-    }
-
-    public MongoIntersectRel copy(
-        RelTraitSet traitSet, List<RelNode> inputs, boolean all) {
-      return new MongoIntersectRel(getCluster(), traitSet, inputs, all);
-    }
-
-    public SqlString implement(MongoImplementor implementor) {
-      return setOpSql(this, implementor, " intersect ");
-    }
-  }
-
-  /**
-   * Rule to convert an {@link org.apache.calcite.rel.logical.LogicalMinus}
-   * to an {@link MongoMinusRel}.
-   o/
-  public static class MongoMinusRule
-      extends MongoConverterRule {
-    private MongoMinusRule(MongoConvention out) {
-      super(
-          LogicalMinus.class,
-          Convention.NONE,
-          out,
-          "MongoMinusRule");
-    }
-
-    public RelNode convert(RelNode rel) {
-      final LogicalMinus minus = (LogicalMinus) rel;
-      if (minus.all) {
-        return null; // EXCEPT ALL not implemented
-      }
-      final RelTraitSet traitSet =
-          rel.getTraitSet().replace(out);
-      return new MongoMinusRel(
-          rel.getCluster(),
-          traitSet,
-          convertList(minus.getInputs(), traitSet),
-          minus.all);
-    }
-  }
-
-  public static class MongoMinusRel
-      extends Minus
-      implements MongoRel {
-    public MongoMinusRel(
-        RelOptCluster cluster,
-        RelTraitSet traitSet,
-        List<RelNode> inputs,
-        boolean all) {
-      super(cluster, traitSet, inputs, all);
-      assert !all;
-    }
-
-    public MongoMinusRel copy(
-        RelTraitSet traitSet, List<RelNode> inputs, boolean all) {
-      return new MongoMinusRel(getCluster(), traitSet, inputs, all);
-    }
-
-    public SqlString implement(MongoImplementor implementor) {
-      return setOpSql(this, implementor, " minus ");
-    }
-  }
-
-  public static class MongoValuesRule extends MongoConverterRule {
-    private MongoValuesRule(MongoConvention out) {
-      super(
-          LogicalValues.class,
-          Convention.NONE,
-          out,
-          "MongoValuesRule");
-    }
-
-    @Override public RelNode convert(RelNode rel) {
-      LogicalValues valuesRel = (LogicalValues) rel;
-      return new MongoValuesRel(
-          valuesRel.getCluster(),
-          valuesRel.getRowType(),
-          valuesRel.getTuples(),
-          valuesRel.getTraitSet().plus(out));
-    }
-  }
-
-  public static class MongoValuesRel
-      extends Values
-      implements MongoRel {
-    MongoValuesRel(
-        RelOptCluster cluster,
-        RelDataType rowType,
-        List<List<RexLiteral>> tuples,
-        RelTraitSet traitSet) {
-      super(cluster, rowType, tuples, traitSet);
-    }
-
-    @Override public RelNode copy(
-        RelTraitSet traitSet, List<RelNode> inputs) {
-      assert inputs.isEmpty();
-      return new MongoValuesRel(
-          getCluster(), rowType, tuples, traitSet);
-    }
-
-    public SqlString implement(MongoImplementor implementor) {
-      throw new AssertionError(); // TODO:
-    }
   }
-*/
 }
diff --git a/contrib/storage-mongo/src/test/java/org/apache/drill/exec/store/mongo/TestMongoQueries.java b/contrib/storage-mongo/src/test/java/org/apache/drill/exec/store/mongo/TestMongoQueries.java
index e8f698b..08b34b9 100644
--- a/contrib/storage-mongo/src/test/java/org/apache/drill/exec/store/mongo/TestMongoQueries.java
+++ b/contrib/storage-mongo/src/test/java/org/apache/drill/exec/store/mongo/TestMongoQueries.java
@@ -252,7 +252,7 @@ public class TestMongoQueries extends MongoTestBase {
 
   @Test
   public void testProjectPushDown() throws Exception {
-    String query = "select t.id * t.id as c from mongo.%s.`%s` t";
+    String query = "select t.sales * t.sales as c, t.name from mongo.%s.`%s` t";
 
     queryBuilder()
         .sql(query, DONUTS_DB, DONUTS_COLLECTION)
@@ -263,12 +263,12 @@ public class TestMongoQueries extends MongoTestBase {
     testBuilder()
         .sqlQuery(query, DONUTS_DB, DONUTS_COLLECTION)
         .unOrdered()
-        .baselineColumns("c")
-        .baselineValues(1)
-        .baselineValues(4)
-        .baselineValues(9)
-        .baselineValues(16)
-        .baselineValues(25)
+        .baselineColumns("c", "name")
+        .baselineValues(196, "Filled")
+        .baselineValues(1225, "Cake")
+        .baselineValues(21025, "Raised")
+        .baselineValues(90000, "Old Fashioned")
+        .baselineValues(490000, "Apple Fritter")
         .go();
   }
 }