diff options
3 files changed, 77 insertions, 23 deletions
diff --git a/src/main/java/com/amazon/carbonado/info/OrderedProperty.java b/src/main/java/com/amazon/carbonado/info/OrderedProperty.java index 7de07c0..fe53c60 100644 --- a/src/main/java/com/amazon/carbonado/info/OrderedProperty.java +++ b/src/main/java/com/amazon/carbonado/info/OrderedProperty.java @@ -56,8 +56,8 @@ public class OrderedProperty<S extends Storable> implements Appender {      /**
       * Parses an ordering property, which may start with a '+' or '-' to
 -     * indicate direction. If ordering prefix not specified, default direction
 -     * is ascending.
 +     * indicate direction. Prefix of '~' indicates unspecified direction. If
 +     * ordering prefix not specified, default direction is ascending.
       *
       * @param info Info for Storable type containing property
       * @param str string to parse
 @@ -73,7 +73,7 @@ public class OrderedProperty<S extends Storable> implements Appender {      /**
       * Parses an ordering property, which may start with a '+' or '-' to
 -     * indicate direction.
 +     * indicate direction. Prefix of '~' indicates unspecified direction.
       *
       * @param info Info for Storable type containing property
       * @param str string to parse
 @@ -98,6 +98,9 @@ public class OrderedProperty<S extends Storable> implements Appender {              } else if (str.charAt(0) == '-') {
                  direction = Direction.DESCENDING;
                  str = str.substring(1);
 +            } else if (str.charAt(0) == '~') {
 +                direction = Direction.UNSPECIFIED;
 +                str = str.substring(1);
              }
          }
          if (direction == null) {
 @@ -158,9 +161,6 @@ public class OrderedProperty<S extends Storable> implements Appender {       */
      @Override
      public String toString() {
 -        if (mDirection == Direction.UNSPECIFIED) {
 -            return mProperty.toString();
 -        }
          StringBuilder buf = new StringBuilder();
          buf.append(mDirection.toCharacter());
          try {
 @@ -172,11 +172,7 @@ public class OrderedProperty<S extends Storable> implements Appender {      }
      public void appendTo(Appendable app) throws IOException {
 -        if (mDirection == Direction.UNSPECIFIED) {
 -            mProperty.appendTo(app);
 -        } else {
 -            app.append(mDirection.toCharacter());
 -            mProperty.appendTo(app);
 -        }
 +        app.append(mDirection.toCharacter());
 +        mProperty.appendTo(app);
      }
  }
 diff --git a/src/main/java/com/amazon/carbonado/qe/OrderingScore.java b/src/main/java/com/amazon/carbonado/qe/OrderingScore.java index ed52cfc..ce85cb6 100644 --- a/src/main/java/com/amazon/carbonado/qe/OrderingScore.java +++ b/src/main/java/com/amazon/carbonado/qe/OrderingScore.java @@ -177,18 +177,32 @@ public class OrderingScore<S extends Storable> {                  ChainedProperty<S> indexChained = indexProp.getChainedProperty();
                  if (chained.equals(indexChained)) {
 -                    if (property.getDirection() != UNSPECIFIED) {
 -                        Direction indexDir = indexProp.getDirection();
 -                        if (indexDir == UNSPECIFIED) {
 -                            indexDir = ASCENDING;
 -                        }
 +                    Direction indexDir = indexProp.getDirection();
 +                    if (indexDir == UNSPECIFIED) {
 +                        // Assume index natural order is ascending.
 +                        indexDir = ASCENDING;
 +                    }
 +
 +                    if (shouldReverseOrder != null && shouldReverseOrder) {
 +                        indexDir = indexDir.reverse();
 +                    }
 -                        if (shouldReverseOrder == null) {
 -                            shouldReverseOrder = indexDir != property.getDirection();
 -                        } else if ((indexDir != property.getDirection()) ^ shouldReverseOrder) {
 -                            // Direction mismatch, so cannot be handled.
 -                            break indexPosMatch;
 +                    if (property.getDirection() == UNSPECIFIED) {
 +                        // Set handled property direction to match index.
 +                        property = property.direction(indexDir);
 +                    } else if (shouldReverseOrder == null) {
 +                        shouldReverseOrder = indexDir != property.getDirection();
 +                        // Any properies already in the list had been
 +                        // originally unspecified. They might need to be
 +                        // reversed now.
 +                        if (shouldReverseOrder) {
 +                            for (int hpi = 0; hpi < handledProperties.size(); hpi++) {
 +                                handledProperties.set(hpi, handledProperties.get(hpi).reverse());
 +                            }
                          }
 +                    } else if (indexDir != property.getDirection()) {
 +                        // Direction mismatch, so cannot be handled.
 +                        break indexPosMatch;
                      }
                      handledProperties.add(property);
 @@ -281,7 +295,9 @@ public class OrderingScore<S extends Storable> {      /**
       * Returns the ordering properties that the evaluated index supports. The
 -     * list of orderings is reduced to eliminate redundancies.
 +     * list of orderings is reduced to eliminate redundancies. If any handled
 +     * ordering properties originally had an unspecified direction, the correct
 +     * direction is specified in this list.
       *
       * @return handled orderings, never null
       */
 diff --git a/src/test/java/com/amazon/carbonado/qe/TestOrderingScore.java b/src/test/java/com/amazon/carbonado/qe/TestOrderingScore.java index 91b5676..ecacf9a 100644 --- a/src/test/java/com/amazon/carbonado/qe/TestOrderingScore.java +++ b/src/test/java/com/amazon/carbonado/qe/TestOrderingScore.java @@ -543,4 +543,46 @@ public class TestOrderingScore extends TestCase {          assertEquals("+doubleProp", score.getHandledOrderings().get(1).toString());
          assertEquals("+longProp", score.getRemainderOrderings().get(0).toString());
      }
 +
 +    public void testUnspecifiedDirection() throws Exception {
 +        // Tests that an originally unspecified ordering direction is determined.
 +        final StorableIndex<StorableTestBasic> ix;
 +        List<OrderedProperty<StorableTestBasic>> ops;
 +        OrderingScore score;
 +        Filter<StorableTestBasic> filter;
 +
 +        ix = makeIndex(StorableTestBasic.class, "id", "intProp", "doubleProp");
 +        ops = makeOrderings(StorableTestBasic.class, "~intProp", "-doubleProp");
 +        filter = Filter.filterFor(StorableTestBasic.class, "id = ?");
 +
 +        score = OrderingScore.evaluate(ix, filter, ops);
 +        assertEquals(2, score.getHandledCount());
 +        assertEquals(0, score.getRemainderCount());
 +        assertEquals(true, score.shouldReverseOrder());
 +
 +        assertEquals("-intProp", score.getHandledOrderings().get(0).toString());
 +        assertEquals("-doubleProp", score.getHandledOrderings().get(1).toString());
 +
 +        ops = makeOrderings(StorableTestBasic.class, "~id", "intProp", "~doubleProp");
 +
 +        score = OrderingScore.evaluate(ix, null, ops);
 +        assertEquals(3, score.getHandledCount());
 +        assertEquals(0, score.getRemainderCount());
 +        assertEquals(false, score.shouldReverseOrder());
 +
 +        assertEquals("+id", score.getHandledOrderings().get(0).toString());
 +        assertEquals("+intProp", score.getHandledOrderings().get(1).toString());
 +        assertEquals("+doubleProp", score.getHandledOrderings().get(2).toString());
 +
 +        ops = makeOrderings(StorableTestBasic.class, "~id", "-intProp", "~doubleProp");
 +
 +        score = OrderingScore.evaluate(ix, null, ops);
 +        assertEquals(3, score.getHandledCount());
 +        assertEquals(0, score.getRemainderCount());
 +        assertEquals(true, score.shouldReverseOrder());
 +
 +        assertEquals("-id", score.getHandledOrderings().get(0).toString());
 +        assertEquals("-intProp", score.getHandledOrderings().get(1).toString());
 +        assertEquals("-doubleProp", score.getHandledOrderings().get(2).toString());
 +    }
  }
  | 
