Repository: drill
Updated Branches:
  refs/heads/master e3fbc6a19 -> 645e43fd3


DRILL-3364: Prune scan range if the filter is on the leading field with byte 
comparable encoding

The change adds support to perform row-key range pruning when the row-key prefix
is interpreted as UINT4_BE, TIMESTAMP_EPOCH_BE, TIME_EPOCH_BE, DATE_EPOCH_BE,
UINT8_BE encoded.

Testing Done: Added a unit-tests for the new feature, also ran all existing
unit-tests to make sure there is no regression.


Project: http://git-wip-us.apache.org/repos/asf/drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/645e43fd
Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/645e43fd
Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/645e43fd

Branch: refs/heads/master
Commit: 645e43fd34ce3b70f14df4e3d21c9c04ca9314f1
Parents: e3fbc6a
Author: Smidth Panchamia <spancha...@mapr.com>
Authored: Mon Jul 27 14:14:20 2015 -0700
Committer: Aditya Kishore <a...@apache.org>
Committed: Fri Aug 14 22:34:33 2015 -0700

----------------------------------------------------------------------
 .../store/hbase/CompareFunctionsProcessor.java  | 335 +++++++++++++++----
 .../exec/store/hbase/HBaseFilterBuilder.java    |  21 ++
 .../org/apache/drill/hbase/HBaseTestsSuite.java |  17 +-
 .../drill/hbase/TestHBaseFilterPushDown.java    | 167 +++++++++
 .../apache/drill/hbase/TestTableGenerator.java  | 125 +++++++
 .../impl/conv/TimeStampEpochBEConvertFrom.java  |  45 +++
 .../fn/impl/conv/TimeStampEpochBEConvertTo.java |  54 +++
 .../fn/impl/conv/TimeStampEpochConvertFrom.java |  47 +++
 .../fn/impl/conv/TimeStampEpochConvertTo.java   |  55 +++
 .../expr/fn/impl/conv/UInt4BEConvertFrom.java   |  45 +++
 .../expr/fn/impl/conv/UInt4BEConvertTo.java     |  54 +++
 .../expr/fn/impl/conv/UInt4ConvertFrom.java     |  46 +++
 .../exec/expr/fn/impl/conv/UInt4ConvertTo.java  |  55 +++
 13 files changed, 1007 insertions(+), 59 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/drill/blob/645e43fd/contrib/storage-hbase/src/main/java/org/apache/drill/exec/store/hbase/CompareFunctionsProcessor.java
----------------------------------------------------------------------
diff --git 
a/contrib/storage-hbase/src/main/java/org/apache/drill/exec/store/hbase/CompareFunctionsProcessor.java
 
b/contrib/storage-hbase/src/main/java/org/apache/drill/exec/store/hbase/CompareFunctionsProcessor.java
index 803f520..87eb42e 100644
--- 
a/contrib/storage-hbase/src/main/java/org/apache/drill/exec/store/hbase/CompareFunctionsProcessor.java
+++ 
b/contrib/storage-hbase/src/main/java/org/apache/drill/exec/store/hbase/CompareFunctionsProcessor.java
@@ -20,6 +20,7 @@ package org.apache.drill.exec.store.hbase;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 
+import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 
 import org.apache.drill.common.expression.CastExpression;
@@ -35,7 +36,11 @@ import 
org.apache.drill.common.expression.ValueExpressions.IntExpression;
 import org.apache.drill.common.expression.ValueExpressions.LongExpression;
 import org.apache.drill.common.expression.ValueExpressions.QuotedString;
 import org.apache.drill.common.expression.ValueExpressions.TimeExpression;
+import org.apache.drill.common.expression.ValueExpressions.TimeStampExpression;
 import org.apache.drill.common.expression.visitors.AbstractExprVisitor;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.filter.Filter;
+import org.apache.hadoop.hbase.filter.PrefixFilter;
 
 import com.google.common.base.Charsets;
 import com.google.common.collect.ImmutableMap;
@@ -48,6 +53,14 @@ class CompareFunctionsProcessor extends 
AbstractExprVisitor<Boolean, LogicalExpr
   private SchemaPath path;
   private String functionName;
 
+  // Fields for row-key prefix comparison
+  // If the query is on row-key prefix, we cannot use a standard template to 
identify startRow, stopRow and filter
+  // Hence, we use these local variables(set depending upon the encoding type 
in user query)
+  private boolean isRowKeyPrefixComparison;
+  byte[] rowKeyPrefixStartRow;
+  byte[] rowKeyPrefixStopRow;
+  Filter rowKeyPrefixFilter;
+
   public static boolean isCompareFunction(String functionName) {
     return COMPARE_FUNCTIONS_TRANSPOSE_MAP.keySet().contains(functionName);
   }
@@ -79,6 +92,7 @@ class CompareFunctionsProcessor extends 
AbstractExprVisitor<Boolean, LogicalExpr
     this.functionName = functionName;
     this.isEqualityFn = 
COMPARE_FUNCTIONS_TRANSPOSE_MAP.containsKey(functionName)
         && 
COMPARE_FUNCTIONS_TRANSPOSE_MAP.get(functionName).equals(functionName);
+    this.isRowKeyPrefixComparison = false;
   }
 
   public byte[] getValue() {
@@ -97,6 +111,22 @@ class CompareFunctionsProcessor extends 
AbstractExprVisitor<Boolean, LogicalExpr
     return functionName;
   }
 
