DRILL-5130: Implement DrillValuesRel and ValuesPrel as Calcite Values sub-classes
Project: http://git-wip-us.apache.org/repos/asf/drill/repo Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/33682be9 Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/33682be9 Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/33682be9 Branch: refs/heads/master Commit: 33682be99e719dce9cb326e2835ebc4ae434104a Parents: 886ccdc Author: Arina Ielchiieva <arina.yelchiy...@gmail.com> Authored: Thu Jun 15 18:03:34 2017 +0300 Committer: Aman Sinha <asi...@maprtech.com> Committed: Sat Jun 24 09:17:29 2017 -0700 ---------------------------------------------------------------------- .../exec/planner/common/DrillValuesRelBase.java | 251 ++++++++++++++++++ .../exec/planner/logical/DrillValuesRel.java | 255 +------------------ .../drill/exec/planner/physical/ValuesPrel.java | 32 +-- .../exec/planner/physical/ValuesPrule.java | 14 +- .../java/org/apache/drill/TestUnionAll.java | 11 + .../physical/impl/filter/TestLargeInClause.java | 2 +- 6 files changed, 290 insertions(+), 275 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/drill/blob/33682be9/exec/java-exec/src/main/java/org/apache/drill/exec/planner/common/DrillValuesRelBase.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/common/DrillValuesRelBase.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/common/DrillValuesRelBase.java new file mode 100644 index 0000000..4d54fce --- /dev/null +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/common/DrillValuesRelBase.java @@ -0,0 +1,251 @@ +/* + * 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.drill.exec.planner.common; + +import com.fasterxml.jackson.core.JsonLocation; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.util.TokenBuffer; +import com.google.common.collect.ImmutableList; +import org.apache.calcite.plan.RelOptCluster; +import org.apache.calcite.plan.RelTraitSet; +import org.apache.calcite.rel.core.Values; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rex.RexLiteral; +import org.apache.calcite.util.NlsString; +import org.apache.drill.common.JSONOptions; +import org.apache.drill.common.exceptions.DrillRuntimeException; +import org.apache.drill.exec.vector.complex.fn.ExtendedJsonOutput; +import org.apache.drill.exec.vector.complex.fn.JsonOutput; +import org.joda.time.DateTime; +import org.joda.time.DateTimeConstants; +import org.joda.time.Period; + +import java.io.IOException; +import java.math.BigDecimal; +import java.util.List; + +import static org.apache.drill.exec.planner.logical.DrillOptiq.isLiteralNull; + +/** + * Base class for logical and physical Values implemented in Drill. + */ +public abstract class DrillValuesRelBase extends Values implements DrillRelNode { + + private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DrillValuesRelBase.class); + private static final ObjectMapper MAPPER = new ObjectMapper(); + + protected final JSONOptions content; + + public DrillValuesRelBase(RelOptCluster cluster, RelDataType rowType, ImmutableList<ImmutableList<RexLiteral>> tuples, RelTraitSet traits) { + this(cluster, rowType, tuples, traits, convertToJsonOptions(rowType, tuples)); + } + + /** + * This constructor helps to avoid unnecessary tuples parsing into json options + * during copying or logical to physical values conversion. + */ + public DrillValuesRelBase(RelOptCluster cluster, + RelDataType rowType, + ImmutableList<ImmutableList<RexLiteral>> tuples, + RelTraitSet traits, + JSONOptions content) { + super(cluster, rowType, tuples, traits); + this.content = content; + } + + /** + * @return values content represented as json + */ + public JSONOptions getContent() { + return content; + } + + /** + * Converts tuples into json representation taking into account row type. + * Example: [['A']] -> [{"EXPR$0":"A"}], [[1]] -> [{"EXPR$0":{"$numberLong":1}}] + * + * @param rowType row type + * @param tuples list of constant values in a row-expression + * @return json representation of tuples + */ + private static JSONOptions convertToJsonOptions(RelDataType rowType, ImmutableList<ImmutableList<RexLiteral>> tuples) { + try { + return new JSONOptions(convertToJsonNode(rowType, tuples), JsonLocation.NA); + } catch (IOException e) { + throw new DrillRuntimeException("Failure while attempting to encode Values in JSON.", e); + } + } + + private static JsonNode convertToJsonNode(RelDataType rowType, ImmutableList<ImmutableList<RexLiteral>> tuples) throws IOException { + TokenBuffer out = new TokenBuffer(MAPPER.getFactory().getCodec(), false); + JsonOutput json = new ExtendedJsonOutput(out); + json.writeStartArray(); + String[] fields = rowType.getFieldNames().toArray(new String[rowType.getFieldCount()]); + + for (List<RexLiteral> row : tuples) { + json.writeStartObject(); + int i = 0; + for (RexLiteral field : row) { + json.writeFieldName(fields[i]); + writeLiteral(field, json); + i++; + } + json.writeEndObject(); + } + json.writeEndArray(); + json.flush(); + return out.asParser().readValueAsTree(); + } + + private static void writeLiteral(RexLiteral literal, JsonOutput out) throws IOException { + switch (literal.getType().getSqlTypeName()) { + case BIGINT: + if (isLiteralNull(literal)) { + out.writeBigIntNull(); + } else { + out.writeBigInt((((BigDecimal) literal.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)).longValue()); + } + return; + + case BOOLEAN: + if (isLiteralNull(literal)) { + out.writeBooleanNull(); + } else { + out.writeBoolean((Boolean) literal.getValue()); + } + return; + + case CHAR: + if (isLiteralNull(literal)) { + out.writeVarcharNull(); + } else { + // Since Calcite treats string literals as fixed char and adds trailing spaces to the strings to make them the + // same length, here we do an rtrim() to get the string without the trailing spaces. If we don't rtrim, the comparison + // with Drill's varchar column values would not return a match. + // TODO: However, note that if the user had explicitly added spaces in the string literals then even those would get + // trimmed, so this exposes another issue that needs to be resolved. + out.writeVarChar(((NlsString) literal.getValue()).rtrim().getValue()); + } + return; + + case DOUBLE: + if (isLiteralNull(literal)) { + out.writeDoubleNull(); + } else { + out.writeDouble(((BigDecimal) literal.getValue()).doubleValue()); + } + return; + + case FLOAT: + if (isLiteralNull(literal)) { + out.writeFloatNull(); + } else { + out.writeFloat(((BigDecimal) literal.getValue()).floatValue()); + } + return; + + case INTEGER: + if (isLiteralNull(literal)) { + out.writeIntNull(); + } else { + out.writeInt((((BigDecimal) literal.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)).intValue()); + } + return; + + case DECIMAL: + if (isLiteralNull(literal)) { + out.writeDoubleNull(); + } else { + out.writeDouble(((BigDecimal) literal.getValue()).doubleValue()); + } + logger.warn("Converting exact decimal into approximate decimal. Should be fixed once full decimal support is implemented."); + return; + + case VARCHAR: + if (isLiteralNull(literal)) { + out.writeVarcharNull(); + } else { + out.writeVarChar(((NlsString) literal.getValue()).getValue()); + } + return; + + case SYMBOL: + if (isLiteralNull(literal)) { + out.writeVarcharNull(); + } else { + out.writeVarChar(literal.getValue().toString()); + } + return; + + case DATE: + if (isLiteralNull(literal)) { + out.writeDateNull(); + } else { + out.writeDate(new DateTime(literal.getValue())); + } + return; + + case TIME: + if (isLiteralNull(literal)) { + out.writeTimeNull(); + } else { + out.writeTime(new DateTime(literal.getValue())); + } + return; + + case TIMESTAMP: + if (isLiteralNull(literal)) { + out.writeTimestampNull(); + } else { + out.writeTimestamp(new DateTime(literal.getValue())); + } + return; + + case INTERVAL_YEAR_MONTH: + if (isLiteralNull(literal)) { + out.writeIntervalNull(); + } else { + int months = ((BigDecimal) (literal.getValue())).intValue(); + out.writeInterval(new Period().plusMonths(months)); + } + return; + + case INTERVAL_DAY_TIME: + if (isLiteralNull(literal)) { + out.writeIntervalNull(); + } else { + long millis = ((BigDecimal) (literal.getValue())).longValue(); + int days = (int) (millis / DateTimeConstants.MILLIS_PER_DAY); + millis = millis - (days * DateTimeConstants.MILLIS_PER_DAY); + out.writeInterval(new Period().plusDays(days).plusMillis((int) millis)); + } + return; + + case NULL: + out.writeUntypedNull(); + return; + + case ANY: + default: + throw new UnsupportedOperationException( + String.format("Unable to convert the value of %s and type %s to a Drill constant expression.", + literal, literal.getType().getSqlTypeName())); + } + } + +} http://git-wip-us.apache.org/repos/asf/drill/blob/33682be9/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillValuesRel.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillValuesRel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillValuesRel.java index 816506a..fb66acd 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillValuesRel.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillValuesRel.java @@ -17,282 +17,45 @@ */ package org.apache.drill.exec.planner.logical; -import static org.apache.drill.exec.planner.logical.DrillOptiq.isLiteralNull; - -import java.io.IOException; -import java.math.BigDecimal; -import java.util.GregorianCalendar; import java.util.List; import com.google.common.collect.ImmutableList; -import org.apache.calcite.rel.AbstractRelNode; -import org.apache.calcite.rel.RelWriter; -import org.apache.calcite.rel.metadata.RelMetadataQuery; -import org.apache.calcite.rel.type.RelDataTypeField; -import org.apache.calcite.sql.SqlExplainLevel; -import org.apache.calcite.sql.type.SqlTypeUtil; -import org.apache.calcite.util.NlsString; -import org.apache.calcite.util.Pair; import org.apache.drill.common.JSONOptions; -import org.apache.drill.common.exceptions.DrillRuntimeException; import org.apache.drill.common.logical.data.LogicalOperator; import org.apache.calcite.rel.RelNode; 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.type.RelDataType; import org.apache.calcite.rex.RexLiteral; -import com.fasterxml.jackson.core.JsonLocation; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.util.TokenBuffer; import org.apache.drill.common.logical.data.Values; -import org.apache.drill.exec.vector.complex.fn.ExtendedJsonOutput; -import org.apache.drill.exec.vector.complex.fn.JsonOutput; -import org.joda.time.DateTime; -import org.joda.time.Period; +import org.apache.drill.exec.planner.common.DrillValuesRelBase; /** - * Values implemented in Drill. + * Logical Values implementation in Drill. */ -public class DrillValuesRel extends AbstractRelNode implements DrillRel { - private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DrillValuesRel.class); - private static final ObjectMapper MAPPER = new ObjectMapper(); - - private static final long MILLIS_IN_DAY = 1000*60*60*24; - - private final JSONOptions options; - private final double rowCount; - - protected DrillValuesRel(RelOptCluster cluster, RelDataType rowType, ImmutableList<ImmutableList<RexLiteral>> tuples, RelTraitSet traits) { - super(cluster, traits); - assert getConvention() == DRILL_LOGICAL; - verifyRowType(tuples, rowType); - - this.rowType = rowType; - this.rowCount = tuples.size(); - - try{ - this.options = new JSONOptions(convertToJsonNode(rowType, tuples), JsonLocation.NA); - }catch(IOException e){ - throw new DrillRuntimeException("Failure while attempting to encode ValuesRel in JSON.", e); - } - - } - - private DrillValuesRel(RelOptCluster cluster, RelDataType rowType, RelTraitSet traits, JSONOptions options, double rowCount){ - super(cluster, traits); - this.options = options; - this.rowCount = rowCount; - this.rowType = rowType; - } - - private static void verifyRowType(final ImmutableList<ImmutableList<RexLiteral>> tuples, RelDataType rowType){ - for (List<RexLiteral> tuple : tuples) { - assert (tuple.size() == rowType.getFieldCount()); - - for (Pair<RexLiteral, RelDataTypeField> pair : Pair.zip(tuple, rowType.getFieldList())) { - RexLiteral literal = pair.left; - RelDataType fieldType = pair.right.getType(); - - if ((!(RexLiteral.isNullLiteral(literal))) - && (!(SqlTypeUtil.canAssignFrom(fieldType, literal.getType())))) { - throw new AssertionError("to " + fieldType + " from " + literal); - } - } - } +public class DrillValuesRel extends DrillValuesRelBase implements DrillRel { + public DrillValuesRel(RelOptCluster cluster, RelDataType rowType, ImmutableList<ImmutableList<RexLiteral>> tuples, RelTraitSet traits) { + super(cluster, rowType, tuples, traits); } - public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { - return planner.getCostFactory().makeCost(this.rowCount, 1.0d, 0.0d); + public DrillValuesRel(RelOptCluster cluster, RelDataType rowType, ImmutableList<ImmutableList<RexLiteral>> tuples, RelTraitSet traits, JSONOptions content) { + super(cluster, rowType, tuples, traits, content); } @Override public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) { assert inputs.isEmpty(); - return new DrillValuesRel(getCluster(), rowType, traitSet, options, rowCount); + return new DrillValuesRel(getCluster(), rowType, tuples, traitSet, content); } @Override public LogicalOperator implement(DrillImplementor implementor) { return Values.builder() - .content(options.asNode()) + .content(content.asNode()) .build(); } - public JSONOptions getTuplesAsJsonOptions() throws IOException { - return options; - } - - public double estimateRowCount(RelMetadataQuery mq) { - return rowCount; - } - - public RelWriter explainTerms(RelWriter pw) { - return super.explainTerms(pw) - .itemIf("type", this.rowType, pw.getDetailLevel() == SqlExplainLevel.DIGEST_ATTRIBUTES) - .itemIf("type", this.rowType.getFieldList(), pw.nest()) - .itemIf("tuplesCount", rowCount, pw.getDetailLevel() != SqlExplainLevel.ALL_ATTRIBUTES) - .itemIf("tuples", options.asNode(), pw.getDetailLevel() == SqlExplainLevel.ALL_ATTRIBUTES); - } - private static JsonNode convertToJsonNode(RelDataType rowType, ImmutableList<ImmutableList<RexLiteral>> tuples) throws IOException{ - TokenBuffer out = new TokenBuffer(MAPPER.getFactory().getCodec(), false); - JsonOutput json = new ExtendedJsonOutput(out); - json.writeStartArray(); - String[] fields = rowType.getFieldNames().toArray(new String[rowType.getFieldCount()]); - - for(List<RexLiteral> row : tuples){ - json.writeStartObject(); - int i =0; - for(RexLiteral field : row){ - json.writeFieldName(fields[i]); - writeLiteral(field, json); - i++; - } - json.writeEndObject(); - } - json.writeEndArray(); - json.flush(); - return out.asParser().readValueAsTree(); - } - - - private static void writeLiteral(RexLiteral literal, JsonOutput out) throws IOException{ - - switch(literal.getType().getSqlTypeName()){ - case BIGINT: - if (isLiteralNull(literal)) { - out.writeBigIntNull(); - }else{ - out.writeBigInt((((BigDecimal) literal.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)).longValue()); - } - return; - - case BOOLEAN: - if (isLiteralNull(literal)) { - out.writeBooleanNull(); - }else{ - out.writeBoolean((Boolean) literal.getValue()); - } - return; - - case CHAR: - if (isLiteralNull(literal)) { - out.writeVarcharNull(); - }else{ - // Since Calcite treats string literals as fixed char and adds trailing spaces to the strings to make them the - // same length, here we do an rtrim() to get the string without the trailing spaces. If we don't rtrim, the comparison - // with Drill's varchar column values would not return a match. - // TODO: However, note that if the user had explicitly added spaces in the string literals then even those would get - // trimmed, so this exposes another issue that needs to be resolved. - out.writeVarChar(((NlsString)literal.getValue()).rtrim().getValue()); - } - return ; - - case DOUBLE: - if (isLiteralNull(literal)){ - out.writeDoubleNull(); - }else{ - out.writeDouble(((BigDecimal) literal.getValue()).doubleValue()); - } - return; - - case FLOAT: - if (isLiteralNull(literal)) { - out.writeFloatNull(); - }else{ - out.writeFloat(((BigDecimal) literal.getValue()).floatValue()); - } - return; - - case INTEGER: - if (isLiteralNull(literal)) { - out.writeIntNull(); - }else{ - out.writeInt((((BigDecimal) literal.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)).intValue()); - } - return; - - case DECIMAL: - if (isLiteralNull(literal)) { - out.writeDoubleNull(); - }else{ - out.writeDouble(((BigDecimal) literal.getValue()).doubleValue()); - } - logger.warn("Converting exact decimal into approximate decimal. Should be fixed once decimal is implemented."); - return; - - case VARCHAR: - if (isLiteralNull(literal)) { - out.writeVarcharNull(); - }else{ - out.writeVarChar( ((NlsString)literal.getValue()).getValue()); - } - return; - - case SYMBOL: - if (isLiteralNull(literal)) { - out.writeVarcharNull(); - }else{ - out.writeVarChar(literal.getValue().toString()); - } - return; - - case DATE: - if (isLiteralNull(literal)) { - out.writeDateNull(); - }else{ - out.writeDate(new DateTime((GregorianCalendar)literal.getValue())); - } - return; - - case TIME: - if (isLiteralNull(literal)) { - out.writeTimeNull(); - }else{ - out.writeTime(new DateTime((GregorianCalendar)literal.getValue())); - } - return; - - case TIMESTAMP: - if (isLiteralNull(literal)) { - out.writeTimestampNull(); - }else{ - out.writeTimestamp(new DateTime((GregorianCalendar)literal.getValue())); - } - return; - - case INTERVAL_YEAR_MONTH: - if (isLiteralNull(literal)) { - out.writeIntervalNull(); - }else{ - int months = ((BigDecimal) (literal.getValue())).intValue(); - out.writeInterval(new Period().plusMonths(months)); - } - return; - - case INTERVAL_DAY_TIME: - if (isLiteralNull(literal)) { - out.writeIntervalNull(); - }else{ - long millis = ((BigDecimal) (literal.getValue())).longValue(); - int days = (int) (millis/MILLIS_IN_DAY); - millis = millis - (days * MILLIS_IN_DAY); - out.writeInterval(new Period().plusDays(days).plusMillis( (int) millis)); - } - return; - - case NULL: - out.writeUntypedNull(); - return; - - case ANY: - default: - throw new UnsupportedOperationException(String.format("Unable to convert the value of %s and type %s to a Drill constant expression.", literal, literal.getType().getSqlTypeName())); - } - } } http://git-wip-us.apache.org/repos/asf/drill/blob/33682be9/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/ValuesPrel.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/ValuesPrel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/ValuesPrel.java index cdb4787..095519f 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/ValuesPrel.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/ValuesPrel.java @@ -1,4 +1,4 @@ -/** +/* * 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 @@ -18,38 +18,39 @@ package org.apache.drill.exec.planner.physical; import java.io.IOException; +import java.util.Collections; import java.util.Iterator; import java.util.List; +import com.google.common.collect.ImmutableList; import org.apache.calcite.plan.RelOptCluster; import org.apache.calcite.plan.RelTraitSet; -import org.apache.calcite.rel.AbstractRelNode; import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rex.RexLiteral; import org.apache.drill.common.JSONOptions; import org.apache.drill.exec.physical.base.PhysicalOperator; import org.apache.drill.exec.physical.config.Values; +import org.apache.drill.exec.planner.common.DrillValuesRelBase; import org.apache.drill.exec.planner.physical.visitor.PrelVisitor; import org.apache.drill.exec.record.BatchSchema.SelectionVectorMode; -import com.google.common.collect.Iterators; - -public class ValuesPrel extends AbstractRelNode implements Prel { - - @SuppressWarnings("unused") - private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(ValuesPrel.class); +/** + * Physical Values implementation in Drill. + */ +public class ValuesPrel extends DrillValuesRelBase implements Prel { - private JSONOptions content; + public ValuesPrel(RelOptCluster cluster, RelDataType rowType, ImmutableList<ImmutableList<RexLiteral>> tuples, RelTraitSet traits) { + super(cluster, rowType, tuples, traits); + } - public ValuesPrel(RelOptCluster cluster, RelTraitSet traitSet, RelDataType rowType, JSONOptions content) { - super(cluster, traitSet); - this.rowType = rowType; - this.content = content; + public ValuesPrel(RelOptCluster cluster, RelDataType rowType, ImmutableList<ImmutableList<RexLiteral>> tuples, RelTraitSet traits, JSONOptions content) { + super(cluster, rowType, tuples, traits, content); } @Override public Iterator<Prel> iterator() { - return Iterators.emptyIterator(); + return Collections.emptyIterator(); } @Override @@ -59,7 +60,7 @@ public class ValuesPrel extends AbstractRelNode implements Prel { @Override public Prel copy(RelTraitSet traitSet, List<RelNode> inputs) { - return new ValuesPrel(getCluster(), traitSet, rowType, content); + return new ValuesPrel(getCluster(), rowType, tuples, traitSet, content); } @Override @@ -87,5 +88,4 @@ public class ValuesPrel extends AbstractRelNode implements Prel { return false; } - } http://git-wip-us.apache.org/repos/asf/drill/blob/33682be9/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/ValuesPrule.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/ValuesPrule.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/ValuesPrule.java index 85d568f..d1f2e28 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/ValuesPrule.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/ValuesPrule.java @@ -1,4 +1,4 @@ -/** +/* * 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 @@ -17,16 +17,12 @@ */ package org.apache.drill.exec.planner.physical; -import java.io.IOException; - import org.apache.calcite.plan.RelOptRule; import org.apache.drill.exec.planner.logical.DrillValuesRel; import org.apache.drill.exec.planner.logical.RelOptHelper; -import org.apache.calcite.plan.RelOptRule; import org.apache.calcite.plan.RelOptRuleCall; public class ValuesPrule extends RelOptRule { - private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(ValuesPrule.class); public static final ValuesPrule INSTANCE = new ValuesPrule(); @@ -37,13 +33,7 @@ public class ValuesPrule extends RelOptRule { @Override public void onMatch(final RelOptRuleCall call) { final DrillValuesRel rel = (DrillValuesRel) call.rel(0); - try{ - call.transformTo(new ValuesPrel(rel.getCluster(), rel.getTraitSet().plus(Prel.DRILL_PHYSICAL), rel.getRowType(), rel.getTuplesAsJsonOptions())); - }catch(IOException e){ - logger.warn("Failure while converting JSONOptions.", e); - } + call.transformTo(new ValuesPrel(rel.getCluster(), rel.getRowType(), rel.getTuples(), rel.getTraitSet().plus(Prel.DRILL_PHYSICAL), rel.getContent())); } - - } http://git-wip-us.apache.org/repos/asf/drill/blob/33682be9/exec/java-exec/src/test/java/org/apache/drill/TestUnionAll.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/test/java/org/apache/drill/TestUnionAll.java b/exec/java-exec/src/test/java/org/apache/drill/TestUnionAll.java index 9046df6..924486f 100644 --- a/exec/java-exec/src/test/java/org/apache/drill/TestUnionAll.java +++ b/exec/java-exec/src/test/java/org/apache/drill/TestUnionAll.java @@ -1180,4 +1180,15 @@ public class TestUnionAll extends BaseTestQuery{ } } + @Test // DRILL-5130 + public void testUnionAllWithValues() throws Exception { + testBuilder() + .sqlQuery("values('A') union all values('B')") + .unOrdered() + .baselineColumns("EXPR$0") + .baselineValues("A") + .baselineValues("B") + .go(); + } + } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/drill/blob/33682be9/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/filter/TestLargeInClause.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/filter/TestLargeInClause.java b/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/filter/TestLargeInClause.java index 22826b4..aff2a60 100644 --- a/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/filter/TestLargeInClause.java +++ b/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/filter/TestLargeInClause.java @@ -87,7 +87,7 @@ public class TestLargeInClause extends BaseTestQuery { testBuilder() .sqlQuery(query) - .ordered() + .unOrdered() .baselineColumns("r_regionkey") .baselineValues(1) .baselineValues(2)