예제 #1
0
  @Description("substring of given length starting at an index")
  @ScalarFunction
  @SqlType(VarcharType.class)
  public static Slice substr(
      @SqlType(VarcharType.class) Slice slice,
      @SqlType(BigintType.class) long start,
      @SqlType(BigintType.class) long length) {
    if ((start == 0) || (length <= 0)) {
      return Slices.EMPTY_SLICE;
    }

    if (start > 0) {
      // make start zero-based
      start--;
    } else {
      // negative start is relative to end of string
      start += slice.length();
      if (start < 0) {
        return Slices.EMPTY_SLICE;
      }
    }

    if ((start + length) > slice.length()) {
      length = slice.length() - start;
    }

    if (start >= slice.length()) {
      return Slices.EMPTY_SLICE;
    }

    return slice.slice((int) start, (int) length);
  }
예제 #2
0
 private static int firstNonSpace(Slice slice) {
   for (int i = 0; i < slice.length(); i++) {
     if (slice.getByte(i) != ' ') {
       return i;
     }
   }
   return slice.length();
 }
예제 #3
0
 @Description("converts all the alphabets in the string to upper case")
 @ScalarFunction
 @SqlType(VarcharType.class)
 public static Slice upper(@SqlType(VarcharType.class) Slice slice) {
   Slice upper = Slices.allocate(slice.length());
   for (int i = 0; i < slice.length(); i++) {
     upper.setByte(i, Ascii.toUpperCase((char) slice.getByte(i)));
   }
   return upper;
 }
예제 #4
0
 @Description("concatenates given strings")
 @ScalarFunction
 @SqlType(VarcharType.class)
 public static Slice concat(
     @SqlType(VarcharType.class) Slice str1, @SqlType(VarcharType.class) Slice str2) {
   Slice concat = Slices.allocate(str1.length() + str2.length());
   concat.setBytes(0, str1);
   concat.setBytes(str1.length(), str2);
   return concat;
 }
예제 #5
0
 @Description("reverses the given string")
 @ScalarFunction
 @SqlType(VarcharType.class)
 public static Slice reverse(@SqlType(VarcharType.class) Slice slice) {
   Slice reverse = Slices.allocate(slice.length());
   for (int i = 0, j = slice.length() - 1; i < slice.length(); i++, j--) {
     reverse.setByte(j, slice.getByte(i));
   }
   return reverse;
 }
예제 #6
0
  @Override
  public void serialize(MaxOrMinByState state, BlockBuilder out) {
    SliceOutput sliceOutput = new DynamicSliceOutput((int) state.getEstimatedSize());

    int keyLength = 0;
    if (state.getKey() != null && !state.getKey().isNull(0)) {
      keyLength = state.getKey().getLength(0);
    }
    sliceOutput.writeInt(keyLength);

    int valueLength = 0;
    if (state.getValue() != null && !state.getValue().isNull(0)) {
      valueLength = state.getValue().getLength(0);
    }
    sliceOutput.writeInt(valueLength);

    if (state.getKey() != null && !state.getKey().isNull(0)) {
      appendTo(keyType, sliceOutput, state.getKey());
    }
    if (state.getValue() != null && !state.getValue().isNull(0)) {
      appendTo(valueType, sliceOutput, state.getValue());
    }
    Slice slice = sliceOutput.slice();
    out.writeBytes(slice, 0, slice.length());
    out.closeEntry();
  }
예제 #7
0
 @Description("removes spaces from the beginning of a string")
 @ScalarFunction("ltrim")
 @SqlType(VarcharType.class)
 public static Slice leftTrim(@SqlType(VarcharType.class) Slice slice) {
   int start = firstNonSpace(slice);
   return slice.slice(start, slice.length() - start);
 }
예제 #8
0
 @Description("suffix starting at given index")
 @ScalarFunction
 @SqlType(VarcharType.class)
 public static Slice substr(
     @SqlType(VarcharType.class) Slice slice, @SqlType(BigintType.class) long start) {
   return substr(slice, start, slice.length());
 }
