in api/src/main/java/com/google/appengine/api/datastore/NormalizedQuery.java [49:137]
private void normalizeQuery() {
// TODO: consider sharing this code with MegastoreQueryPlanner
// NOTE: Keep in sync with MegastoreQueryPlanner#normalize()
Set<Property> equalityFilterProperties = new HashSet<Property>();
Set<String> equalityProperties = new HashSet<String>();
Set<String> inequalityProperties = new HashSet<String>();
for (Iterator<Filter> itr = query.mutableFilters().iterator(); itr.hasNext(); ) {
Filter f = itr.next();
/* Normalize IN filters to EQUAL. */
if (f.propertySize() == 1 && f.getOpEnum() == Operator.IN) {
f.setOp(Operator.EQUAL);
}
if (f.propertySize() >= 1) {
String name = f.getProperty(0).getName();
if (f.getOpEnum() == Operator.EQUAL) {
if (!equalityFilterProperties.add(f.getProperty(0))) {
// The filter is an exact duplicate, remove it.
itr.remove();
} else {
equalityProperties.add(name);
}
} else if (INEQUALITY_OPERATORS.contains(f.getOpEnum())) {
inequalityProperties.add(name);
}
}
}
equalityProperties.removeAll(inequalityProperties);
// Strip repeated orders and orders coinciding with EQUAL filters.
for (Iterator<Order> itr = query.mutableOrders().iterator(); itr.hasNext(); ) {
if (!equalityProperties.add(itr.next().getProperty())) {
itr.remove();
}
}
Set<String> allProperties = equalityProperties;
allProperties.addAll(inequalityProperties);
// Removing redundant exists filters.
for (Iterator<Filter> itr = query.mutableFilters().iterator(); itr.hasNext(); ) {
Filter f = itr.next();
if (f.getOpEnum() == Operator.EXISTS
&& f.propertySize() >= 1
&& !allProperties.add(f.getProperty(0).getName())) {
itr.remove();
}
}
// Adding exist filters for any requested properties or group by properties that need them.
for (String propName : Iterables.concat(query.propertyNames(), query.groupByPropertyNames())) {
if (allProperties.add(propName)) {
query
.addFilter()
.setOp(Operator.EXISTS)
.addProperty()
.setName(propName)
.setMultiple(false)
.getMutableValue();
}
}
// NOTE: Keep in sync with MegastoreQueryPlanner#normalizeForKeyComponents()
/* Strip all orders if filtering on __key__ with equals. */
for (Filter f : query.filters()) {
if (f.getOpEnum() == Operator.EQUAL
&& f.propertySize() >= 1
&& f.getProperty(0).getName().equals(Entity.KEY_RESERVED_PROPERTY)) {
query.clearOrder();
break;
}
}
/* Strip all orders that follow a ordering on __key__ as keys are unique
* thus additional ordering has no effect. */
boolean foundKeyOrder = false;
for (Iterator<Order> i = query.mutableOrders().iterator(); i.hasNext(); ) {
String property = i.next().getProperty();
if (foundKeyOrder) {
i.remove();
} else if (property.equals(Entity.KEY_RESERVED_PROPERTY)) {
foundKeyOrder = true;
}
}
}