@Description("removes spaces from the end of a string") @ScalarFunction("rtrim") @SqlType(VarcharType.class) public static Slice rightTrim(@SqlType(VarcharType.class) Slice slice) { int end = lastNonSpace(slice); return slice.slice(0, end + 1); }
@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); }
@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); }
// 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; }
@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); }
public void appendTo(int position, BlockBuilder builder) { checkArgument(position >= 0 && position < positionOffsets.size()); int offset = positionOffsets.getInt(position); if (slice.getByte(offset) != 0) { builder.appendNull(); } else if (type == Type.FIXED_INT_64) { builder.append(slice.getLong(offset + SIZE_OF_BYTE)); } else if (type == Type.DOUBLE) { builder.append(slice.getDouble(offset + SIZE_OF_BYTE)); } else if (type == Type.BOOLEAN) { builder.append(slice.getByte(offset + SIZE_OF_BYTE) != 0); } else if (type == Type.VARIABLE_BINARY) { int sliceLength = getVariableBinaryLength(slice, offset); builder.append(slice.slice(offset + SIZE_OF_BYTE + SIZE_OF_INT, sliceLength)); } else { throw new IllegalArgumentException("Unsupported type " + type); } }
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(); }
@Override public Slice getSlice(Slice slice, int offset) { return slice.slice(offset + SIZE_OF_INT, getValueSize(slice, offset)); }