public Boolean visitConvertExpression()

in contrib/storage-hbase/src/main/java/org/apache/drill/exec/store/hbase/CompareFunctionsProcessor.java [178:357]


  public Boolean visitConvertExpression(ConvertExpression e, LogicalExpression valueArg) throws RuntimeException {
    if (ConvertExpression.CONVERT_FROM.equals(e.getConvertFunction())) {

      String encodingType = e.getEncodingType();
      int prefixLength;

      // 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")) {
          return false;
        }

        FunctionCall call = (FunctionCall)e.getInput();
        String functionName = call.getName();
        if (!functionName.equalsIgnoreCase("byte_substr")) {
          return false;
        }

        LogicalExpression nameArg = call.arg(0);
        LogicalExpression valueArg1 = call.argCount() >= 2 ? call.arg(1) : null;
        LogicalExpression valueArg2 = call.argCount() >= 3 ? call.arg(2) : null;

        if (!(nameArg instanceof SchemaPath)
            || (valueArg1 == null) || !(valueArg1 instanceof IntExpression)
            || (valueArg2 == null) || !(valueArg2 instanceof IntExpression)) {
          return false;
        }

        boolean isRowKey = ((SchemaPath) nameArg).getRootSegmentPath().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());
            }
            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 "DOUBLE_OB":
          case "DOUBLE_OBD":
            if (valueArg instanceof DoubleExpression) {
              bb = newByteBuf(9, true);
              PositionedByteRange br = new SimplePositionedMutableByteRange(bb.array(), 0, 9);
              if (encodingType.endsWith("_OBD")) {
                org.apache.hadoop.hbase.util.OrderedBytes.encodeFloat64(br,
                  ((DoubleExpression) valueArg).getDouble(), Order.DESCENDING);
                this.sortOrderAscending = false;
              } else {
                org.apache.hadoop.hbase.util.OrderedBytes.encodeFloat64(br,
                  ((DoubleExpression) valueArg).getDouble(), Order.ASCENDING);
              }
            }
            break;
          case "FLOAT_OB":
          case "FLOAT_OBD":
            if (valueArg instanceof FloatExpression) {
              bb = newByteBuf(5, true);
              PositionedByteRange br = new SimplePositionedMutableByteRange(bb.array(), 0, 5);
              if (encodingType.endsWith("_OBD")) {
                org.apache.hadoop.hbase.util.OrderedBytes.encodeFloat32(br,
                  ((FloatExpression) valueArg).getFloat(), Order.DESCENDING);
                this.sortOrderAscending = false;
              } else {
                org.apache.hadoop.hbase.util.OrderedBytes.encodeFloat32(br,
                          ((FloatExpression) valueArg).getFloat(), Order.ASCENDING);
              }
            }
            break;
          case "BIGINT_OB":
          case "BIGINT_OBD":
            if (valueArg instanceof LongExpression) {
              bb = newByteBuf(9, true);
              PositionedByteRange br = new SimplePositionedMutableByteRange(bb.array(), 0, 9);
              if (encodingType.endsWith("_OBD")) {
                org.apache.hadoop.hbase.util.OrderedBytes.encodeInt64(br,
                          ((LongExpression) valueArg).getLong(), Order.DESCENDING);
                this.sortOrderAscending = false;
              } else {
                org.apache.hadoop.hbase.util.OrderedBytes.encodeInt64(br,
                  ((LongExpression) valueArg).getLong(), Order.ASCENDING);
              }
            }
            break;
          case "INT_OB":
          case "INT_OBD":
            if (valueArg instanceof IntExpression) {
              bb = newByteBuf(5, true);
              PositionedByteRange br = new SimplePositionedMutableByteRange(bb.array(), 0, 5);
              if (encodingType.endsWith("_OBD")) {
                org.apache.hadoop.hbase.util.OrderedBytes.encodeInt32(br,
                  ((IntExpression) valueArg).getInt(), Order.DESCENDING);
                this.sortOrderAscending = false;
              } else {
                org.apache.hadoop.hbase.util.OrderedBytes.encodeInt32(br,
                          ((IntExpression) valueArg).getInt(), Order.ASCENDING);
              }
            }
            break;
          case "UTF8":
            // let visitSchemaPath() handle this.
            return e.getInput().accept(this, valueArg);
          default:
            bb = getByteBuf(valueArg, encodingType);
        }

        if (bb != null) {
          this.value = bb.array();
          this.path = (SchemaPath)e.getInput();
          return true;
        }
      }
    }
    return false;
  }