예제 #9
0
 private static int lastNonSpace(Slice slice) {
   for (int i = slice.length() - 1; i >= 0; i--) {
     if (slice.getByte(i) != ' ') {
       return i;
     }
   }
   return -1;
 }
  private Block createZeroBlock(Type type, int rowsCount, Slice constantSlice) {
    checkArgument(isSupportedType(type), "Unsupported type [%s]", type);

    Slice slice;
    // do not exceed varchar limit
    if (isVarcharType(type)) {
      slice =
          constantSlice.slice(
              0, Math.min(((VarcharType) type).getLength(), constantSlice.length()));
    } else if (isLongDecimal(type)) {
      slice = encodeScaledValue(ZERO);
    } else {
      slice = constantSlice;
    }

    BlockBuilder builder;
    if (type instanceof FixedWidthType) {
      builder = type.createBlockBuilder(new BlockBuilderStatus(), rowsCount);
    } else {
      builder = type.createBlockBuilder(new BlockBuilderStatus(), rowsCount, slice.length());
    }

    for (int i = 0; i < rowsCount; i++) {
      Class<?> javaType = type.getJavaType();
      if (javaType == boolean.class) {
        type.writeBoolean(builder, false);
      } else if (javaType == long.class) {
        type.writeLong(builder, 0);
      } else if (javaType == double.class) {
        type.writeDouble(builder, 0.0);
      } else if (javaType == Slice.class) {
        requireNonNull(slice, "slice is null");
        type.writeSlice(builder, slice, 0, slice.length());
      } else {
        throw new UnsupportedOperationException("Unknown javaType: " + javaType.getName());
      }
    }
    return builder.build();
  }
예제 #11
0
  @Description("removes spaces from the beginning and end of a string")
  @ScalarFunction
  @SqlType(VarcharType.class)
  public static Slice trim(@SqlType(VarcharType.class) Slice slice) {
    int start = firstNonSpace(slice);
    if (start == slice.length()) {
      return Slices.EMPTY_SLICE;
    }

    int end = lastNonSpace(slice);
    assert (end >= 0) && (end >= start);

    return slice.slice(start, (end - start) + 1);
  }
예제 #12
0
  // TODO: Implement a more efficient string search
  @Nullable
  @Description("splits a string by a delimiter and returns the specified field (counting from one)")
  @ScalarFunction
  @SqlType(VarcharType.class)
  public static Slice splitPart(
      @SqlType(VarcharType.class) Slice string,
      @SqlType(VarcharType.class) Slice delimiter,
      @SqlType(BigintType.class) long index) {
    checkArgument(index > 0, "Index must be greater than zero");

    if (delimiter.length() == 0) {
      if (index > string.length()) {
        // index is too big, null is returned
        return null;
      }
      return string.slice((int) (index - 1), 1);
    }

    int previousIndex = 0;
    int matchCount = 0;

    for (int i = 0; i <= (string.length() - delimiter.length()); i++) {
      if (string.equals(i, delimiter.length(), delimiter, 0, delimiter.length())) {
        matchCount++;
        if (matchCount == index) {
          return string.slice(previousIndex, i - previousIndex);
        }
        // noinspection AssignmentToForLoopParameter
        i += (delimiter.length() - 1);
        previousIndex = i + 1;
      }
    }

    if (matchCount == index - 1) {
      // returns last section of the split
      return string.slice(previousIndex, string.length() - previousIndex);
    }

    // index is too big, null is returned
    return null;
  }
예제 #13
0
  @Description("returns index of first occurrence of a substring (or 0 if not found)")
  @ScalarFunction("strpos")
  @SqlType(BigintType.class)
  public static long stringPosition(
      @SqlType(VarcharType.class) Slice string, @SqlType(VarcharType.class) Slice substring) {
    if (substring.length() > string.length()) {
      return 0;
    }

    for (int i = 0; i <= (string.length() - substring.length()); i++) {
      if (string.equals(i, substring.length(), substring, 0, substring.length())) {
        return i + 1;
      }
    }

    return 0;
  }
예제 #14
0
 @Override
 public BlockBuilder appendSlice(Slice value) {
   return appendSlice(value, 0, value.length());
 }
