in hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/GraphIndexTransaction.java [1289:1380]
protected static List<Condition> constructShardConditions(
ConditionQuery query,
List<Id> fields,
HugeKeys key) {
List<Condition> conditions = new ArrayList<>(2);
boolean hasRange = false;
int processedCondCount = 0;
List<Object> prefixes = new ArrayList<>();
for (Id field : fields) {
List<Condition> fieldConds = query.userpropConditions(field);
processedCondCount += fieldConds.size();
if (fieldConds.isEmpty()) {
break;
}
RangeConditions range = new RangeConditions(fieldConds);
if (!range.hasRange()) {
E.checkArgument(range.keyEq() != null,
"Invalid query: %s", query);
prefixes.add(range.keyEq());
continue;
}
if (range.keyMin() != null) {
RelationType type = range.keyMinEq() ?
RelationType.GTE : RelationType.GT;
conditions.add(shardFieldValuesCondition(key, prefixes,
range.keyMin(),
type));
} else {
assert range.keyMax() != null;
Object num = range.keyMax();
num = NumericUtil.minValueOf(NumericUtil.isNumber(num) ?
num.getClass() : Long.class);
conditions.add(shardFieldValuesCondition(key, prefixes, num,
RelationType.GTE));
}
if (range.keyMax() != null) {
RelationType type = range.keyMaxEq() ?
RelationType.LTE : RelationType.LT;
conditions.add(shardFieldValuesCondition(key, prefixes,
range.keyMax(), type));
} else {
Object num = range.keyMin();
num = NumericUtil.maxValueOf(NumericUtil.isNumber(num) ?
num.getClass() : Long.class);
conditions.add(shardFieldValuesCondition(key, prefixes, num,
RelationType.LTE));
}
hasRange = true;
break;
}
/*
* Can't have conditions after range condition for shard index,
* but SORT_KEYS can have redundant conditions because upper
* layer can do filter.
*/
if (key == HugeKeys.FIELD_VALUES &&
processedCondCount < query.userpropKeys().size()) {
throw new HugeException("Invalid shard index query: %s", query);
}
// 1. First range condition processed, finish shard query conditions
if (hasRange) {
return conditions;
}
// 2. Shard query without range
String joinedValues;
// 2.1 All fields have equal-conditions
if (prefixes.size() == fields.size()) {
// Prefix numeric values should be converted to sortable string
joinedValues = ConditionQuery.concatValues(prefixes);
conditions.add(Condition.eq(key, joinedValues));
return conditions;
}
// 2.2 Prefix fields have equal-conditions
/*
* Append EMPTY to 'values' to ensure FIELD_VALUES suffix
* with IdGenerator.NAME_SPLITOR
*/
prefixes.add(ConditionQuery.INDEX_VALUE_EMPTY);
joinedValues = ConditionQuery.concatValues(prefixes);
Condition min = Condition.gte(key, joinedValues);
conditions.add(min);
// Increase 1 on prefix to get the next prefix
Condition max = Condition.lt(key, increaseString(joinedValues));
conditions.add(max);
return conditions;
}