use of com.pingcap.tikv.expression.ComparisonBinaryExpression.NormalizedPredicate in project tispark by pingcap.
the class ProtoConverter method visit.
@Override
protected Expr visit(ComparisonBinaryExpression node, Object context) {
NormalizedPredicate predicate = node.normalize();
if (predicate.getValue().isOverflowed()) {
throw new UnsupportedOperationException("overflowed ComparisonBinaryExpression cannot be pushed down");
}
Expression child = node.getLeft();
String typeSignature = getTypeSignature(child);
ScalarFuncSig protoSig;
switch(node.getComparisonType()) {
case EQUAL:
protoSig = ScalarFuncSig.valueOf("EQ" + typeSignature);
break;
case GREATER_EQUAL:
protoSig = ScalarFuncSig.valueOf("GE" + typeSignature);
break;
case GREATER_THAN:
protoSig = ScalarFuncSig.valueOf("GT" + typeSignature);
break;
case LESS_EQUAL:
protoSig = ScalarFuncSig.valueOf("LE" + typeSignature);
break;
case LESS_THAN:
protoSig = ScalarFuncSig.valueOf("LT" + typeSignature);
break;
case NOT_EQUAL:
protoSig = ScalarFuncSig.valueOf("NE" + typeSignature);
break;
default:
throw new TiExpressionException(String.format("Unknown comparison type %s", node.getComparisonType()));
}
Expr.Builder builder = scalarToPartialProto(node, context);
builder.setSig(protoSig);
builder.setFieldType(toPBFieldType(getType(node)));
return builder.build();
}
use of com.pingcap.tikv.expression.ComparisonBinaryExpression.NormalizedPredicate in project tispark by pingcap.
the class RangeColumnPartitionPruner method visit.
@Override
protected Set<Integer> visit(ComparisonBinaryExpression node, LogicalBinaryExpression parent) {
NormalizedPredicate predicate = node.normalize();
if (predicate == null) {
throw new UnsupportedOperationException(String.format("ComparisonBinaryExpression %s cannot be normalized", node.toString()));
}
String colRefName = predicate.getColumnRef().getName();
List<Expression> partExprs = partExprsPerColumnRef.get(colRefName);
Set<Integer> partDefs = new HashSet<>();
if (partExprs == null) {
switch(parent.getCompType()) {
case OR:
return partDefs;
case AND:
for (int i = 0; i < partsSize; i++) {
partDefs.add(i);
}
return partDefs;
}
}
Objects.requireNonNull(partExprs, "partition expression cannot be null");
for (int i = 0; i < partsSize; i++) {
PrunedPartitionBuilder rangeBuilder = new PrunedPartitionBuilder(ImmutableSet.of(predicate.getColumnRef()));
RangeSet<TypedKey> partExprRange = rangeBuilder.buildRange(partExprs.get(i));
RangeSet<TypedKey> filterRange = rangeBuilder.buildRange(node);
RangeSet<TypedKey> copy = TreeRangeSet.create(partExprRange);
copy.removeAll(filterRange.complement());
// part expr and filter is connected
if (!copy.isEmpty()) {
partDefs.add(i);
}
}
return partDefs;
}
use of com.pingcap.tikv.expression.ComparisonBinaryExpression.NormalizedPredicate in project tispark by pingcap.
the class RangeSetBuilder method visitComparisonBinaryExpr.
/**
* visits {@code ComparisonBinaryExpression} expression and constructs a range set.
*
* @param node represents a {@code ComparisonBinaryExpression}.
* @param context represents a context during visiting process. It is not being used in this
* method.
* @param literal represents a comparable value.
* @param loose If prefix length is specified, then filter is loose, so is the range.
* @return a range set.
*/
RangeSet<C> visitComparisonBinaryExpr(ComparisonBinaryExpression node, Void context, C literal, boolean loose) {
NormalizedPredicate predicate = node.normalize();
RangeSet<C> ranges = TreeRangeSet.create();
if (loose) {
switch(predicate.getType()) {
case GREATER_THAN:
case GREATER_EQUAL:
ranges.add(Range.atLeast(literal));
break;
case LESS_THAN:
case LESS_EQUAL:
ranges.add(Range.atMost(literal));
break;
case EQUAL:
ranges.add(Range.singleton(literal));
break;
case NOT_EQUAL:
// Should return full range because prefix index predicate for NOT_EQUAL
// will be split into an NOT_EQUAL filter and a full range scan
ranges.add(Range.all());
break;
default:
throwOnError(node);
}
} else {
switch(predicate.getType()) {
case GREATER_THAN:
ranges.add(Range.greaterThan(literal));
break;
case GREATER_EQUAL:
ranges.add(Range.atLeast(literal));
break;
case LESS_THAN:
ranges.add(Range.lessThan(literal));
break;
case LESS_EQUAL:
ranges.add(Range.atMost(literal));
break;
case EQUAL:
ranges.add(Range.singleton(literal));
break;
case NOT_EQUAL:
ranges.add(Range.lessThan(literal));
ranges.add(Range.greaterThan(literal));
break;
default:
throwOnError(node);
}
}
return ranges;
}
use of com.pingcap.tikv.expression.ComparisonBinaryExpression.NormalizedPredicate in project tispark by pingcap.
the class ComparisonBinaryExpressionTest method verifyNormalize.
private void verifyNormalize(ComparisonBinaryExpression cond, String colName, Object value, DataType dataType, Operator operator) {
NormalizedPredicate normCond = cond.normalize();
assertEquals(colName, normCond.getColumnRef().getName());
assertEquals(value, normCond.getValue().getValue());
assertEquals(TypedKey.toTypedKey(value, dataType), normCond.getTypedLiteral());
assertEquals(operator, normCond.getType());
}
use of com.pingcap.tikv.expression.ComparisonBinaryExpression.NormalizedPredicate in project tispark by pingcap.
the class IndexRangeSetBuilder method visit.
@Override
protected RangeSet<TypedKey> visit(ComparisonBinaryExpression node, Void context) {
NormalizedPredicate predicate = node.normalize();
if (predicate == null) {
throwOnError(node);
}
// In order to match a prefix index, we have to cut the literal by prefix length.
// e.g., for table t:
// CREATE TABLE `t` {
// `b` VARCHAR(10) DEFAULT NULL,
// KEY `prefix_index` (`b`(2))
// }
//
// b(2) > "bbc" -> ["bb", +∞)
// b(2) >= "bbc" -> ["bb", +∞)
// b(2) < "bbc" -> (-∞, "bb"]
// b(2) <= "bbc" -> (-∞, "bb"]
// b(2) = "bbc" -> ["bb", "bb"]
// b(2) > "b" -> ["b", +∞)
// b(2) >= "b" -> ["b", +∞)
// b(2) < "b" -> (-∞, "b"]
// b(2) <= "b" -> (-∞, "b"]
//
// For varchar, `b`(2) will take first two characters(bytes) as prefix index.
// TODO: Note that TiDB only supports UTF-8, we need to check if prefix index behave differently
// under other encoding methods
int prefixLen = lengths.getOrDefault(predicate.getColumnRef(), DataType.UNSPECIFIED_LEN);
TypedKey literal = predicate.getTypedLiteral(prefixLen);
boolean loose = !DataType.isLengthUnSpecified(prefixLen);
// With prefix length specified, the filter is loosen and so should the ranges
return visitComparisonBinaryExpr(node, context, literal, loose);
}
Aggregations