use of org.apache.phoenix.parse.LikeParseNode in project phoenix by apache.
the class ExpressionCompiler method visitLeave.
@Override
public Expression visitLeave(LikeParseNode node, List<Expression> children) throws SQLException {
ParseNode lhsNode = node.getChildren().get(0);
ParseNode rhsNode = node.getChildren().get(1);
Expression lhs = children.get(0);
Expression rhs = children.get(1);
if (rhs.getDataType() != null && lhs.getDataType() != null && !lhs.getDataType().isCoercibleTo(rhs.getDataType()) && !rhs.getDataType().isCoercibleTo(lhs.getDataType())) {
throw TypeMismatchException.newException(lhs.getDataType(), rhs.getDataType(), node.toString());
}
if (lhsNode instanceof BindParseNode) {
context.getBindManager().addParamMetaData((BindParseNode) lhsNode, rhs);
}
if (rhsNode instanceof BindParseNode) {
context.getBindManager().addParamMetaData((BindParseNode) rhsNode, lhs);
}
if (rhs instanceof LiteralExpression) {
String pattern = (String) ((LiteralExpression) rhs).getValue();
if (pattern == null || pattern.length() == 0) {
return LiteralExpression.newConstant(null, rhs.getDeterminism());
}
// TODO: for pattern of '%' optimize to strlength(lhs) > 0
// We can't use lhs IS NOT NULL b/c if lhs is NULL we need
// to return NULL.
int index = LikeExpression.indexOfWildcard(pattern);
// Can't possibly be as long as the constant, then FALSE
Integer lhsMaxLength = lhs.getMaxLength();
if (lhsMaxLength != null && lhsMaxLength < index) {
return LiteralExpression.newConstant(false, rhs.getDeterminism());
}
if (index == -1) {
String rhsLiteral = LikeExpression.unescapeLike(pattern);
if (lhsMaxLength != null && lhsMaxLength != rhsLiteral.length()) {
return LiteralExpression.newConstant(false, rhs.getDeterminism());
}
if (node.getLikeType() == LikeType.CASE_SENSITIVE) {
CompareOp op = node.isNegate() ? CompareOp.NOT_EQUAL : CompareOp.EQUAL;
if (pattern.equals(rhsLiteral)) {
return new ComparisonExpression(children, op);
} else {
rhs = LiteralExpression.newConstant(rhsLiteral, PChar.INSTANCE, rhs.getDeterminism());
return new ComparisonExpression(Arrays.asList(lhs, rhs), op);
}
}
} else {
byte[] wildcardString = new byte[pattern.length()];
byte[] wildcard = { StringUtil.MULTI_CHAR_LIKE };
StringUtil.fill(wildcardString, 0, pattern.length(), wildcard, 0, 1, false);
if (pattern.equals(new String(wildcardString))) {
List<Expression> compareChildren = Arrays.asList(lhs, NOT_NULL_STRING);
return new ComparisonExpression(compareChildren, node.isNegate() ? CompareOp.LESS : CompareOp.GREATER_OR_EQUAL);
}
}
}
QueryServices services = context.getConnection().getQueryServices();
boolean useByteBasedRegex = services.getProps().getBoolean(QueryServices.USE_BYTE_BASED_REGEX_ATTRIB, QueryServicesOptions.DEFAULT_USE_BYTE_BASED_REGEX);
Expression expression;
if (useByteBasedRegex) {
expression = ByteBasedLikeExpression.create(children, node.getLikeType());
} else {
expression = StringBasedLikeExpression.create(children, node.getLikeType());
}
if (ExpressionUtil.isConstant(expression)) {
ImmutableBytesWritable ptr = context.getTempPtr();
if (!expression.evaluate(null, ptr)) {
return LiteralExpression.newConstant(null, expression.getDeterminism());
} else {
return LiteralExpression.newConstant(Boolean.TRUE.equals(PBoolean.INSTANCE.toObject(ptr)) ^ node.isNegate(), expression.getDeterminism());
}
}
if (node.isNegate()) {
expression = new NotExpression(expression);
}
return wrapGroupByExpression(expression);
}
Aggregations