Revision created by MOE tool push_codebase.
[gae.git] / java / src / main / com / google / appengine / api / datastore / NormalizedQuery.java
blobd974188d9a2734ad12a3c2466953c37b3b9eba9d
1 package com.google.appengine.api.datastore;
3 import com.google.apphosting.datastore.DatastoreV3Pb.Query;
4 import com.google.apphosting.datastore.DatastoreV3Pb.Query.Filter;
5 import com.google.apphosting.datastore.DatastoreV3Pb.Query.Filter.Operator;
6 import com.google.apphosting.datastore.DatastoreV3Pb.Query.Order;
7 import com.google.common.collect.Iterables;
8 import com.google.storage.onestore.v3.OnestoreEntity.Property;
10 import java.util.Arrays;
11 import java.util.Collections;
12 import java.util.HashSet;
13 import java.util.Iterator;
14 import java.util.Set;
16 class NormalizedQuery {
17 static final Set<Operator> INEQUALITY_OPERATORS = makeImmutableSet(
18 Operator.GREATER_THAN,
19 Operator.GREATER_THAN_OR_EQUAL,
20 Operator.LESS_THAN,
21 Operator.LESS_THAN_OR_EQUAL);
23 protected final Query query;
25 public NormalizedQuery(Query query) {
26 this.query = query.clone();
27 normalizeQuery();
30 public Query getQuery() {
31 return query;
34 private void normalizeQuery() {
36 Set<Property> equalityFilterProperties = new HashSet<Property>();
37 Set<String> equalityProperties = new HashSet<String>();
38 Set<String> inequalityProperties = new HashSet<String>();
40 for (Iterator<Filter> itr = query.filterIterator(); itr.hasNext();) {
41 Filter f = itr.next();
42 if (f.propertySize() == 1 && f.getOpEnum() == Operator.IN) {
43 f.setOp(Operator.EQUAL);
45 if (f.propertySize() >= 1) {
46 String name = f.getProperty(0).getName();
47 if (f.getOpEnum() == Operator.EQUAL) {
48 if (!equalityFilterProperties.add(f.getProperty(0))) {
49 itr.remove();
50 } else {
51 equalityProperties.add(name);
53 } else if (INEQUALITY_OPERATORS.contains(f.getOpEnum())) {
54 inequalityProperties.add(name);
59 equalityProperties.removeAll(inequalityProperties);
61 for (Iterator<Order> itr = query.orderIterator(); itr.hasNext();) {
62 if (!equalityProperties.add(itr.next().getProperty())) {
63 itr.remove();
67 Set<String> allProperties = equalityProperties;
68 allProperties.addAll(inequalityProperties);
70 for (Iterator<Filter> itr = query.filterIterator(); itr.hasNext();) {
71 Filter f = itr.next();
72 if (f.getOpEnum() == Operator.EXISTS && f.propertySize() >= 1 &&
73 !allProperties.add(f.getProperty(0).getName())) {
74 itr.remove();
78 for (String propName : Iterables.concat(query.propertyNames(), query.groupByPropertyNames())) {
79 if (allProperties.add(propName)) {
80 query.addFilter().setOp(Operator.EXISTS).addProperty()
81 .setName(propName).setMultiple(false).getMutableValue();
85 for (Filter f : query.filters()) {
86 if (f.getOpEnum() == Operator.EQUAL && f.propertySize() >= 1 &&
87 f.getProperty(0).getName().equals(Entity.KEY_RESERVED_PROPERTY)) {
88 query.clearOrder();
89 break;
93 boolean foundKeyOrder = false;
94 for (Iterator<Order> i = query.orderIterator(); i.hasNext();) {
95 String property = i.next().getProperty();
96 if (foundKeyOrder) {
97 i.remove();
98 } else if (property.equals(Entity.KEY_RESERVED_PROPERTY)) {
99 foundKeyOrder = true;
104 static <T> Set<T> makeImmutableSet(T ...of) {
105 return Collections.unmodifiableSet(new HashSet<T>(Arrays.asList(of)));