+  public boolean isRowKeyPrefixComparison() {
+  return isRowKeyPrefixComparison;
+  }
+
+  public byte[] getRowKeyPrefixStartRow() {
+  return rowKeyPrefixStartRow;
+  }
+
+  public byte[] getRowKeyPrefixStopRow() {
+  return rowKeyPrefixStopRow;
+  }
+
+  public Filter getRowKeyPrefixFilter() {
+  return rowKeyPrefixFilter;
+  }
+
   @Override
   public Boolean visitCastExpression(CastExpression e, LogicalExpression 
valueArg) throws RuntimeException {
     if (e.getInput() instanceof CastExpression || e.getInput() instanceof 
SchemaPath) {
@@ -107,79 +137,268 @@ class CompareFunctionsProcessor extends 
AbstractExprVisitor<Boolean, LogicalExpr
 
   @Override
   public Boolean visitConvertExpression(ConvertExpression e, LogicalExpression 
valueArg) throws RuntimeException {
-    if (e.getConvertFunction() == ConvertExpression.CONVERT_FROM && 
e.getInput() instanceof SchemaPath) {
-      ByteBuf bb = null;
+    if (e.getConvertFunction() == ConvertExpression.CONVERT_FROM) {
+
       String encodingType = e.getEncodingType();
-      switch (encodingType) {
-      case "INT_BE":
-      case "INT":
-      case "UINT_BE":
-      case "UINT":
-      case "UINT4_BE":
-      case "UINT4":
-        if (valueArg instanceof IntExpression
-            && (isEqualityFn || encodingType.startsWith("U"))) {
-          bb = newByteBuf(4, encodingType.endsWith("_BE"));
-          bb.writeInt(((IntExpression)valueArg).getInt());
+      int prefixLength    = 0;
+
+      // Handle scan pruning in the following scenario:
+      // The row-key is a composite key and the CONVERT_FROM() function has 
byte_substr() as input function which is
+      // querying for the first few bytes of the row-key(start-offset 1)
+      // Example WHERE clause:
+      // CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'DATE_EPOCH_BE') < DATE 
'2015-06-17'
+      if (e.getInput() instanceof FunctionCall) {
+
+        // We can prune scan range only for big-endian encoded data
+        if (encodingType.endsWith("_BE") == false) {
+          return false;
         }
-        break;
-      case "BIGINT_BE":
-      case "BIGINT":
-      case "UINT8_BE":
-      case "UINT8":
-        if (valueArg instanceof LongExpression
-            && (isEqualityFn || encodingType.startsWith("U"))) {
-          bb = newByteBuf(8, encodingType.endsWith("_BE"));
-          bb.writeLong(((LongExpression)valueArg).getLong());
+
+        FunctionCall call = (FunctionCall)e.getInput();
+        String functionName = call.getName();
+        if (!functionName.equalsIgnoreCase("byte_substr")) {
+          return false;
         }
-        break;
-      case "FLOAT":
-        if (valueArg instanceof FloatExpression && isEqualityFn) {
+
+        LogicalExpression nameArg = call.args.get(0);
+        LogicalExpression valueArg1 = call.args.size() >= 2 ? call.args.get(1) 
: null;
+        LogicalExpression valueArg2 = call.args.size() >= 3 ? call.args.get(2) 
: null;
+
+        if (((nameArg instanceof SchemaPath) == false) ||
+             (valueArg1 == null) || ((valueArg1 instanceof IntExpression) == 
false) ||
+             (valueArg2 == null) || ((valueArg2 instanceof IntExpression) == 
false)) {
+          return false;
+        }
+
+        boolean isRowKey = 
((SchemaPath)nameArg).getAsUnescapedPath().equals(DrillHBaseConstants.ROW_KEY);
+        int offset = ((IntExpression)valueArg1).getInt();
+
+        if (!isRowKey || (offset != 1)) {
+          return false;
+        }
+
+        this.path    = (SchemaPath)nameArg;
+        prefixLength = ((IntExpression)valueArg2).getInt();
+        this.isRowKeyPrefixComparison = true;
+        return visitRowKeyPrefixConvertExpression(e, prefixLength, valueArg);
+      }
+
+      if (e.getInput() instanceof SchemaPath) {
+        ByteBuf bb = null;
+        switch (encodingType) {
+        case "INT_BE":
+        case "INT":
+        case "UINT_BE":
+        case "UINT":
+        case "UINT4_BE":
+        case "UINT4":
+          if (valueArg instanceof IntExpression
+              && (isEqualityFn || encodingType.startsWith("U"))) {
+            bb = newByteBuf(4, encodingType.endsWith("_BE"));
+            bb.writeInt(((IntExpression)valueArg).getInt());
+          }
+          break;
+        case "BIGINT_BE":
+        case "BIGINT":
+        case "UINT8_BE":
+        case "UINT8":
+          if (valueArg instanceof LongExpression
+              && (isEqualityFn || encodingType.startsWith("U"))) {
+            bb = newByteBuf(8, encodingType.endsWith("_BE"));
+            bb.writeLong(((LongExpression)valueArg).getLong());
+          }
+          break;
+        case "FLOAT":
+          if (valueArg instanceof FloatExpression && isEqualityFn) {
           bb = newByteBuf(4, true);
-          bb.writeFloat(((FloatExpression)valueArg).getFloat());
+            bb.writeFloat(((FloatExpression)valueArg).getFloat());
+          }
+          break;
+        case "DOUBLE":
+          if (valueArg instanceof DoubleExpression && isEqualityFn) {
+            bb = newByteBuf(8, true);
+            bb.writeDouble(((DoubleExpression)valueArg).getDouble());
+          }
+          break;
+        case "TIME_EPOCH":
+        case "TIME_EPOCH_BE":
+          if (valueArg instanceof TimeExpression) {
+            bb = newByteBuf(8, encodingType.endsWith("_BE"));
+            bb.writeLong(((TimeExpression)valueArg).getTime());
+          }
+          break;
+        case "DATE_EPOCH":
+        case "DATE_EPOCH_BE":
+          if (valueArg instanceof DateExpression) {
+            bb = newByteBuf(8, encodingType.endsWith("_BE"));
+            bb.writeLong(((DateExpression)valueArg).getDate());
+          }
+          break;
+        case "BOOLEAN_BYTE":
+          if (valueArg instanceof BooleanExpression) {
+            bb = newByteBuf(1, false /* does not matter */);
+            bb.writeByte(((BooleanExpression)valueArg).getBoolean() ? 1 : 0);
+          }
+          break;
+        case "UTF8":
+          // let visitSchemaPath() handle this.
+          return e.getInput().accept(this, valueArg);
         }
-        break;
-      case "DOUBLE":
-        if (valueArg instanceof DoubleExpression && isEqualityFn) {
-          bb = newByteBuf(8, true);
-          bb.writeDouble(((DoubleExpression)valueArg).getDouble());
+
+        if (bb != null) {
+          this.value = bb.array();
+          this.path = (SchemaPath)e.getInput();
+          return true;
         }
-        break;
-      case "TIME_EPOCH":
-      case "TIME_EPOCH_BE":
-        if (valueArg instanceof TimeExpression) {
-          bb = newByteBuf(8, encodingType.endsWith("_BE"));
-          bb.writeLong(((TimeExpression)valueArg).getTime());
+      }
+    }
+    return false;
+  }
+
+  private Boolean visitRowKeyPrefixConvertExpression(ConvertExpression e,
+    int prefixLength, LogicalExpression valueArg) {
+    String encodingType = e.getEncodingType();
+    rowKeyPrefixStartRow = HConstants.EMPTY_START_ROW;
+    rowKeyPrefixStopRow  = HConstants.EMPTY_START_ROW;
+    rowKeyPrefixFilter   = null;
+
+    if ((encodingType.compareTo("UINT4_BE") == 0) ||
+        (encodingType.compareTo("UINT_BE") == 0)) {
+      if (prefixLength != 4) {
+        throw new RuntimeException("Invalid length(" + prefixLength + ") of 
row-key prefix");
+      }
+
+      int val;
+      if ((valueArg instanceof IntExpression) == false) {
+        return false;
+      }
+
+      val = ((IntExpression)valueArg).getInt();
+
+      // For TIME_EPOCH_BE/BIGINT_BE encoding, the operators that we push-down 
are =, <>, <, <=, >, >=
+      switch (functionName) {
+      case "equal":
+      rowKeyPrefixFilter = new 
PrefixFilter(ByteBuffer.allocate(4).putInt(val).array());
+      rowKeyPrefixStartRow = ByteBuffer.allocate(4).putInt(val).array();
+      rowKeyPrefixStopRow = ByteBuffer.allocate(4).putInt(val + 1).array();
+      return true;
+    case "greater_than_or_equal_to":
+      rowKeyPrefixStartRow = ByteBuffer.allocate(4).putInt(val).array();
+        return true;
+      case "greater_than":
+      rowKeyPrefixStartRow = ByteBuffer.allocate(4).putInt(val + 1).array();
+        return true;
+      case "less_than_or_equal_to":
+        rowKeyPrefixStopRow = ByteBuffer.allocate(4).putInt(val + 1).array();
+        return true;
+      case "less_than":
+        rowKeyPrefixStopRow = ByteBuffer.allocate(4).putInt(val).array();
+        return true;
+      }
+
+      return false;
+    }
+
+    if ((encodingType.compareTo("TIMESTAMP_EPOCH_BE") == 0) ||
+        (encodingType.compareTo("TIME_EPOCH_BE") == 0) ||
+        (encodingType.compareTo("UINT8_BE") == 0)) {
+
+      if (prefixLength != 8) {
+        throw new RuntimeException("Invalid length(" + prefixLength + ") of 
row-key prefix");
+      }
+
+      long val;
+      if (encodingType.compareTo("TIME_EPOCH_BE") == 0) {
+        if ((valueArg instanceof TimeExpression) == false) {
+          return false;
         }
-        break;
-      case "DATE_EPOCH":
-      case "DATE_EPOCH_BE":
-        if (valueArg instanceof DateExpression) {
-          bb = newByteBuf(8, encodingType.endsWith("_BE"));
-          bb.writeLong(((DateExpression)valueArg).getDate());
+
+        val = ((TimeExpression)valueArg).getTime();
+      } else if (encodingType.compareTo("UINT8_BE") == 0){
+        if ((valueArg instanceof LongExpression) == false) {
+          return false;
         }
-        break;
-      case "BOOLEAN_BYTE":
-        if (valueArg instanceof BooleanExpression) {
-          bb = newByteBuf(1, false /* does not matter */);
-          bb.writeByte(((BooleanExpression)valueArg).getBoolean() ? 1 : 0);
+
+        val = ((LongExpression)valueArg).getLong();
+      } else if (encodingType.compareTo("TIMESTAMP_EPOCH_BE") == 0) {
+        if ((valueArg instanceof TimeStampExpression) == false) {
+          return false;
         }
-        break;
-      case "UTF8":
-        // let visitSchemaPath() handle this.
-        return e.getInput().accept(this, valueArg);
+
+        val = ((TimeStampExpression)valueArg).getTimeStamp();
+      } else {
+        // Should not reach here.
+        return false;
       }
 
-      if (bb != null) {
-        this.value = bb.array();
-        this.path = (SchemaPath)e.getInput();
+      // For TIME_EPOCH_BE/BIGINT_BE encoding, the operators that we push-down 
are =, <>, <, <=, >, >=
+      switch (functionName) {
+      case "equal":
+        rowKeyPrefixFilter = new 
PrefixFilter(ByteBuffer.allocate(8).putLong(val).array());
+        rowKeyPrefixStartRow = ByteBuffer.allocate(8).putLong(val).array();
+        rowKeyPrefixStopRow = ByteBuffer.allocate(8).putLong(val + 1).array();
+        return true;
+      case "greater_than_or_equal_to":
+        rowKeyPrefixStartRow = ByteBuffer.allocate(8).putLong(val).array();
+        return true;
+      case "greater_than":
+        rowKeyPrefixStartRow = ByteBuffer.allocate(8).putLong(val + 1).array();
+        return true;
+      case "less_than_or_equal_to":
+        rowKeyPrefixStopRow = ByteBuffer.allocate(8).putLong(val + 1).array();
+        return true;
+      case "less_than":
+        rowKeyPrefixStopRow = ByteBuffer.allocate(8).putLong(val).array();
         return true;
       }
+
+      return false;
     }
-    return false;
+
+    if (encodingType.compareTo("DATE_EPOCH_BE") == 0) {
+      if ((valueArg instanceof DateExpression) == false) {
+        return false;
+      }
+
+      if (prefixLength != 8) {
+        throw new RuntimeException("Invalid length(" + prefixLength + ") of 
row-key prefix");
+      }
+
+      final long MILLISECONDS_IN_A_DAY  = (long)1000 * 60 * 60 * 24;
+      long dateToSet;
+      // For DATE encoding, the operators that we push-down are =, <>, <, <=, 
>, >=
+      switch (functionName) {
+      case "equal":
+        long startDate = ((DateExpression)valueArg).getDate();
+        rowKeyPrefixStartRow = 
ByteBuffer.allocate(8).putLong(startDate).array();
+        long stopDate  = ((DateExpression)valueArg).getDate() + 
MILLISECONDS_IN_A_DAY;
+        rowKeyPrefixStopRow = ByteBuffer.allocate(8).putLong(stopDate).array();
+        return true;
+      case "greater_than_or_equal_to":
+        dateToSet = ((DateExpression)valueArg).getDate();
+        rowKeyPrefixStartRow = 
ByteBuffer.allocate(8).putLong(dateToSet).array();
+        return true;
+      case "greater_than":
+        dateToSet = ((DateExpression)valueArg).getDate() + 
MILLISECONDS_IN_A_DAY;
+        rowKeyPrefixStartRow = 
ByteBuffer.allocate(8).putLong(dateToSet).array();
+        return true;
+      case "less_than_or_equal_to":
+        dateToSet = ((DateExpression)valueArg).getDate() + 
MILLISECONDS_IN_A_DAY;
+        rowKeyPrefixStopRow = 
ByteBuffer.allocate(8).putLong(dateToSet).array();
+        return true;
+      case "less_than":
+        dateToSet = ((DateExpression)valueArg).getDate();
+        rowKeyPrefixStopRow = 
ByteBuffer.allocate(8).putLong(dateToSet).array();
+        return true;
+      }
+
+      return false;
   }
 
-  @Override
+  return false;
+}
+
+@Override
   public Boolean visitUnknown(LogicalExpression e, LogicalExpression valueArg) 
throws RuntimeException {
     return false;
   }
@@ -237,4 +456,4 @@ class CompareFunctionsProcessor extends 
AbstractExprVisitor<Boolean, LogicalExpr
         .build();
   }
 
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/645e43fd/contrib/storage-hbase/src/main/java/org/apache/drill/exec/store/hbase/HBaseFilterBuilder.java
----------------------------------------------------------------------
diff --git 
a/contrib/storage-hbase/src/main/java/org/apache/drill/exec/store/hbase/HBaseFilterBuilder.java
 
b/contrib/storage-hbase/src/main/java/org/apache/drill/exec/store/hbase/HBaseFilterBuilder.java
index 245d77d..623846f 100644
--- 
a/contrib/storage-hbase/src/main/java/org/apache/drill/exec/store/hbase/HBaseFilterBuilder.java
+++ 
b/contrib/storage-hbase/src/main/java/org/apache/drill/exec/store/hbase/HBaseFilterBuilder.java
@@ -30,6 +30,7 @@ import org.apache.hadoop.hbase.filter.ByteArrayComparable;
 import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
 import org.apache.hadoop.hbase.filter.Filter;
 import org.apache.hadoop.hbase.filter.NullComparator;
+import org.apache.hadoop.hbase.filter.PrefixFilter;
 import org.apache.hadoop.hbase.filter.RegexStringComparator;
 import org.apache.hadoop.hbase.filter.RowFilter;
 import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
@@ -167,6 +168,10 @@ public class HBaseFilterBuilder extends 
AbstractExprVisitor<HBaseScanSpec, Void,
       return null;
     }
 
+    if (processor.isRowKeyPrefixComparison()) {
+      return createRowKeyPrefixScanSpec(call, processor);
+    }
+
     CompareOp compareOp = null;
     boolean isNullTest = false;
     ByteArrayComparable comparator = new BinaryComparator(fieldValue);
@@ -296,4 +301,20 @@ public class HBaseFilterBuilder extends 
AbstractExprVisitor<HBaseScanSpec, Void,
     return null;
   }
 
+private HBaseScanSpec createRowKeyPrefixScanSpec(FunctionCall call,
+    CompareFunctionsProcessor processor) {
+    byte[] startRow = processor.getRowKeyPrefixStartRow();
+    byte[] stopRow  = processor.getRowKeyPrefixStopRow();
+    Filter filter   = processor.getRowKeyPrefixFilter();
+
+    if (startRow != HConstants.EMPTY_START_ROW ||
+      stopRow != HConstants.EMPTY_END_ROW ||
+      filter != null) {
+      return new HBaseScanSpec(groupScan.getTableName(), startRow, stopRow, 
filter);
+    }
+
+    // else
+    return null;
+}
+
 }

http://git-wip-us.apache.org/repos/asf/drill/blob/645e43fd/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/HBaseTestsSuite.java
----------------------------------------------------------------------
diff --git 
a/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/HBaseTestsSuite.java
 
b/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/HBaseTestsSuite.java
index a77baba..a5dbc6f 100644
--- 
a/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/HBaseTestsSuite.java
+++ 
b/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/HBaseTestsSuite.java
@@ -50,6 +50,9 @@ public class HBaseTestsSuite {
 
   protected static final String TEST_TABLE_1 = "TestTable1";
   protected static final String TEST_TABLE_3 = "TestTable3";
+  protected static final String TEST_TABLE_COMPOSITE_DATE = 
"TestTableCompositeDate";
+  protected static final String TEST_TABLE_COMPOSITE_TIME = 
"TestTableCompositeTime";
+  protected static final String TEST_TABLE_COMPOSITE_INT = 
"TestTableCompositeInt";
 
   private static Configuration conf;
 
@@ -135,7 +138,10 @@ public class HBaseTestsSuite {
   }
 
   private static boolean tablesExist() throws IOException {
-    return admin.tableExists(TEST_TABLE_1) && admin.tableExists(TEST_TABLE_3);
+    return admin.tableExists(TEST_TABLE_1) && admin.tableExists(TEST_TABLE_3) 
&&
+           admin.tableExists(TEST_TABLE_COMPOSITE_DATE) &&
+           admin.tableExists(TEST_TABLE_COMPOSITE_TIME) &&
+           admin.tableExists(TEST_TABLE_COMPOSITE_INT);
   }
 
   private static void createTestTables() throws Exception {
@@ -146,6 +152,9 @@ public class HBaseTestsSuite {
      */
     TestTableGenerator.generateHBaseDataset1(admin, TEST_TABLE_1, 1);
     TestTableGenerator.generateHBaseDataset3(admin, TEST_TABLE_3, 1);
+    TestTableGenerator.generateHBaseDatasetCompositeKeyDate(admin, 
TEST_TABLE_COMPOSITE_DATE, 1);
+    TestTableGenerator.generateHBaseDatasetCompositeKeyTime(admin, 
TEST_TABLE_COMPOSITE_TIME, 1);
+    TestTableGenerator.generateHBaseDatasetCompositeKeyInt(admin, 
TEST_TABLE_COMPOSITE_INT, 1);
   }
 
   private static void cleanupTestTables() throws IOException {
@@ -153,6 +162,12 @@ public class HBaseTestsSuite {
     admin.deleteTable(TEST_TABLE_1);
     admin.disableTable(TEST_TABLE_3);
     admin.deleteTable(TEST_TABLE_3);
+    admin.disableTable(TEST_TABLE_COMPOSITE_DATE);
+    admin.deleteTable(TEST_TABLE_COMPOSITE_DATE);
+    admin.disableTable(TEST_TABLE_COMPOSITE_TIME);
+    admin.deleteTable(TEST_TABLE_COMPOSITE_TIME);
+    admin.disableTable(TEST_TABLE_COMPOSITE_INT);
+    admin.deleteTable(TEST_TABLE_COMPOSITE_INT);
   }
 
   public static int getZookeeperPort() {

http://git-wip-us.apache.org/repos/asf/drill/blob/645e43fd/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/TestHBaseFilterPushDown.java
----------------------------------------------------------------------
diff --git 
a/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/TestHBaseFilterPushDown.java
 
b/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/TestHBaseFilterPushDown.java
index 00de0ba..5c3a463 100644
--- 
a/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/TestHBaseFilterPushDown.java
+++ 
b/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/TestHBaseFilterPushDown.java
@@ -58,6 +58,173 @@ public class TestHBaseFilterPushDown extends BaseHBaseTest {
     PlanTestBase.testPlanMatchingPatterns(sqlHBase, expectedPlan, 
excludedPlan);
   }
 
+
+  @Test
+  public void testFilterPushDownCompositeDateRowKey1() throws Exception {
+    setColumnWidths(new int[] {11, 22, 32});
+    runHBaseSQLVerifyCount("SELECT \n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'date_epoch_be') d\n"
+        + ", CONVERT_FROM(BYTE_SUBSTR(row_key, 9, 8), 'bigint_be') id\n"
+        + ", CONVERT_FROM(tableName.f.c, 'UTF8') \n"
+        + " FROM hbase.`TestTableCompositeDate` tableName\n"
+        + " WHERE\n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'date_epoch_be') < DATE 
'2015-06-18' AND\n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'date_epoch_be') > DATE 
'2015-06-13'"
+        , 12);
+  }
+
+  @Test
+  public void testFilterPushDownCompositeDateRowKey2() throws Exception {
+    setColumnWidths(new int[] {11, 22, 32});
+    runHBaseSQLVerifyCount("SELECT \n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'date_epoch_be') d\n"
+        + ", CONVERT_FROM(BYTE_SUBSTR(row_key, 9, 8), 'bigint_be') id\n"
+        + ", CONVERT_FROM(tableName.f.c, 'UTF8') \n"
+        + " FROM hbase.`TestTableCompositeDate` tableName\n"
+        + " WHERE\n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'date_epoch_be') = DATE 
'2015-08-22'"
+        , 3);
+  }
+
+  @Test
+  public void testFilterPushDownCompositeDateRowKey3() throws Exception {
+    setColumnWidths(new int[] {11, 2000});
+    runHBaseSQLVerifyCount("EXPLAIN PLAN FOR SELECT \n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'date_epoch_be') d\n"
+        + ", CONVERT_FROM(BYTE_SUBSTR(row_key, 9, 8), 'bigint_be') id\n"
+        + ", CONVERT_FROM(tableName.f.c, 'UTF8') \n"
+        + " FROM hbase.`TestTableCompositeDate` tableName\n"
+        + " WHERE\n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'date_epoch_be') < DATE 
'2015-06-18' AND\n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'date_epoch_be') > DATE 
'2015-06-13'"
+        , 1);
+  }
+
+  @Test
+  public void testFilterPushDownCompositeDateRowKey4() throws Exception {
+    setColumnWidths(new int[] {30, 22, 30, 10});
+    runHBaseSQLVerifyCount("SELECT \n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'timestamp_epoch_be') d\n"
+        + ", CONVERT_FROM(BYTE_SUBSTR(row_key, 9, 8), 'bigint_be') id\n"
+        + ", CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'time_epoch_be') t\n"
+        + ", CONVERT_FROM(tableName.f.c, 'UTF8') \n"
+        + " FROM hbase.`TestTableCompositeDate` tableName\n"
+        + " WHERE\n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'timestamp_epoch_be') >= 
TIMESTAMP '2015-06-18 08:00:00.000' AND\n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'timestamp_epoch_be') < 
TIMESTAMP '2015-06-20 16:00:00.000'"
+        , 7);
+  }
+
+  @Test
+  public void testFilterPushDownCompositeTimeRowKey1() throws Exception {
+    setColumnWidths(new int[] {50, 40, 32});
+    runHBaseSQLVerifyCount("SELECT \n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'time_epoch_be') d\n"
+        + ", CONVERT_FROM(BYTE_SUBSTR(row_key, 9, 8), 'bigint_be') id\n"
+        + ", CONVERT_FROM(tableName.f.c, 'UTF8') \n"
+        + " FROM hbase.`TestTableCompositeTime` tableName\n"
+        + " WHERE\n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'time_epoch_be') = TIME 
'23:57:15.275'"//convert_from(binary_string('\\x00\\x00\\x00\\x00\\x55\\x4D\\xBE\\x80'),
 'BIGINT_BE') \n"
+        , 1);
+  }
+
+  @Test
+  public void testFilterPushDownCompositeTimeRowKey2() throws Exception {
+    setColumnWidths(new int[] {30, 2002, 32});
+    runHBaseSQLVerifyCount("EXPLAIN PLAN FOR SELECT \n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'time_epoch_be') d\n"
+        + ", CONVERT_FROM(BYTE_SUBSTR(row_key, 9, 8), 'bigint_be') id\n"
+        + ", CONVERT_FROM(tableName.f.c, 'UTF8') \n"
+        + " FROM hbase.`TestTableCompositeTime` tableName\n"
+        + " WHERE\n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'time_epoch_be') = TIME 
'23:55:51.250'"//convert_from(binary_string('\\x00\\x00\\x00\\x00\\x55\\x4D\\xBE\\x80'),
 'BIGINT_BE') \n"
+        , 1);
+  }
+
+  @Test
+  public void testFilterPushDownCompositeTimeRowKey3() throws Exception {
+    setColumnWidths(new int[] {30, 22, 32});
+    runHBaseSQLVerifyCount("SELECT \n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'time_epoch_be') d\n"
+        + ", CONVERT_FROM(BYTE_SUBSTR(row_key, 9, 8), 'bigint_be') id\n"
+        + ", CONVERT_FROM(tableName.f.c, 'UTF8') \n"
+        + " FROM hbase.`TestTableCompositeTime` tableName\n"
+        + " WHERE\n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'time_epoch_be') > TIME 
'23:57:06' 
AND"//convert_from(binary_string('\\x00\\x00\\x00\\x00\\x55\\x4D\\xBE\\x80'), 
'BIGINT_BE') \n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'time_epoch_be') < TIME 
'23:59:59'"
+        , 8);
+  }
+
+  @Test
+  public void testFilterPushDownCompositeBigIntRowKey1() throws Exception {
+    setColumnWidths(new int[] {15, 40, 32});
+    runHBaseSQLVerifyCount("SELECT \n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'bigint_be') d\n"
+        + ", CONVERT_FROM(BYTE_SUBSTR(row_key, 9, 8), 'bigint_be') id\n"
+        + ", CONVERT_FROM(tableName.f.c, 'UTF8') \n"
+        + " FROM hbase.`TestTableCompositeDate` tableName\n"
+        + " WHERE\n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'bigint_be') = 
cast(1409040000000 as 
bigint)"//convert_from(binary_string('\\x00\\x00\\x00\\x00\\x55\\x4D\\xBE\\x80'),
 'BIGINT_BE') \n"
+        , 1);
+  }
+
+  @Test
+  public void testFilterPushDownCompositeBigIntRowKey2() throws Exception {
+    setColumnWidths(new int[] {16, 22, 32});
+    runHBaseSQLVerifyCount("SELECT \n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'bigint_be') i\n"
+        + ", CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'date_epoch_be') d\n"
+        + ", CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'time_epoch_be') t\n"
+        + ", CONVERT_FROM(BYTE_SUBSTR(row_key, 9, 8), 'bigint_be') id\n"
+        + ", CONVERT_FROM(tableName.f.c, 'UTF8') \n"
+        + " FROM hbase.`TestTableCompositeDate` tableName\n"
+        + " WHERE\n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'uint8_be') > 
cast(1438300800000 as bigint) AND\n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'uint8_be') < 
cast(1438617600000 as bigint)"
+        , 10);
+  }
+
+  @Test
+  public void testFilterPushDownCompositeIntRowKey1() throws Exception {
+    setColumnWidths(new int[] {16, 22, 32});
+    runHBaseSQLVerifyCount("SELECT \n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 4), 'uint4_be') i\n"
+        + ", CONVERT_FROM(BYTE_SUBSTR(row_key, 5, 8), 'bigint_be') id\n"
+        + ", CONVERT_FROM(tableName.f.c, 'UTF8') \n"
+        + " FROM hbase.`TestTableCompositeInt` tableName\n"
+        + " WHERE\n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 4), 'uint4_be') >= cast(423 
as int) AND"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 4), 'uint4_be') < cast(940 as 
int)"
+        , 11);
+  }
+
+  @Test
+  public void testFilterPushDownCompositeIntRowKey2() throws Exception {
+    setColumnWidths(new int[] {16, 2002, 32});
+    runHBaseSQLVerifyCount("EXPLAIN PLAN FOR SELECT \n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 4), 'uint4_be') i\n"
+        + ", CONVERT_FROM(BYTE_SUBSTR(row_key, 5, 8), 'bigint_be') id\n"
+        + ", CONVERT_FROM(tableName.f.c, 'UTF8') \n"
+        + " FROM hbase.`TestTableCompositeInt` tableName\n"
+        + " WHERE\n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 4), 'uint4_be') >= cast(300 
as int) AND"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 4), 'uint4_be') < cast(900 as 
int)"
+        , 1);
+  }
+
+  @Test
+  public void testFilterPushDownCompositeIntRowKey3() throws Exception {
+    setColumnWidths(new int[] {16, 22, 32});
+    runHBaseSQLVerifyCount("SELECT \n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 4), 'uint4_be') i\n"
+        + ", CONVERT_FROM(BYTE_SUBSTR(row_key, 5, 8), 'bigint_be') id\n"
+        + ", CONVERT_FROM(tableName.f.c, 'UTF8') \n"
+        + " FROM hbase.`TestTableCompositeInt` tableName\n"
+        + " WHERE\n"
+        + " CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 4), 'uint4_be') = cast(658 as 
int)"
+        , 1);
+  }
+
   @Test
   public void testFilterPushDownRowKeyLike() throws Exception {
     setColumnWidths(new int[] {8, 22});

http://git-wip-us.apache.org/repos/asf/drill/blob/645e43fd/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/TestTableGenerator.java
----------------------------------------------------------------------
diff --git 
a/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/TestTableGenerator.java
 
b/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/TestTableGenerator.java
index 5cb9aa5..07ae697 100644
--- 
a/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/TestTableGenerator.java
+++ 
b/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/TestTableGenerator.java
@@ -17,7 +17,9 @@
  */
 package org.apache.drill.hbase;
 
+import java.nio.ByteBuffer;
 import java.util.Arrays;
+import java.util.Date;
 import java.util.Random;
 
 import org.apache.hadoop.hbase.HColumnDescriptor;
@@ -206,4 +208,127 @@ public class TestTableGenerator {
     admin.flush(tableName);
   }
 
+  public static void generateHBaseDatasetCompositeKeyDate(HBaseAdmin admin, 
String tableName, int numberRegions) throws Exception {
+    if (admin.tableExists(tableName)) {
+      admin.disableTable(tableName);
+      admin.deleteTable(tableName);
+    }
+
+    HTableDescriptor desc = new HTableDescriptor(tableName);
+    desc.addFamily(new HColumnDescriptor(FAMILY_F));
+
+    if (numberRegions > 1) {
+      admin.createTable(desc, Arrays.copyOfRange(SPLIT_KEYS, 0, 
numberRegions-1));
+    } else {
+      admin.createTable(desc);
+    }
+
+    HTable table = new HTable(admin.getConfiguration(), tableName);
+
+    Date startDate = new Date(1408924800000L);
+    long startTime  = startDate.getTime();
+    long MILLISECONDS_IN_A_DAY  = (long)1000 * 60 * 60 * 24;
+    long MILLISECONDS_IN_A_YEAR = MILLISECONDS_IN_A_DAY * 365;
+    long endTime    = startTime + MILLISECONDS_IN_A_YEAR;
+    long interval   = MILLISECONDS_IN_A_DAY / 3;
+
+    for (long ts = startTime, counter = 0; ts < endTime; ts += interval, 
counter ++) {
+      byte[] rowKey = ByteBuffer.allocate(16) .putLong(ts).array();
+
+      for(int i = 0; i < 8; ++i) {
+        rowKey[8 + i] = (byte)(counter >> (56 - (i * 8)));
+      }
+
+      Put p = new Put(rowKey);
+      p.add(FAMILY_F, COLUMN_C, "dummy".getBytes());
+      table.put(p);
+    }
+
+    table.flushCommits();
+    table.close();
+  }
+
+  public static void generateHBaseDatasetCompositeKeyTime(HBaseAdmin admin, 
String tableName, int numberRegions) throws Exception {
+    if (admin.tableExists(tableName)) {
+      admin.disableTable(tableName);
+      admin.deleteTable(tableName);
+    }
+
+    HTableDescriptor desc = new HTableDescriptor(tableName);
+    desc.addFamily(new HColumnDescriptor(FAMILY_F));
+
+    if (numberRegions > 1) {
+      admin.createTable(desc, Arrays.copyOfRange(SPLIT_KEYS, 0, 
numberRegions-1));
+    } else {
+      admin.createTable(desc);
+    }
+
+    HTable table = new HTable(admin.getConfiguration(), tableName);
+
+    long startTime  = 0;
+    long MILLISECONDS_IN_A_SEC  = (long)1000;
+    long MILLISECONDS_IN_A_DAY = MILLISECONDS_IN_A_SEC * 60 * 60 * 24;
+    long endTime    = startTime + MILLISECONDS_IN_A_DAY;
+    long smallInterval   = 25;
+    long largeInterval   = MILLISECONDS_IN_A_SEC * 42;
+    long interval        = smallInterval;
+
+    for (long ts = startTime, counter = 0; ts < endTime; ts += interval, 
counter ++) {
+      byte[] rowKey = ByteBuffer.allocate(16) .putLong(ts).array();
+
+      for(int i = 0; i < 8; ++i) {
+        rowKey[8 + i] = (byte)(counter >> (56 - (i * 8)));
+      }
+
+      Put p = new Put(rowKey);
+      p.add(FAMILY_F, COLUMN_C, "dummy".getBytes());
+      table.put(p);
+
+      if (interval == smallInterval) {
+        interval = largeInterval;
+      } else {
+        interval = smallInterval;
+      }
+    }
+
+    table.flushCommits();
+    table.close();
+  }
+
+  public static void generateHBaseDatasetCompositeKeyInt(HBaseAdmin admin, 
String tableName, int numberRegions) throws Exception {
+    if (admin.tableExists(tableName)) {
+      admin.disableTable(tableName);
+      admin.deleteTable(tableName);
+    }
+
+    HTableDescriptor desc = new HTableDescriptor(tableName);
+    desc.addFamily(new HColumnDescriptor(FAMILY_F));
+
+    if (numberRegions > 1) {
+      admin.createTable(desc, Arrays.copyOfRange(SPLIT_KEYS, 0, 
numberRegions-1));
+    } else {
+      admin.createTable(desc);
+    }
+
+    HTable table = new HTable(admin.getConfiguration(), tableName);
+
+    int startVal = 0;
+    int stopVal = 1000;
+    int interval = 47;
+    long counter = 0;
+    for (int i = startVal; i < stopVal; i += interval, counter ++) {
+      byte[] rowKey = ByteBuffer.allocate(12).putInt(i).array();
+
+      for(int j = 0; j < 8; ++j) {
+        rowKey[4 + j] = (byte)(counter >> (56 - (j * 8)));
+      }
+
+      Put p = new Put(rowKey);
+      p.add(FAMILY_F, COLUMN_C, "dummy".getBytes());
+      table.put(p);
+    }
+
+    table.flushCommits();
+    table.close();
+  }
 }

http://git-wip-us.apache.org/repos/asf/drill/blob/645e43fd/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/TimeStampEpochBEConvertFrom.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/TimeStampEpochBEConvertFrom.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/TimeStampEpochBEConvertFrom.java
new file mode 100644
index 0000000..eec7159
--- /dev/null
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/TimeStampEpochBEConvertFrom.java
@@ -0,0 +1,45 @@
+/**
+ * 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.expr.fn.impl.conv;
+
+import org.apache.drill.exec.expr.DrillSimpleFunc;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
+import org.apache.drill.exec.expr.annotations.Output;
+import org.apache.drill.exec.expr.annotations.Param;
+import org.apache.drill.exec.expr.holders.TimeStampHolder;
+import org.apache.drill.exec.expr.holders.VarBinaryHolder;
+
+@FunctionTemplate(name = "convert_fromTIMESTAMP_EPOCH_BE", scope = 
FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL)
+public class TimeStampEpochBEConvertFrom implements DrillSimpleFunc {
+
+  @Param VarBinaryHolder in;
+  @Output TimeStampHolder out;
+
+  @Override
+  public void setup() { }
+
+  @Override
+  public void eval() {
+    org.apache.drill.exec.util.ByteBufUtil.checkBufferLength(in.buffer, 
in.start, in.end, 8);
+
+    in.buffer.readerIndex(in.start);
+    out.value = Long.reverseBytes(in.buffer.readLong());
+  }
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/645e43fd/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/TimeStampEpochBEConvertTo.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/TimeStampEpochBEConvertTo.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/TimeStampEpochBEConvertTo.java
new file mode 100644
index 0000000..504cb45
--- /dev/null
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/TimeStampEpochBEConvertTo.java
@@ -0,0 +1,54 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.expr.fn.impl.conv;
+
+import io.netty.buffer.DrillBuf;
+
+import javax.inject.Inject;
+
+import org.apache.drill.exec.expr.DrillSimpleFunc;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
+import org.apache.drill.exec.expr.annotations.Output;
+import org.apache.drill.exec.expr.annotations.Param;
+import org.apache.drill.exec.expr.holders.TimeStampHolder;
+import org.apache.drill.exec.expr.holders.VarBinaryHolder;
+
+@FunctionTemplate(name = "convert_toTIMESTAMP_EPOCH_BE", scope = 
FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL)
+public class TimeStampEpochBEConvertTo implements DrillSimpleFunc {
+
+  @Param TimeStampHolder in;
+  @Output VarBinaryHolder out;
+  @Inject DrillBuf buffer;
+
+
+  @Override
+  public void setup() {
+    buffer = buffer.reallocIfNeeded(8);
+  }
+
+  @Override
+  public void eval() {
+    buffer.clear();
+    buffer.writeLong(Long.reverseBytes(in.value));
+    out.buffer = buffer;
+    out.start = 0;
+    out.end = 8;
+  }
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/645e43fd/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/TimeStampEpochConvertFrom.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/TimeStampEpochConvertFrom.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/TimeStampEpochConvertFrom.java
new file mode 100644
index 0000000..e68d301
--- /dev/null
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/TimeStampEpochConvertFrom.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+
+ * 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.expr.fn.impl.conv;
+
+import org.apache.drill.exec.expr.DrillSimpleFunc;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
+import org.apache.drill.exec.expr.annotations.Output;
+import org.apache.drill.exec.expr.annotations.Param;
+import org.apache.drill.exec.expr.holders.TimeHolder;
+import org.apache.drill.exec.expr.holders.TimeStampHolder;
+import org.apache.drill.exec.expr.holders.VarBinaryHolder;
+
+@FunctionTemplate(name = "convert_fromTIMESTAMP_EPOCH", scope = 
FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL)
+public class TimeStampEpochConvertFrom implements DrillSimpleFunc {
+
+  @Param VarBinaryHolder in;
+  @Output TimeStampHolder out;
+
+  @Override
+  public void setup() { }
+
+  @Override
+  public void eval() {
+    org.apache.drill.exec.util.ByteBufUtil.checkBufferLength(in.buffer, 
in.start, in.end, 8);
+
+    in.buffer.readerIndex(in.start);
+    out.value = in.buffer.readLong();
+  }
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/645e43fd/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/TimeStampEpochConvertTo.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/TimeStampEpochConvertTo.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/TimeStampEpochConvertTo.java
new file mode 100644
index 0000000..4022487
--- /dev/null
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/TimeStampEpochConvertTo.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+
+ * 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.expr.fn.impl.conv;
+
+import io.netty.buffer.DrillBuf;
+
+import javax.inject.Inject;
+
+import org.apache.drill.exec.expr.DrillSimpleFunc;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
+import org.apache.drill.exec.expr.annotations.Output;
+import org.apache.drill.exec.expr.annotations.Param;
+import org.apache.drill.exec.expr.holders.TimeStampHolder;
+import org.apache.drill.exec.expr.holders.VarBinaryHolder;
+
+@FunctionTemplate(name = "convert_toTIMESTAMP_EPOCH", scope = 
FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL)
+public class TimeStampEpochConvertTo implements DrillSimpleFunc {
+
+  @Param TimeStampHolder in;
+  @Output VarBinaryHolder out;
+  @Inject DrillBuf buffer;
+
+
+  @Override
+  public void setup() {
+    buffer = buffer.reallocIfNeeded(8);
+  }
+
+  @Override
+  public void eval() {
+    buffer.clear();
+    buffer.writeLong(in.value);
+    out.buffer = buffer;
+    out.start = 0;
+    out.end = 8;
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/drill/blob/645e43fd/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/UInt4BEConvertFrom.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/UInt4BEConvertFrom.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/UInt4BEConvertFrom.java
new file mode 100644
index 0000000..dd2c29c
--- /dev/null
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/UInt4BEConvertFrom.java
@@ -0,0 +1,45 @@
+/**
+ * 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.expr.fn.impl.conv;
+
+import org.apache.drill.exec.expr.DrillSimpleFunc;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
+import org.apache.drill.exec.expr.annotations.Output;
+import org.apache.drill.exec.expr.annotations.Param;
+import org.apache.drill.exec.expr.holders.UInt4Holder;
+import org.apache.drill.exec.expr.holders.VarBinaryHolder;
+
+@FunctionTemplate(name = "convert_fromUINT4_BE", scope = FunctionScope.SIMPLE, 
nulls = NullHandling.NULL_IF_NULL)
+public class UInt4BEConvertFrom implements DrillSimpleFunc {
+
+  @Param VarBinaryHolder in;
+  @Output UInt4Holder out;
+
+  @Override
+  public void setup() { }
+
+  @Override
+  public void eval() {
+    org.apache.drill.exec.util.ByteBufUtil.checkBufferLength(in.buffer, 
in.start, in.end, 4);
+
+    in.buffer.readerIndex(in.start);
+    out.value = Integer.reverseBytes(in.buffer.readInt());
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/drill/blob/645e43fd/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/UInt4BEConvertTo.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/UInt4BEConvertTo.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/UInt4BEConvertTo.java
new file mode 100644
index 0000000..302f18c
--- /dev/null
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/UInt4BEConvertTo.java
@@ -0,0 +1,54 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.expr.fn.impl.conv;
+
+import io.netty.buffer.DrillBuf;
+
+import javax.inject.Inject;
+
+import org.apache.drill.exec.expr.DrillSimpleFunc;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
+import org.apache.drill.exec.expr.annotations.Output;
+import org.apache.drill.exec.expr.annotations.Param;
+import org.apache.drill.exec.expr.holders.UInt4Holder;
+import org.apache.drill.exec.expr.holders.VarBinaryHolder;
+
+@FunctionTemplate(name = "convert_toUINT4_BE", scope = FunctionScope.SIMPLE, 
nulls = NullHandling.NULL_IF_NULL)
+public class UInt4BEConvertTo implements DrillSimpleFunc {
+
+  @Param UInt4Holder in;
+  @Output VarBinaryHolder out;
+  @Inject DrillBuf buffer;
+
+
+  @Override
+  public void setup() {
+    buffer = buffer.reallocIfNeeded(4);
+  }
+
+  @Override
+  public void eval() {
+    buffer.clear();
+    buffer.writeInt(Integer.reverseBytes(in.value));
+    out.buffer = buffer;
+    out.start = 0;
+    out.end = 4;
+  }
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/645e43fd/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/UInt4ConvertFrom.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/UInt4ConvertFrom.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/UInt4ConvertFrom.java
new file mode 100644
index 0000000..fba2b97
--- /dev/null
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/UInt4ConvertFrom.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+
+ * 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.expr.fn.impl.conv;
+
+import org.apache.drill.exec.expr.DrillSimpleFunc;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
+import org.apache.drill.exec.expr.annotations.Output;
+import org.apache.drill.exec.expr.annotations.Param;
+import org.apache.drill.exec.expr.holders.UInt4Holder;
+import org.apache.drill.exec.expr.holders.VarBinaryHolder;
+
+@FunctionTemplate(name = "convert_fromUINT4", scope = FunctionScope.SIMPLE, 
nulls = NullHandling.NULL_IF_NULL)
+public class UInt4ConvertFrom implements DrillSimpleFunc {
+
+  @Param VarBinaryHolder in;
+  @Output UInt4Holder out;
+
+  @Override
+  public void setup() { }
+
+  @Override
+  public void eval() {
+    org.apache.drill.exec.util.ByteBufUtil.checkBufferLength(in.buffer, 
in.start, in.end, 4);
+
+    in.buffer.readerIndex(in.start);
+    out.value = in.buffer.readInt();
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/drill/blob/645e43fd/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/UInt4ConvertTo.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/UInt4ConvertTo.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/UInt4ConvertTo.java
new file mode 100644
index 0000000..a362bd8
--- /dev/null
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/UInt4ConvertTo.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+
+ * 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.expr.fn.impl.conv;
+
+import io.netty.buffer.DrillBuf;
+
+import javax.inject.Inject;
+
+import org.apache.drill.exec.expr.DrillSimpleFunc;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
+import org.apache.drill.exec.expr.annotations.Output;
+import org.apache.drill.exec.expr.annotations.Param;
+import org.apache.drill.exec.expr.holders.UInt4Holder;
+import org.apache.drill.exec.expr.holders.VarBinaryHolder;
+
+@FunctionTemplate(name = "convert_toUINT4", scope = FunctionScope.SIMPLE, 
nulls = NullHandling.NULL_IF_NULL)
+public class UInt4ConvertTo implements DrillSimpleFunc {
+
+  @Param UInt4Holder in;
+  @Output VarBinaryHolder out;
+  @Inject DrillBuf buffer;
+
+
+  @Override
+  public void setup() {
+    buffer = buffer.reallocIfNeeded(4);
+  }
+
+  @Override
+  public void eval() {
+    buffer.clear();
+    buffer.writeInt(in.value);
+    out.buffer = buffer;
+    out.start = 0;
+    out.end = 4;
+  }
+}
\ No newline at end of file

Reply via email to