use of com.pingcap.tikv.key.TypedKey in project tispark by pingcap.
the class IndexRangeSetBuilder method visit.
@Override
protected RangeSet<TypedKey> visit(StringRegExpression node, Void context) {
ColumnRef columnRef = node.getColumnRef();
// In order to match a prefix index, we have to cut the literal by prefix length.
// e.g., for table t:
// CREATE TABLE `t` {
// `c1` VARCHAR(10) DEFAULT NULL,
// KEY `prefix_index` (`c`(2))
// }
// when the predicate is `c1` LIKE 'abc%', the index range should be ['ab', 'ab'].
// when the predicate is `c1` LIKE 'a%', the index range should be ['a', 'b').
// for varchar, `c1`(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(columnRef, DataType.UNSPECIFIED_LEN);
TypedKey literal = node.getTypedLiteral(prefixLen);
RangeSet<TypedKey> ranges = TreeRangeSet.create();
switch(node.getRegType()) {
case STARTS_WITH:
ranges.add(Range.atLeast(literal).intersection(Range.lessThan(literal.next())));
break;
default:
throwOnError(node);
}
return ranges;
}
use of com.pingcap.tikv.key.TypedKey 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.key.TypedKey in project tispark by pingcap.
the class PredicateUtils method expressionToPoints.
/**
* Turn access conditions into list of points Each condition is bound to single key We pick up
* single condition for each index key and disregard if multiple EQ conditions in DNF
*
* @param pointPredicates expressions that convertible to access points
* @return access points for each index
*/
private static List<Key> expressionToPoints(List<Expression> pointPredicates, TiTableInfo table, TiIndexInfo index) {
requireNonNull(pointPredicates, "pointPredicates cannot be null");
List<Key> resultKeys = new ArrayList<>();
IndexRangeSetBuilder indexRangeBuilder = new IndexRangeSetBuilder(table, index);
for (int i = 0; i < pointPredicates.size(); i++) {
Expression predicate = pointPredicates.get(i);
try {
// each expr will be expand to one or more points
Set<Range<TypedKey>> ranges = indexRangeBuilder.buildRange(predicate).asRanges();
List<Key> points = rangesToPoint(ranges);
resultKeys = joinKeys(resultKeys, points);
} catch (Exception e) {
throw new TiExpressionException(String.format("Error converting access points %s", predicate), e);
}
}
return resultKeys;
}
use of com.pingcap.tikv.key.TypedKey in project tispark by pingcap.
the class TiKVScanAnalyzer method buildTableScanKeyRangePerId.
private Pair<Key, Key> buildTableScanKeyRangePerId(long id, IndexRange ir) {
Key startKey;
Key endKey;
if (ir.hasAccessKey()) {
checkArgument(!ir.hasRange(), "Table scan must have one and only one access condition / point");
Key key = ir.getAccessKey();
checkArgument(key instanceof TypedKey, "Table scan key range must be typed key");
TypedKey typedKey = (TypedKey) key;
startKey = RowKey.toRowKey(id, typedKey);
endKey = startKey.next();
} else if (ir.hasRange()) {
checkArgument(!ir.hasAccessKey(), "Table scan must have one and only one access condition / point");
Range<TypedKey> r = ir.getRange();
if (!r.hasLowerBound()) {
// -INF
startKey = RowKey.createMin(id);
} else {
// Comparison with null should be filtered since it yields unknown always
startKey = RowKey.toRowKey(id, r.lowerEndpoint());
if (r.lowerBoundType().equals(BoundType.OPEN)) {
startKey = startKey.next();
}
}
if (!r.hasUpperBound()) {
// INF
endKey = RowKey.createBeyondMax(id);
} else {
endKey = RowKey.toRowKey(id, r.upperEndpoint());
if (r.upperBoundType().equals(BoundType.CLOSED)) {
endKey = endKey.next();
}
}
} else {
throw new TiClientInternalException("Empty access conditions");
}
return new Pair<>(startKey, endKey);
}
use of com.pingcap.tikv.key.TypedKey in project tispark by pingcap.
the class PredicateUtilsTest method expressionToIndexRangesTest.
@Test
public void expressionToIndexRangesTest() {
TiTableInfo table = createTable();
ColumnRef col1 = ColumnRef.create("c1", table);
ColumnRef col4 = ColumnRef.create("c4", table);
ColumnRef col5 = ColumnRef.create("c5", table);
Constant c1 = Constant.create(1, IntegerType.INT);
Constant c2 = Constant.create(2, IntegerType.INT);
Constant c3 = Constant.create(3, IntegerType.INT);
Constant c4 = Constant.create(4, IntegerType.INT);
TypedKey key1 = TypedKey.toTypedKey(1, IntegerType.INT);
TypedKey key2 = TypedKey.toTypedKey(2, IntegerType.INT);
TypedKey key3 = TypedKey.toTypedKey(3, IntegerType.INT);
TypedKey key4 = TypedKey.toTypedKey(4, IntegerType.INT);
Expression predicate1 = or(or(equal(c1, col1), equal(col1, c2)), equal(col1, c1));
Expression predicate2 = or(equal(c3, col4), equal(c4, col4));
Expression rangePredicate = notEqual(col5, c1);
List<IndexRange> indexRanges = PredicateUtils.expressionToIndexRanges(ImmutableList.of(predicate1, predicate2), Optional.of(rangePredicate), table, null);
assertEquals(8, indexRanges.size());
Key indexKey1 = CompoundKey.concat(key1, key3);
Key indexKey2 = CompoundKey.concat(key1, key4);
Key indexKey3 = CompoundKey.concat(key2, key3);
Key indexKey4 = CompoundKey.concat(key2, key4);
Range<TypedKey> baselineRange1 = Range.lessThan(key1);
Range<TypedKey> baselineRange2 = Range.greaterThan(key1);
Set<Key> baselineKeys = ImmutableSet.of(indexKey1, indexKey2, indexKey3, indexKey4);
Set<Range<TypedKey>> baselineRanges = ImmutableSet.of(baselineRange1, baselineRange2);
for (IndexRange range : indexRanges) {
assertTrue(baselineKeys.contains(range.getAccessKey()));
assertTrue(baselineRanges.contains(range.getRange()));
}
}
Aggregations