예제 #15
0
  @SuppressWarnings("fallthrough")
  public static DateTimeFormatter createDateTimeFormatter(Slice format) {
    DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();

    String formatString = format.toString(Charsets.UTF_8);
    boolean escaped = false;
    for (int i = 0; i < format.length(); i++) {
      char character = formatString.charAt(i);

      if (escaped) {
        switch (character) {
          case 'a': // %a Abbreviated weekday name (Sun..Sat)
            builder.appendDayOfWeekShortText();
            break;
          case 'b': // %b Abbreviated month name (Jan..Dec)
            builder.appendMonthOfYearShortText();
            break;
          case 'c': // %c Month, numeric (0..12)
            builder.appendMonthOfYear(1);
            break;
          case 'd': // %d Day of the month, numeric (00..31)
            builder.appendDayOfMonth(2);
            break;
          case 'e': // %e Day of the month, numeric (0..31)
            builder.appendDayOfMonth(1);
            break;
          case 'f': // %f Microseconds (000000..999999)
            builder.appendMillisOfSecond(6);
            break;
          case 'H': // %H Hour (00..23)
            builder.appendHourOfDay(2);
            break;
          case 'h': // %h Hour (01..12)
          case 'I': // %I Hour (01..12)
            builder.appendClockhourOfHalfday(2);
            break;
          case 'i': // %i Minutes, numeric (00..59)
            builder.appendMinuteOfHour(2);
            break;
          case 'j': // %j Day of year (001..366)
            builder.appendDayOfYear(3);
            break;
          case 'k': // %k Hour (0..23)
            builder.appendClockhourOfDay(1);
            break;
          case 'l': // %l Hour (1..12)
            builder.appendClockhourOfHalfday(1);
            break;
          case 'M': // %M Month name (January..December)
            builder.appendMonthOfYearText();
            break;
          case 'm': // %m Month, numeric (00..12)
            builder.appendMonthOfYear(2);
            break;
          case 'p': // %p AM or PM
            builder.appendHalfdayOfDayText();
            break;
          case 'r': // %r Time, 12-hour (hh:mm:ss followed by AM or PM)
            builder
                .appendClockhourOfHalfday(2)
                .appendLiteral(':')
                .appendMinuteOfHour(2)
                .appendLiteral(':')
                .appendSecondOfMinute(2)
                .appendLiteral(' ')
                .appendHalfdayOfDayText();
            break;
          case 'S': // %S Seconds (00..59)
          case 's': // %s Seconds (00..59)
            builder.appendSecondOfMinute(2);
            break;
          case 'T': // %T Time, 24-hour (hh:mm:ss)
            builder
                .appendHourOfDay(2)
                .appendLiteral(':')
                .appendMinuteOfHour(2)
                .appendLiteral(':')
                .appendSecondOfMinute(2);
            break;
          case 'v': // %v Week (01..53), where Monday is the first day of the week; used with %x
            builder.appendWeekOfWeekyear(2);
            break;
          case 'x': // %x Year for the week, where Monday is the first day of the week, numeric,
                    // four digits; used with %v
            builder.appendWeekyear(4, 4);
            break;
          case 'W': // %W Weekday name (Sunday..Saturday)
            builder.appendDayOfWeekText();
            break;
          case 'w': // %w Day of the week (0=Sunday..6=Saturday)
            builder.appendDayOfWeek(1);
            break;
          case 'Y': // %Y Year, numeric, four digits
            builder.appendYear(4, 4);
            break;
          case 'y': // %y Year, numeric (two digits)
            builder.appendYearOfCentury(2, 2);
            break;
          case 'U': // %U Week (00..53), where Sunday is the first day of the week
          case 'u': // %u Week (00..53), where Monday is the first day of the week
          case 'V': // %V Week (01..53), where Sunday is the first day of the week; used with %X
          case 'X': // %X Year for the week where Sunday is the first day of the week, numeric, four
                    // digits; used with %V
          case 'D': // %D Day of the month with English suffix (0th, 1st, 2nd, 3rd, …)
            throw new PrestoException(
                INVALID_FUNCTION_ARGUMENT.toErrorCode(),
                String.format("%%%s not supported in date format string", character));
          case '%': // %% A literal “%” character
            builder.appendLiteral('%');
            break;
          default: // %<x> The literal character represented by <x>
            builder.appendLiteral(character);
            break;
        }
        escaped = false;
      } else if (character == '%') {
        escaped = true;
      } else {
        builder.appendLiteral(character);
      }
    }

    try {
      return builder.toFormatter();
    } catch (UnsupportedOperationException e) {
      throw new PrestoException(INVALID_FUNCTION_ARGUMENT.toErrorCode(), e);
    }
  }
예제 #16
0
 public long getMemorySize() {
   return slice.length() + sizeOf(positionOffsets.elements());
 }
예제 #17
0
 @Description("length of the given string")
 @ScalarFunction
 @SqlType(BigintType.class)
 public static long length(@SqlType(VarcharType.class) Slice slice) {
   return slice.length();
 }