You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@drill.apache.org by ts...@apache.org on 2013/01/22 03:35:07 UTC
[1/6] Basic reference interpreter implementation
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/238ca97d/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/NumericValue.java
----------------------------------------------------------------------
diff --git a/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/NumericValue.java b/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/NumericValue.java
new file mode 100644
index 0000000..f690c67
--- /dev/null
+++ b/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/NumericValue.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * 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.ref.values;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import org.apache.drill.common.exceptions.DrillRuntimeException;
+import org.apache.drill.exec.ref.eval.EvaluatorTypes.BasicEvaluator;
+import org.apache.drill.exec.ref.values.ScalarValues.DoubleScalar;
+import org.apache.drill.exec.ref.values.ScalarValues.FloatScalar;
+import org.apache.drill.exec.ref.values.ScalarValues.IntegerScalar;
+import org.apache.drill.exec.ref.values.ScalarValues.LongScalar;
+
+public abstract class NumericValue extends BaseDataValue implements ComparableValue, BasicEvaluator{
+ static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(NumericValue.class);
+
+
+ public static enum NumericType {
+ // order is important for conversion
+ INT, LONG, BIG_INTEGER, FLOAT, DOUBLE, BIG_DECIMAL;
+ }
+
+ public abstract NumericType getNumericType();
+
+ @Override
+ public int compareTo(DataValue dv2) {
+ NumericValue other = dv2.getAsNumeric();
+ NumericType mutual = getMutualType(this, other);
+ switch(mutual){
+ case BIG_DECIMAL:
+ return this.getAsBigDecimal().compareTo(other.getAsBigDecimal());
+ case BIG_INTEGER:
+ return this.getAsBigInteger().compareTo(other.getAsBigInteger());
+ case DOUBLE:
+ return Double.compare(this.getAsDouble(), other.getAsDouble());
+ case FLOAT:
+ return Float.compare(this.getAsFloat(), other.getAsFloat());
+ case INT:
+ return Integer.compare(this.getAsInt(), other.getAsInt());
+ case LONG:
+ return Long.compare(this.getAsInt(), other.getAsInt());
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ public int getHashCode(double d){
+ Long l = Double.doubleToLongBits(d);
+ return (int)(l ^ (l >>> 32));
+ }
+
+ @Override
+ public DataValue eval() {
+ return this;
+ }
+
+ private static NumericType getMutualType(NumericValue... values){
+ int ord = 0;
+ for(int i =0; i < values.length; i++){
+ ord = Math.max(ord, values[i].getNumericType().ordinal());
+ }
+ return NumericType.values()[ord];
+ }
+
+
+
+ @Override
+ public boolean equals(DataValue v) {
+ if(v == null) return false;
+ if(v.getDataType().isNumericType()){
+ return this.compareTo(v) == 0;
+ }else{
+ return false;
+ }
+ }
+
+
+ public static NumericValue add(NumericValue... values){
+ NumericType mutual = getMutualType(values);
+ switch(mutual){
+ case BIG_DECIMAL:
+ throw new UnsupportedOperationException();
+// BigDecimal bd = new BigDecimal(0);
+// for(int i =0; i < values.length; i++){
+// bd = bd.add(values[i].getAsBigDecimal());
+// }
+// return new BigDecimalScalar(bd);
+ case BIG_INTEGER:
+ throw new UnsupportedOperationException();
+//
+// BigInteger bi = BigInteger.valueOf(0);
+// for(int i =0; i < values.length; i++){
+// bi = bi.add(values[i].getAsBigInteger());
+// }
+// return new BigIntegerScalar(bi);
+ case DOUBLE:
+ double d = 0d;
+ for(int i =0; i < values.length; i++){
+ d += values[i].getAsDouble();
+ }
+ return new DoubleScalar(d);
+ case FLOAT:
+ float f = 0f;
+ for(int i =0; i < values.length; i++){
+ f += values[i].getAsFloat();
+ }
+ return new FloatScalar(f);
+ case INT:
+ int x = 0;
+ for(int i =0; i < values.length; i++){
+ x += values[i].getAsInt();
+ }
+ return new IntegerScalar(x);
+ case LONG:
+ int l = 0;
+ for(int i =0; i < values.length; i++){
+ l += values[i].getAsLong();
+ }
+ return new LongScalar(l);
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ @Override
+ public boolean supportsCompare(DataValue dv2) {
+ return dv2.getDataType().isNumericType();
+ }
+
+
+
+
+ @Override
+ public NumericValue getAsNumeric() {
+ return this;
+ }
+
+ public long getAsLong(){
+ throw new DrillRuntimeException(String.format("A %s value can not be implicitly cast to a long.", this.getDataType().getName()));
+ }
+ public int getAsInt(){
+ throw new DrillRuntimeException(String.format("A %s value can not be implicitly cast to an int.", this.getDataType().getName()));
+ }
+ public float getAsFloat(){
+ throw new DrillRuntimeException(String.format("A %s value can not be implicitly cast to an float.", this.getDataType().getName()));
+ }
+ public double getAsDouble(){
+ throw new DrillRuntimeException(String.format("A %s value can not be implicitly cast to a double.", this.getDataType().getName()));
+ }
+ public BigDecimal getAsBigDecimal(){
+ throw new DrillRuntimeException(String.format("A %s value can not be implicitly cast to an big decimal.", this.getDataType().getName()));
+ }
+ public BigInteger getAsBigInteger(){
+ throw new DrillRuntimeException(String.format("A %s value can not be implicitly cast to a big integer.", this.getDataType().getName()));
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/238ca97d/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/ScalarValues.java
----------------------------------------------------------------------
diff --git a/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/ScalarValues.java b/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/ScalarValues.java
new file mode 100644
index 0000000..56e0b9d
--- /dev/null
+++ b/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/ScalarValues.java
@@ -0,0 +1,507 @@
+/*******************************************************************************
+ * 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.ref.values;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Arrays;
+
+import org.apache.drill.common.expression.types.DataType;
+import org.apache.drill.exec.ref.eval.EvaluatorTypes.BasicEvaluator;
+import org.apache.drill.exec.ref.rops.DataWriter;
+import org.apache.hadoop.io.BytesWritable;
+
+import com.google.common.hash.HashFunction;
+import com.google.common.hash.Hashing;
+
+
+public final class ScalarValues {
+ static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(ScalarValues.class);
+
+ private ScalarValues(){}
+
+ public static class StringScalar extends BaseDataValue implements StringValue, ComparableValue, BasicEvaluator {
+ private CharSequence seq;
+
+ public StringScalar(CharSequence seq){
+ this.seq = seq;
+ }
+
+ @Override
+ public int compareTo(DataValue o) {
+ CharSequence seq1 = seq;
+ CharSequence seq2 = o.getAsStringValue().getString();
+ final int len = Math.min(seq1.length(), seq2.length());
+ for(int i =0; i < len; i++){
+ char c1 = seq1.charAt(i);
+ char c2 = seq2.charAt(i);
+ if(c1 != c2){
+ return c1 - c2;
+ }
+ }
+ return seq1.length() - seq2.length();
+ }
+
+ @Override
+ public boolean supportsCompare(DataValue dv2) {
+ return dv2.getDataType() == DataType.NVARCHAR;
+ }
+
+ @Override
+ public void write(DataWriter writer) throws IOException {
+ writer.writeCharSequence(seq);
+ }
+
+ @Override
+ public DataType getDataType() {
+ return DataType.NVARCHAR;
+ }
+
+ @Override
+ public StringValue getAsStringValue() {
+ return this;
+ }
+
+ @Override
+ public CharSequence getString() {
+ return seq;
+ }
+
+ @Override
+ public boolean isConstant() {
+ return true;
+ }
+
+ public DataValue eval(){
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return "StringScalar [seq=" + seq + "]";
+ }
+
+ @Override
+ public boolean equals(DataValue v) {
+ if(v.getDataType() != this.getDataType()) return false;
+ return seq.equals(v.getAsStringValue().getString());
+ }
+
+ @Override
+ public int hashCode() {
+ return seq.hashCode();
+ }
+ }
+
+
+
+ public static class BooleanScalar extends BaseDataValue implements BooleanValue, BasicEvaluator{
+ private boolean b;
+ public BooleanScalar(boolean b){
+ this.b = b;
+ }
+
+ @Override
+ public void write(DataWriter writer) throws IOException {
+ writer.writeBoolean(b);
+ }
+
+ @Override
+ public boolean getBoolean() {
+ return b;
+ }
+
+ @Override
+ public BooleanValue getAsBooleanValue() {
+ return this;
+ }
+
+ @Override
+ public DataType getDataType() {
+ return DataType.BOOLEAN;
+ }
+
+ @Override
+ public boolean isConstant() {
+ return true;
+ }
+
+ @Override
+ public DataValue eval() {
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return "BooleanScalar [b=" + b + "]";
+ }
+
+ @Override
+ public boolean equals(DataValue v) {
+ if(v.getDataType() != this.getDataType()) return false;
+ return b == v.getAsBooleanValue().getBoolean();
+ }
+
+
+ @Override
+ public int hashCode() {
+ return b ? 1 : 0;
+ }
+ }
+
+ public static class LongScalar extends NumericValue{
+ long l;
+ public LongScalar(long l) {
+ this.l = l;
+ }
+
+ @Override
+ public long getAsLong() {
+ return l;
+ }
+
+ @Override
+ public float getAsFloat() {
+ return l;
+ }
+
+ @Override
+ public double getAsDouble() {
+ return l;
+ }
+
+ @Override
+ public BigInteger getAsBigInteger() {
+ return BigInteger.valueOf(l);
+ }
+
+ @Override
+ public BigDecimal getAsBigDecimal() {
+ return BigDecimal.valueOf(l);
+ }
+
+ @Override
+ public void write(DataWriter writer) throws IOException {
+ writer.writeSInt64(l);
+ }
+
+ @Override
+ public DataType getDataType() {
+ return DataType.INT64;
+ }
+
+ @Override
+ public NumericType getNumericType() {
+ return NumericType.LONG;
+ }
+
+ @Override
+ public boolean isConstant() {
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "LongScalar [l=" + l + "]";
+ }
+
+
+ @Override
+ public int hashCode() {
+ return getHashCode(l);
+ }
+
+ }
+
+ public static class IntegerScalar extends NumericValue{
+ int i;
+
+ public IntegerScalar(int i){
+ this.i = i;
+ }
+
+ @Override
+ public BigInteger getAsBigInteger() {
+ return BigInteger.valueOf(i);
+ }
+
+ @Override
+ public BigDecimal getAsBigDecimal() {
+ return BigDecimal.valueOf(i);
+ }
+
+ @Override
+ public void write(DataWriter writer) throws IOException {
+ writer.writeSInt32(i);
+ }
+
+ @Override
+ public DataType getDataType() {
+ return DataType.INT32;
+ }
+
+ @Override
+ public NumericType getNumericType() {
+ return NumericType.INT;
+ }
+
+ @Override
+ public long getAsLong() {
+ return i;
+ }
+
+ @Override
+ public int getAsInt() {
+ return i;
+ }
+
+ @Override
+ public float getAsFloat() {
+ return i;
+ }
+
+ @Override
+ public double getAsDouble() {
+ return i;
+ }
+
+ @Override
+ public boolean isConstant() {
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "IntegerScalar [i=" + i + "]";
+ }
+
+
+ @Override
+ public int hashCode() {
+ return getHashCode(i);
+ }
+
+ }
+
+
+
+ public static class FloatScalar extends NumericValue{
+ float f;
+ public FloatScalar(float f){
+ this.f = f;
+ }
+
+ @Override
+ public BigDecimal getAsBigDecimal() {
+ return BigDecimal.valueOf(f);
+ }
+
+ @Override
+ public void write(DataWriter writer) throws IOException {
+ writer.writeSFloat32(f);
+ }
+
+ @Override
+ public DataType getDataType() {
+ return DataType.FLOAT32;
+ }
+
+ @Override
+ public NumericType getNumericType() {
+ return NumericType.FLOAT;
+ }
+
+ @Override
+ public double getAsDouble() {
+ return f;
+ }
+
+ @Override
+ public boolean isConstant() {
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "FloatScalar [f=" + f + "]";
+ }
+
+ @Override
+ public int hashCode() {
+ return getHashCode(f);
+ }
+ }
+
+
+ public static class DoubleScalar extends NumericValue{
+ private double d;
+ public DoubleScalar(double d){
+ this.d = d;
+ }
+
+ @Override
+ public DataType getDataType() {
+ return DataType.FLOAT64;
+ }
+
+ @Override
+ public NumericType getNumericType() {
+ return NumericType.DOUBLE;
+ }
+
+
+ @Override
+ public double getAsDouble() {
+ return d;
+ }
+
+
+ @Override
+ public BigDecimal getAsBigDecimal() {
+ return BigDecimal.valueOf(d);
+ }
+
+ @Override
+ public void write(DataWriter writer) throws IOException {
+ writer.writeSFloat64(d);
+ }
+
+ @Override
+ public boolean isConstant() {
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "DoubleScalar [d=" + d + "]";
+ }
+
+ @Override
+ public int hashCode() {
+ return getHashCode(d);
+ }
+
+ }
+
+ public static class BytesScalar extends BaseDataValue implements BytesValue{
+ private BytesWritable.Comparator comparator = new BytesWritable.Comparator();
+ private final static HashFunction HASH = Hashing.murmur3_32();
+
+ private byte[] bytes;
+ public BytesScalar(byte[] value){
+ this.bytes = value;
+ }
+
+ @Override
+ public void write(DataWriter writer) throws IOException {
+ writer.writeBytes(bytes);
+ }
+
+ @Override
+ public boolean supportsCompare(DataValue dv2) {
+ return dv2.getDataType() == DataType.BYTES;
+ }
+
+
+ @Override
+ public int compareTo(DataValue other) {
+ byte[] b1 = bytes;
+ byte[] b2 = other.getAsBytesValue().getAsArray();
+ return comparator.compare(b1, 0, bytes.length, b2, 0, bytes.length);
+ }
+
+ @Override
+ public DataType getDataType() {
+ return DataType.BYTES;
+ }
+
+ @Override
+ public byte[] getAsArray() {
+ return bytes;
+ }
+
+ @Override
+ public int getLength() {
+ return bytes.length;
+ }
+
+ @Override
+ public byte get(int pos) {
+ return bytes[pos];
+ }
+
+ @Override
+ public String toString() {
+ return "BytesScalar [bytes=" + Arrays.toString(bytes) + "]";
+ }
+
+ @Override
+ public boolean equals(DataValue v) {
+ if(v.getDataType() != this.getDataType()) return false;
+ BytesValue other = v.getAsBytesValue();
+ if(this.getLength() != other.getLength()) return false;
+ for(int i =0; i < this.getLength(); i++){
+ if(this.get(i) != other.get(i)) return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return HASH.hashBytes(bytes).asInt();
+ }
+ }
+
+
+
+ static class NullValue extends BaseDataValue{
+
+ @Override
+ public void write(DataWriter writer) throws IOException {
+ writer.writeNullValue();
+ }
+
+ @Override
+ public DataType getDataType() {
+ return DataType.NULL;
+ }
+
+ @Override
+ public String toString() {
+ return "NullValue []";
+ }
+
+ @Override
+ public boolean equals(DataValue v) {
+ // identity since there should be only one.
+ return v == this;
+ }
+
+ @Override
+ public int hashCode() {
+ return 0;
+ }
+
+
+
+
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/238ca97d/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/SimpleArrayValue.java
----------------------------------------------------------------------
diff --git a/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/SimpleArrayValue.java b/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/SimpleArrayValue.java
new file mode 100644
index 0000000..d6adefb
--- /dev/null
+++ b/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/SimpleArrayValue.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * 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.ref.values;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Objects;
+
+import org.apache.drill.common.expression.types.DataType;
+import org.apache.drill.exec.ref.rops.DataWriter;
+
+
+public class SimpleArrayValue extends BaseArrayValue{
+ static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(SimpleArrayValue.class);
+
+ private static int padding = 5;
+ private DataValue[] items;
+ private int currentLast = -1;
+
+
+ public SimpleArrayValue(int size){
+ items = new DataValue[size];
+ }
+
+ public SimpleArrayValue(){
+ this(5);
+ }
+
+ @Override
+ public void addToArray(int index, DataValue v) {
+ if( !(index < items.length)){
+ DataValue[] newItems = new DataValue[index + padding];
+ System.arraycopy(items, 0, newItems, 0, items.length);
+ this.items = newItems;
+ }
+ items[index] = v;
+ this.currentLast = Math.max(this.currentLast, index);
+ }
+
+ @Override
+ protected DataValue getByArrayIndex(int index) {
+ if(index < items.length){
+ DataValue ret = items[index];
+ if(ret == null) return NULL_VALUE;
+ return ret;
+ }else{
+ return NULL_VALUE;
+ }
+ }
+
+ @Override
+ protected int getNextIndex() {
+ return currentLast+1;
+ }
+
+ public int size(){
+ return currentLast+1;
+ }
+
+ @Override
+ public void write(DataWriter w) throws IOException {
+ w.writeArrayStart(currentLast+1);
+ for(int i = 0; i <= currentLast; i++){
+ w.writeArrayElementStart();
+ DataValue v = items[i];
+ if(v == null){
+ w.writeNullValue();
+ }else{
+ v.write(w);
+ }
+ w.writeArrayElementEnd();
+ }
+ w.writeArrayEnd();
+ }
+
+
+ @Override
+ public void append(BaseArrayValue container) {
+ int curLen = size();
+ int otherLen = container.size();
+
+ // go backwards so the array gets resized first.
+ for(int i = otherLen -1; i > -1; i--){
+ DataValue v = container.getByArrayIndex(otherLen);
+ this.addToArray(i + curLen, v);
+ }
+
+ }
+
+ @Override
+ public BaseArrayValue getAsArray() {
+ return this;
+ }
+
+ @Override
+ public BaseMapValue getAsMap() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String toString() {
+ return "SimpleArrayValue [items=" + Arrays.toString(items) + ", currentLast=" + currentLast + "]";
+ }
+
+ @Override
+ public boolean equals(DataValue v) {
+ if(v.getDataType() != DataType.MAP) return false;
+ BaseArrayValue other = v.getAsContainer().getAsArray();
+ if(this.size() != other.size()) return false;
+ for(int i =0; i < this.size(); i++){
+ DataValue v1 = this.getByArrayIndex(i);
+ DataValue v2 = other.getByArrayIndex(i);
+ if(!v1.equals(v2)) return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash((Object[]) items);
+ }
+
+
+
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/238ca97d/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/SimpleMapValue.java
----------------------------------------------------------------------
diff --git a/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/SimpleMapValue.java b/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/SimpleMapValue.java
new file mode 100644
index 0000000..1c596e4
--- /dev/null
+++ b/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/SimpleMapValue.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * 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.ref.values;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.drill.common.expression.types.DataType;
+import org.apache.drill.exec.ref.exceptions.RecordException;
+import org.apache.drill.exec.ref.rops.DataWriter;
+
+public class SimpleMapValue extends BaseMapValue{
+ static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(SimpleMapValue.class);
+
+ private HashMap<CharSequence, DataValue> map = new HashMap<CharSequence, DataValue>();
+
+
+ @Override
+ public void setByName(CharSequence name, DataValue v) {
+ if( v== null) throw new RecordException(String.format("You attempted to write a null value with the map key of %s.", name), null);
+ map.put(name, v);
+ }
+
+ @Override
+ protected DataValue getByName(CharSequence name) {
+ return map.get(name);
+ }
+
+ @Override
+ public void write(DataWriter w) throws IOException {
+ w.writeMapStart();
+
+ for(Map.Entry<CharSequence, DataValue> e : map.entrySet()){
+ DataValue v = e.getValue();
+ // skip null values.
+ if(v == null) continue;
+// logger.debug("Writing key {}", e.getKey());
+ w.writeMapKey(e.getKey());
+ w.writeMapValueStart();
+ v.write(w);
+ w.writeMapValueEnd();
+ }
+
+ w.writeMapEnd();
+ }
+
+ @Override
+ public Iterator<Entry<CharSequence, DataValue>> iterator() {
+ return map.entrySet().iterator();
+ }
+
+ @Override
+ public BaseArrayValue getAsArray() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public BaseMapValue getAsMap() {
+ return this;
+ }
+
+ @Override
+ public boolean equals(DataValue v) {
+ if(v == null) return false;
+ if(v.getDataType() != DataType.MAP) return false;
+ BaseMapValue other = v.getAsContainer().getAsMap();
+ for(Entry<CharSequence, DataValue> e : this){
+ DataValue v2 = other.getByName(e.getKey());
+ if(!e.getValue().equals(v2)) return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return map.hashCode();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/238ca97d/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/StringValue.java
----------------------------------------------------------------------
diff --git a/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/StringValue.java b/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/StringValue.java
new file mode 100644
index 0000000..a4b9c64
--- /dev/null
+++ b/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/StringValue.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * 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.ref.values;
+
+public interface StringValue extends DataValue, ComparableValue{
+ public abstract CharSequence getString();
+}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/238ca97d/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/ValueReader.java
----------------------------------------------------------------------
diff --git a/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/ValueReader.java b/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/ValueReader.java
new file mode 100644
index 0000000..9adcca0
--- /dev/null
+++ b/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/ValueReader.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * 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.ref.values;
+
+import org.apache.drill.common.exceptions.DrillRuntimeException;
+import org.apache.drill.common.expression.types.DataType;
+
+public class ValueReader {
+ static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(ValueReader.class);
+
+ public static boolean getBoolean(DataValue v){
+ if(v.getDataType() == DataType.BOOLEAN){
+ return v.getAsBooleanValue().getBoolean();
+ }else{
+ throw new DrillRuntimeException(String.format("Unable to get boolean. Type os a %s", v.getClass().getCanonicalName()));
+ }
+ }
+
+ public static long getLong(DataValue v){
+ if(v.getDataType().isNumericType()){
+ return v.getAsNumeric().getAsLong();
+ }else{
+ throw new DrillRuntimeException(String.format("Unable to get value. %s is not a numeric type.", v.getClass().getCanonicalName()));
+ }
+ }
+ public static double getDouble(DataValue v){
+ if(v.getDataType().isNumericType()){
+ return v.getAsNumeric().getAsDouble();
+ }else{
+ throw new DrillRuntimeException(String.format("Unable to get value. %s is not a numeric type.", v.getClass().getCanonicalName()));
+ }
+ }
+ public static CharSequence getChars(DataValue v){
+ if(v.getDataType() == DataType.NVARCHAR){
+ return v.getAsStringValue().getString();
+ }else{
+ throw new DrillRuntimeException(String.format("Unable to get value. %s is not a StringValue type.", v.getClass().getCanonicalName()));
+ }
+ }
+
+ public static String getString(DataValue v){
+ return getChars(v).toString();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/238ca97d/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/ValueUtils.java
----------------------------------------------------------------------
diff --git a/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/ValueUtils.java b/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/ValueUtils.java
new file mode 100644
index 0000000..ac51d3b
--- /dev/null
+++ b/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/values/ValueUtils.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * 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.ref.values;
+
+import org.apache.drill.common.expression.PathSegment;
+import org.apache.drill.common.expression.ValueExpressions.CollisionBehavior;
+import org.apache.drill.common.expression.types.DataType;
+import org.apache.drill.exec.ref.exceptions.RecordException;
+
+public class ValueUtils {
+ static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(ValueUtils.class);
+
+ public static DataValue getMergedDataValue(CollisionBehavior behavior, DataValue oldValue, DataValue newValue){
+// logger.debug("Checking merged to see if merged value should be added. Segment {}, oldValue: {}, new value: " + newValue, segment, oldValue);
+ if(oldValue == DataValue.NULL_VALUE) return newValue;
+
+ switch(behavior){
+ case SKIP:
+ return oldValue;
+ case REPLACE:
+ return newValue;
+ case FAIL:
+ throw new RecordException("Failure while doing query. The destination specified already contains a value and no collision behavior was provdied.", null);
+ case OBJECTIFY:
+ SimpleMapValue n = new SimpleMapValue();
+ n.setByName("old", oldValue);
+ n.setByName("new", newValue);
+ return n;
+ case ARRAYIFY:
+ SimpleArrayValue a = new SimpleArrayValue();
+ a.addToArray(0, oldValue);
+ a.addToArray(1, newValue);
+ return a;
+ case MERGE_OVERRIDE:
+ DataType oldT = oldValue.getDataType();
+ DataType newT = oldValue.getDataType();
+ if(oldT == DataType.MAP && newT == DataType.MAP){
+ oldValue.getAsContainer().getAsMap().merge(newValue.getAsContainer().getAsMap());
+ return oldValue;
+ }else if(oldT == DataType.ARRAY && newT == DataType.ARRAY){
+ logger.debug("Merging two arrays. {} and {}", oldValue, newValue);
+ oldValue.getAsContainer().getAsArray().append(newValue.getAsContainer().getAsArray());
+ return oldValue;
+ }else if(oldT == DataType.ARRAY || newT == DataType.ARRAY || oldT == DataType.MAP || newT == DataType.MAP){
+ throw new RecordException(String.format("Failure while doing query. You requested a merge of values that were incompatibile. Examples include merging an array and a map or merging a map/array with a scalar. Merge Types were %s and %s.", oldT.getName(), newT.getName()), null);
+ }else{
+ // scalar type, just override the value.
+ return newValue;
+ }
+ default:
+ throw new UnsupportedOperationException();
+
+ }
+ }
+
+ public static DataValue getIntermediateValues(PathSegment missing, DataValue value){
+ if(missing == null) return value;
+
+ DataValue current = missing.isArray() ? new SimpleArrayValue() : new SimpleMapValue();
+ current.addValue(missing, value);
+ return current;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/238ca97d/sandbox/prototype/exec/ref/src/main/resources/logback-test.xml
----------------------------------------------------------------------
diff --git a/sandbox/prototype/exec/ref/src/main/resources/logback-test.xml b/sandbox/prototype/exec/ref/src/main/resources/logback-test.xml
new file mode 100644
index 0000000..9a53c12
--- /dev/null
+++ b/sandbox/prototype/exec/ref/src/main/resources/logback-test.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<configuration>
+
+ <appender name="SOCKET" class="de.huxhorn.lilith.logback.appender.ClassicMultiplexSocketAppender">
+ <Compressing>true</Compressing>
+ <ReconnectionDelay>10000</ReconnectionDelay>
+ <IncludeCallerData>true</IncludeCallerData>
+ <RemoteHosts>localhost</RemoteHosts>
+ </appender>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <!-- encoders are assigned the type
+ ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+
+ <logger name="org.apache.drill" additivity="false">
+ <level value="debug" />
+ <appender-ref ref="SOCKET" />
+ <appender-ref ref="STDOUT" />
+ </logger>
+
+ <root>
+ <level value="error" />
+ <appender-ref ref="SOCKET" />
+ <appender-ref ref="STDOUT" />
+ </root>
+
+
+</configuration>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/238ca97d/sandbox/prototype/exec/ref/src/test/resources/donuts.json
----------------------------------------------------------------------
diff --git a/sandbox/prototype/exec/ref/src/test/resources/donuts.json b/sandbox/prototype/exec/ref/src/test/resources/donuts.json
new file mode 100644
index 0000000..d9d69fe
--- /dev/null
+++ b/sandbox/prototype/exec/ref/src/test/resources/donuts.json
@@ -0,0 +1,129 @@
+
+ {
+ "id": "0001",
+ "type": "donut",
+ "name": "Cake",
+ "ppu": 0.55,
+ "sales": 35,
+
+ "batters":
+ {
+ "batter":
+ [
+ { "id": "1001", "type": "Regular" },
+ { "id": "1002", "type": "Chocolate" },
+ { "id": "1003", "type": "Blueberry" },
+ { "id": "1004", "type": "Devil's Food" }
+ ]
+ },
+ "topping":
+ [
+ { "id": "5001", "type": "None" },
+ { "id": "5002", "type": "Glazed" },
+ { "id": "5005", "type": "Sugar" },
+ { "id": "5007", "type": "Powdered Sugar" },
+ { "id": "5006", "type": "Chocolate with Sprinkles" },
+ { "id": "5003", "type": "Chocolate" },
+ { "id": "5004", "type": "Maple" }
+ ]
+ }
+ {
+ "id": "0002",
+ "type": "donut",
+ "name": "Raised",
+ "ppu": 0.69,
+ "sales": 145,
+ "batters":
+ {
+ "batter":
+ [
+ { "id": "1001", "type": "Regular" }
+ ]
+ },
+ "topping":
+ [
+ { "id": "5001", "type": "None" },
+ { "id": "5002", "type": "Glazed" },
+ { "id": "5005", "type": "Sugar" },
+ { "id": "5003", "type": "Chocolate" },
+ { "id": "5004", "type": "Maple" }
+ ]
+ }
+ {
+ "id": "0003",
+ "type": "donut",
+ "name": "Old Fashioned",
+ "ppu": 0.55,
+ "sales": 300,
+
+ "batters":
+ {
+ "batter":
+ [
+ { "id": "1001", "type": "Regular" },
+ { "id": "1002", "type": "Chocolate" }
+ ]
+ },
+ "topping":
+ [
+ { "id": "5001", "type": "None" },
+ { "id": "5002", "type": "Glazed" },
+ { "id": "5003", "type": "Chocolate" },
+ { "id": "5004", "type": "Maple" }
+ ]
+ }
+ {
+ "id": "0004",
+ "type": "donut",
+ "name": "Filled",
+ "ppu": 0.69,
+ "sales": 14,
+
+ "batters":
+ {
+ "batter":
+ [
+ { "id": "1001", "type": "Regular" },
+ { "id": "1002", "type": "Chocolate" },
+ { "id": "1003", "type": "Blueberry" },
+ { "id": "1004", "type": "Devil's Food" }
+ ]
+ },
+ "topping":
+ [
+ { "id": "5001", "type": "None" },
+ { "id": "5002", "type": "Glazed" },
+ { "id": "5005", "type": "Sugar" },
+ { "id": "5007", "type": "Powdered Sugar" },
+ { "id": "5006", "type": "Chocolate with Sprinkles" },
+ { "id": "5003", "type": "Chocolate" },
+ { "id": "5004", "type": "Maple" }
+ ],
+ "filling":
+ [
+ { "id": "6001", "type": "None" },
+ { "id": "6002", "type": "Raspberry" },
+ { "id": "6003", "type": "Lemon" },
+ { "id": "6004", "type": "Chocolate" },
+ { "id": "6005", "type": "Kreme" }
+ ]
+ }
+ {
+ "id": "0005",
+ "type": "donut",
+ "name": "Apple Fritter",
+ "ppu": 1.00,
+ "sales": 700,
+
+ "batters":
+ {
+ "batter":
+ [
+ { "id": "1001", "type": "Regular" }
+ ]
+ },
+ "topping":
+ [
+ { "id": "5002", "type": "Glazed" }
+ ]
+ }
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/238ca97d/sandbox/prototype/exec/ref/src/test/resources/simple_plan.json
----------------------------------------------------------------------
diff --git a/sandbox/prototype/exec/ref/src/test/resources/simple_plan.json b/sandbox/prototype/exec/ref/src/test/resources/simple_plan.json
new file mode 100644
index 0000000..f4f6b5b
--- /dev/null
+++ b/sandbox/prototype/exec/ref/src/test/resources/simple_plan.json
@@ -0,0 +1,76 @@
+{
+ head:{
+ type:"apache_drill_logical_plan",
+ version:"1",
+ generator:{
+ type:"manual",
+ info:"na"
+ }
+ },
+ sources:[
+ {
+ type:"json",
+ name:"local-logs",
+ files:[
+ "src/test/resources/donuts.json"
+ ]
+ }
+ ],
+ query:[
+ {
+ op:"sequence",
+ do:[
+ {
+ op: "scan",
+ memo: "initial_scan",
+ ref: "donuts",
+ source: "local-logs",
+ selection: {data: "activity"}
+ },
+ {
+ op: "transform",
+ transforms: [
+ { ref: "donuts.quanity", expr: "donuts.sales"}
+ ]
+ },
+ {
+ op: "filter",
+ expr: "donuts.ppu < 1.00"
+ },
+ {
+ op: "group",
+ groupings: [
+ { ref: "donuts.ppu", expr: "donuts.ppu" }
+ ]
+ },
+ {
+ op: "aggregate",
+ type: "simple",
+ keys: ["donuts.ppu"],
+ aggregations: [
+ { ref: "donuts.typeCount", expr: "count(1)" },
+ { ref: "donuts.quantity", expr: "sum(donuts.sales)" },
+ { ref: "donuts.sales", expr: "sum(donuts.ppu * donuts.sales)" }
+ ]
+ },
+ {
+ op: "order",
+ orderings: [
+ {order: "desc", expr: "donuts.ppu" }
+ ]
+ },
+ {
+ op: "project",
+ projections: [
+ { ref: "output", expr: "donuts" }
+ ]
+ },
+ {
+ op: "write",
+ memo: "save file",
+ file: "file:///opt/data/out.json"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/238ca97d/sandbox/prototype/planner/src/main/java/org/apache/drill/App.java
----------------------------------------------------------------------
diff --git a/sandbox/prototype/planner/src/main/java/org/apache/drill/App.java b/sandbox/prototype/planner/src/main/java/org/apache/drill/App.java
deleted file mode 100644
index 201a69c..0000000
--- a/sandbox/prototype/planner/src/main/java/org/apache/drill/App.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.apache.drill;
-
-/**
- * Hello world!
- *
- */
-public class App
-{
- public static void main( String[] args )
- {
- System.out.println( "Hello World!" );
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/238ca97d/sandbox/prototype/planner/src/test/java/org/apache/drill/AppTest.java
----------------------------------------------------------------------
diff --git a/sandbox/prototype/planner/src/test/java/org/apache/drill/AppTest.java b/sandbox/prototype/planner/src/test/java/org/apache/drill/AppTest.java
deleted file mode 100644
index 5908f3e..0000000
--- a/sandbox/prototype/planner/src/test/java/org/apache/drill/AppTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.apache.drill;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-/**
- * Unit test for simple App.
- */
-public class AppTest
- extends TestCase
-{
- /**
- * Create the test case
- *
- * @param testName name of the test case
- */
- public AppTest( String testName )
- {
- super( testName );
- }
-
- /**
- * @return the suite of tests being tested
- */
- public static Test suite()
- {
- return new TestSuite( AppTest.class );
- }
-
- /**
- * Rigourous Test :-)
- */
- public void testApp()
- {
- assertTrue( true );
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/238ca97d/sandbox/prototype/pom.xml
----------------------------------------------------------------------
diff --git a/sandbox/prototype/pom.xml b/sandbox/prototype/pom.xml
index 5ff9617..9d665f1 100644
--- a/sandbox/prototype/pom.xml
+++ b/sandbox/prototype/pom.xml
@@ -3,6 +3,12 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache</groupId>
+ <artifactId>apache</artifactId>
+ <version>9</version>
+ </parent>
+
<groupId>org.apache.drill</groupId>
<artifactId>prototype-parent</artifactId>
<version>1.0-SNAPSHOT</version>
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/238ca97d/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/App.java
----------------------------------------------------------------------
diff --git a/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/App.java b/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/App.java
deleted file mode 100644
index 201a69c..0000000
--- a/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/App.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.apache.drill;
-
-/**
- * Hello world!
- *
- */
-public class App
-{
- public static void main( String[] args )
- {
- System.out.println( "Hello World!" );
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/238ca97d/sandbox/prototype/sqlparser/src/test/java/org/apache/drill/AppTest.java
----------------------------------------------------------------------
diff --git a/sandbox/prototype/sqlparser/src/test/java/org/apache/drill/AppTest.java b/sandbox/prototype/sqlparser/src/test/java/org/apache/drill/AppTest.java
deleted file mode 100644
index 5908f3e..0000000
--- a/sandbox/prototype/sqlparser/src/test/java/org/apache/drill/AppTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.apache.drill;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-/**
- * Unit test for simple App.
- */
-public class AppTest
- extends TestCase
-{
- /**
- * Create the test case
- *
- * @param testName name of the test case
- */
- public AppTest( String testName )
- {
- super( testName );
- }
-
- /**
- * @return the suite of tests being tested
- */
- public static Test suite()
- {
- return new TestSuite( AppTest.class );
- }
-
- /**
- * Rigourous Test :-)
- */
- public void testApp()
- {
- assertTrue( true );
- }
-}