use of com.google.apphosting.datastore.DatastoreV3Pb.Query.Filter in project appengine-java-standard by GoogleCloudPlatform.
the class BaseEntityComparator method makeAdjustedOrders.
private static List<Order> makeAdjustedOrders(List<Order> orders, List<Filter> filters) {
// Making arbitrary guess about order implied by exists filters.
List<Order> existsOrders = Lists.newArrayList();
for (Filter filter : filters) {
if (filter.getOpEnum() == Filter.Operator.EXISTS) {
existsOrders.add(new Order().setProperty(filter.getProperty(0).getName()).setDirection(Direction.ASCENDING));
}
}
Collections.sort(existsOrders, ORDER_PROPERTY_COMPARATOR);
List<Order> adjusted = new ArrayList<Order>(orders.size() + existsOrders.size() + 1);
adjusted.addAll(orders);
if (adjusted.isEmpty()) {
// Check for a inequality filter to order by
for (Filter filter : filters) {
if (ValidatedQuery.INEQUALITY_OPERATORS.contains(filter.getOpEnum())) {
// Only the first inequality is applied natively
adjusted.add(new Order().setProperty(filter.getProperty(0).getName()).setDirection(Direction.ASCENDING));
break;
}
}
}
adjusted.addAll(existsOrders);
if (adjusted.isEmpty() || !adjusted.get(adjusted.size() - 1).equals(KEY_ASC_ORDER)) {
// make sure we're always sorted by the key as the final sort order.
adjusted.add(KEY_ASC_ORDER);
}
return adjusted;
}
use of com.google.apphosting.datastore.DatastoreV3Pb.Query.Filter in project appengine-java-standard by GoogleCloudPlatform.
the class CompositeIndexManager method compositeIndexForQuery.
/**
* Given a {@link IndexComponentsOnlyQuery}, return the {@link Index} needed to fulfill the query,
* or {@code null} if no index is needed.
*
* <p>This code needs to remain in sync with its counterparts in other languages. If you modify
* this code please make sure you make the same update in the local datastore for other languages.
*
* @param indexOnlyQuery The query.
* @return The index that must be present in order to fulfill the query, or {@code null} if no
* index is needed.
*/
@Nullable
protected Index compositeIndexForQuery(final IndexComponentsOnlyQuery indexOnlyQuery) {
DatastoreV3Pb.Query query = indexOnlyQuery.getQuery();
boolean hasKind = query.hasKind();
boolean isAncestor = query.hasAncestor();
List<Filter> filters = query.filters();
List<Order> orders = query.orders();
if (filters.isEmpty() && orders.isEmpty()) {
// built-in primary key or kind index can handle this.
return null;
}
// Group the filters by operator.
List<String> eqProps = indexOnlyQuery.getPrefix();
List<Property> indexProperties = indexOnlyQuery.isGeo() ? getNeededSearchProps(eqProps, indexOnlyQuery.getGeoProperties()) : getRecommendedIndexProps(indexOnlyQuery);
if (hasKind && !eqProps.isEmpty() && eqProps.size() == filters.size() && !indexOnlyQuery.hasKeyProperty() && orders.isEmpty()) {
// specified, and those queries can _not_ be satisfied by merge-join.
return null;
}
if (hasKind && !isAncestor && indexProperties.size() <= 1 && !indexOnlyQuery.isGeo() && (!indexOnlyQuery.hasKeyProperty() || indexProperties.get(0).getDirectionEnum() == Property.Direction.ASCENDING)) {
// (a.k.a. Search) indexes, we might.)
return null;
}
Index index = new Index();
index.setEntityType(query.getKind());
index.setAncestor(isAncestor);
index.mutablePropertys().addAll(indexProperties);
return index;
}
use of com.google.apphosting.datastore.DatastoreV3Pb.Query.Filter in project appengine-java-standard by GoogleCloudPlatform.
the class IndexComponentsOnlyQuery method categorizeQuery.
private void categorizeQuery() {
Set<String> ineqProps = Sets.newHashSet();
hasKeyProperty = false;
for (Filter filter : query.filters()) {
String propName = filter.getProperty(0).getName();
switch(filter.getOpEnum()) {
case EQUAL:
equalityProps.add(propName);
break;
case EXISTS:
existsProps.add(propName);
break;
case GREATER_THAN:
case GREATER_THAN_OR_EQUAL:
case LESS_THAN:
case LESS_THAN_OR_EQUAL:
ineqProps.add(propName);
break;
case CONTAINED_IN_REGION:
containmentProps.add(propName);
break;
default:
throw new IllegalArgumentException("Unable to categorize query using filter operator " + filter.getOp());
}
if (propName.equals(Entity.KEY_RESERVED_PROPERTY)) {
hasKeyProperty = true;
}
}
// Add the inequality filter properties, if any.
if (query.orderSize() == 0 && !ineqProps.isEmpty()) {
// We do not add an index property for the inequality filter because
// it will be taken care of when we add the sort on that same property
// down below.
orderProps.add(new Property().setName(ineqProps.iterator().next()));
}
groupByProps.addAll(query.groupByPropertyNames());
// If a property is included in the group by, its existance will be satisfied.
existsProps.removeAll(groupByProps);
// Add orders.
for (Order order : query.orders()) {
if (order.getProperty().equals(Entity.KEY_RESERVED_PROPERTY)) {
hasKeyProperty = true;
}
// If a property is in the ordering, it has already been satisfied.
groupByProps.remove(order.getProperty());
orderProps.add(new Property().setName(order.getProperty()).setDirection(order.getDirection()));
}
}
use of com.google.apphosting.datastore.DatastoreV3Pb.Query.Filter in project appengine-java-standard by GoogleCloudPlatform.
the class BaseEntityComparator method makeFilterMatchers.
private static Map<String, FilterMatcher> makeFilterMatchers(List<Order> orders, List<Filter> filters) {
Map<String, FilterMatcher> filterMatchers = new HashMap<String, FilterMatcher>();
for (Filter filter : filters) {
String name = filter.getProperty(0).getName();
FilterMatcher filterMatcher = filterMatchers.get(name);
if (filterMatcher == null) {
filterMatcher = new FilterMatcher();
filterMatchers.put(name, filterMatcher);
}
filterMatcher.addFilter(filter);
}
// order implies existence filter
for (Order order : orders) {
if (!filterMatchers.containsKey(order.getProperty())) {
filterMatchers.put(order.getProperty(), FilterMatcher.MATCH_ALL);
}
if (order.getProperty().equals(KEY_ASC_ORDER.getProperty())) {
// sort orders after a key sort are ignored
break;
}
}
return filterMatchers;
}
use of com.google.apphosting.datastore.DatastoreV3Pb.Query.Filter in project appengine-java-standard by GoogleCloudPlatform.
the class EntityComparatorTests method testMultiTypeExtremeWithFilter.
@Test
public void testMultiTypeExtremeWithFilter() {
FilterMatcher matcher = new FilterMatcher();
Filter filter = new Filter().setOp(Operator.GREATER_THAN);
filter.addProperty().setName("a").getMutableValue().setInt64Value(3);
matcher.addFilter(filter);
filter.setOp(Operator.LESS_THAN).getProperty(0).getValue().setInt64Value(5);
matcher.addFilter(filter);
assertThat(BaseEntityComparator.multiTypeExtreme(nastyCast(5L, 4L, 3L), true, matcher)).isEqualTo(4L);
assertThrows(IllegalArgumentException.class, () -> BaseEntityComparator.multiTypeExtreme(nastyCast(byteArray("5"), byteArray("4"), byteArray("3")), true, matcher));
assertThat(BaseEntityComparator.multiTypeExtreme(nastyCast(4L, true, 4L, false), true, matcher)).isEqualTo(4L);
assertThat(BaseEntityComparator.multiTypeExtreme(nastyCast(5L, 4L, 3L), false, matcher)).isEqualTo(4L);
assertThrows(IllegalArgumentException.class, () -> BaseEntityComparator.multiTypeExtreme(nastyCast(byteArray("5"), byteArray("4"), byteArray("3")), false, matcher));
assertThat(BaseEntityComparator.multiTypeExtreme(nastyCast(4L, true, 4L, false), false, matcher)).isEqualTo(4L);
}
Aggregations