private void init() { isOffsetConstant = getOffsetExpression() instanceof LiteralExpression; isLengthConstant = getLengthExpression() instanceof LiteralExpression; hasLengthExpression = !isLengthConstant || ((LiteralExpression)getLengthExpression()).getValue() != null; isFixedWidth = getStrExpression().getDataType().isFixedWidth() && ((hasLengthExpression && isLengthConstant) || (!hasLengthExpression && isOffsetConstant)); if (hasLengthExpression && isLengthConstant) { Integer maxLength = ((Number)((LiteralExpression)getLengthExpression()).getValue()).intValue(); this.maxLength = maxLength >= 0 ? maxLength : 0; } else if (isOffsetConstant) { Number offsetNumber = (Number)((LiteralExpression)getOffsetExpression()).getValue(); if (offsetNumber != null) { int offset = offsetNumber.intValue(); PDataType type = getStrExpression().getDataType(); if (type.isFixedWidth()) { if (offset >= 0) { Integer maxLength = getStrExpression().getMaxLength(); this.maxLength = maxLength - offset + (offset == 0 ? 0 : 1); } else { this.maxLength = -offset; } } } } }
@Override public String toString() { StringBuilder buf = new StringBuilder(getName() + "("); if (children.size()==0) return buf.append(")").toString(); if (hasLengthExpression) { buf.append(getStrExpression()); buf.append(", "); buf.append(getOffsetExpression()); buf.append(", "); buf.append(getLengthExpression()); } else { buf.append(getStrExpression()); buf.append(", "); buf.append(getOffsetExpression()); } buf.append(")"); return buf.toString(); }
public SubstrFunction(List<Expression> children) { super(children); init(); }
@Override public boolean isNullable() { return getStrExpression().isNullable() || !isFixedWidth || getOffsetExpression().isNullable(); }
@Override public PDataType getDataType() { // If fixed width, then return child expression type. // If not fixed width, then we don't know how big this will be across the board return isFixedWidth ? getStrExpression().getDataType() : PVarchar.INSTANCE; }
@Override public OrderPreserving preservesOrder() { if (isOffsetConstant) { LiteralExpression literal = (LiteralExpression) getOffsetExpression(); Number offsetNumber = (Number) literal.getValue(); if (offsetNumber != null) { int offset = offsetNumber.intValue(); if ((offset == 0 || offset == 1) && (!hasLengthExpression || isLengthConstant)) { return OrderPreserving.YES_IF_LAST; } } } return OrderPreserving.NO; }
public static Expression substr2(Expression e, Object offset) { return new SubstrFunction(Arrays.asList(e, LiteralExpression.newConstant(offset), LiteralExpression.newConstant(null))); }
@Test public void testSubstrExpressionWithoutLengthVariable() { assertEquals("SUBSTR(ENTITY_ID, 1)",((SubstrFunction)substr2(ENTITY_ID,1)).toString()); }
@Override public boolean isNullable() { return getStrExpression().isNullable() || !isFixedWidth || getOffsetExpression().isNullable(); }
@Override public SortOrder getSortOrder() { return getStrExpression().getSortOrder(); }
@Override public OrderPreserving preservesOrder() { if (isOffsetConstant) { LiteralExpression literal = (LiteralExpression) getOffsetExpression(); Number offsetNumber = (Number) literal.getValue(); if (offsetNumber != null) { int offset = offsetNumber.intValue(); if ((offset == 0 || offset == 1) && (!hasLengthExpression || isLengthConstant)) { return OrderPreserving.YES_IF_LAST; } } } return OrderPreserving.NO; }
public static Expression substr(Expression e, Object offset, Object length) { return new SubstrFunction(Arrays.asList(e, LiteralExpression.newConstant(offset), LiteralExpression.newConstant(length))); }
@Test public void testSubstrExpressionWithLengthVariable() { assertEquals("SUBSTR(ENTITY_ID, 1, 10)",((SubstrFunction)substr(ENTITY_ID,1, 10)).toString()); }
@Override public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) { Expression offsetExpression = getOffsetExpression(); if (!offsetExpression.evaluate(tuple, ptr)) { return false; Expression lengthExpression = getLengthExpression(); if (!lengthExpression.evaluate(tuple, ptr)) { return false; if (!getStrExpression().evaluate(tuple, ptr)) { return false; boolean isCharType = getStrExpression().getDataType() == PChar.INSTANCE; SortOrder sortOrder = getStrExpression().getSortOrder(); int strlen = isCharType ? ptr.getLength() : StringUtil.calculateUTF8Length(ptr.get(), ptr.getOffset(), ptr.getLength(), sortOrder);
@Override public String toString() { StringBuilder buf = new StringBuilder(getName() + "("); if (children.size()==0) return buf.append(")").toString(); if (hasLengthExpression) { buf.append(getStrExpression()); buf.append(", "); buf.append(getOffsetExpression()); buf.append(", "); buf.append(getLengthExpression()); } else { buf.append(getStrExpression()); buf.append(", "); buf.append(getOffsetExpression()); } buf.append(")"); return buf.toString(); }
@Override public boolean isNullable() { return getStrExpression().isNullable() || !isFixedWidth || getOffsetExpression().isNullable(); }
@Override public PDataType getDataType() { // If fixed width, then return child expression type. // If not fixed width, then we don't know how big this will be across the board return isFixedWidth ? getStrExpression().getDataType() : PVarchar.INSTANCE; }
@Override public void readFields(DataInput input) throws IOException { super.readFields(input); init(); }
@Override public OrderPreserving preservesOrder() { if (isOffsetConstant) { LiteralExpression literal = (LiteralExpression) getOffsetExpression(); Number offsetNumber = (Number) literal.getValue(); if (offsetNumber != null) { int offset = offsetNumber.intValue(); if ((offset == 0 || offset == 1) && (!hasLengthExpression || isLengthConstant)) { return OrderPreserving.YES_IF_LAST; } } } return OrderPreserving.NO; }
@Test public void substrLtrim() throws Exception { List<Expression> ltrimArgs = Lists.newArrayList(getInvertedLiteral(" blah", PChar.INSTANCE)); Expression ltrim = new LTrimFunction(ltrimArgs); List<Expression> substrArgs = Lists.newArrayList(ltrim, getLiteral(3), getLiteral(2)); evaluateAndAssertResult(new SubstrFunction(substrArgs), "ah"); }