You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@druid.apache.org by GitBox <gi...@apache.org> on 2019/01/09 01:17:05 UTC

[GitHub] clintropolis closed pull request #6745: add version comparator for StringComparator

clintropolis closed pull request #6745: add version comparator for StringComparator
URL: https://github.com/apache/incubator-druid/pull/6745
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/docs/content/querying/filters.md b/docs/content/querying/filters.md
index 23d733eda7d..e1269811ee0 100644
--- a/docs/content/querying/filters.md
+++ b/docs/content/querying/filters.md
@@ -276,7 +276,7 @@ greater than, less than, greater than or equal to, less than or equal to, and "b
 |upper|String|The upper bound for the filter|no|
 |lowerStrict|Boolean|Perform strict comparison on the lower bound (">" instead of ">=")|no, default: false|
 |upperStrict|Boolean|Perform strict comparison on the upper bound ("<" instead of "<=")|no, default: false|
-|ordering|String|Specifies the sorting order to use when comparing values against the bound. Can be one of the following values: "lexicographic", "alphanumeric", "numeric", "strlen". See [Sorting Orders](./sorting-orders.html) for more details.|no, default: "lexicographic"|
+|ordering|String|Specifies the sorting order to use when comparing values against the bound. Can be one of the following values: "lexicographic", "alphanumeric", "numeric", "strlen", "version". See [Sorting Orders](./sorting-orders.html) for more details.|no, default: "lexicographic"|
 |extractionFn|[Extraction function](#filtering-with-extraction-functions)| Extraction function to apply to the dimension|no|
   
 Bound filters support the use of extraction functions, see [Filtering with Extraction Functions](#filtering-with-extraction-functions) for details.
diff --git a/docs/content/querying/sorting-orders.md b/docs/content/querying/sorting-orders.md
index 2604b524d62..5c83ac467dc 100644
--- a/docs/content/querying/sorting-orders.md
+++ b/docs/content/querying/sorting-orders.md
@@ -47,3 +47,8 @@ When comparing two unparseable values (e.g., "hello" and "world"), this ordering
 
 ## Strlen
 Sorts values by the their string lengths. When there is a tie, this comparator falls back to using the String compareTo method.
+
+## Version
+Sorts values as versions, e.g.: "10.0 sorts after 9.0", "1.0.0-SNAPSHOT sorts after 1.0.0".
+
+See https://maven.apache.org/ref/3.6.0/maven-artifact/apidocs/org/apache/maven/artifact/versioning/ComparableVersion.html for more details on how this ordering sorts values.
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index ca2321486f5..23f6981ba03 100644
--- a/pom.xml
+++ b/pom.xml
@@ -748,6 +748,11 @@
                 <artifactId>caffeine</artifactId>
                 <version>${caffeine.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.maven</groupId>
+                <artifactId>maven-artifact</artifactId>
+                <version>3.6.0</version>
+            </dependency>
 
             <dependency>
                 <groupId>org.apache.calcite</groupId>
diff --git a/processing/pom.xml b/processing/pom.xml
index 542c3f22f60..714a1f2a025 100644
--- a/processing/pom.xml
+++ b/processing/pom.xml
@@ -116,6 +116,11 @@
             <artifactId>checker</artifactId>
             <version>${checkerframework.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-artifact</artifactId>
+        </dependency>
+
 
         <!-- Tests -->
         <dependency>
diff --git a/processing/src/main/java/org/apache/druid/jackson/StringComparatorModule.java b/processing/src/main/java/org/apache/druid/jackson/StringComparatorModule.java
index a072ba19199..4b7ea2953db 100644
--- a/processing/src/main/java/org/apache/druid/jackson/StringComparatorModule.java
+++ b/processing/src/main/java/org/apache/druid/jackson/StringComparatorModule.java
@@ -36,7 +36,8 @@ public StringComparatorModule()
         new NamedType(StringComparators.LexicographicComparator.class, StringComparators.LEXICOGRAPHIC_NAME),
         new NamedType(StringComparators.AlphanumericComparator.class, StringComparators.ALPHANUMERIC_NAME),
         new NamedType(StringComparators.StrlenComparator.class, StringComparators.STRLEN_NAME),
-        new NamedType(StringComparators.NumericComparator.class, StringComparators.NUMERIC_NAME)
+        new NamedType(StringComparators.NumericComparator.class, StringComparators.NUMERIC_NAME),
+        new NamedType(StringComparators.VersionComparator.class, StringComparators.VERSION_NAME)
     );
   }
 
diff --git a/processing/src/main/java/org/apache/druid/query/ordering/StringComparator.java b/processing/src/main/java/org/apache/druid/query/ordering/StringComparator.java
index 33016c4d2af..8e66baf7df3 100644
--- a/processing/src/main/java/org/apache/druid/query/ordering/StringComparator.java
+++ b/processing/src/main/java/org/apache/druid/query/ordering/StringComparator.java
@@ -39,6 +39,8 @@ public static StringComparator fromString(String type)
         return StringComparators.STRLEN;
       case StringComparators.NUMERIC_NAME:
         return StringComparators.NUMERIC;
+      case StringComparators.VERSION_NAME:
+        return StringComparators.VERSION;
       default:
         throw new IAE("Unknown string comparator[%s]", type);
     }
diff --git a/processing/src/main/java/org/apache/druid/query/ordering/StringComparators.java b/processing/src/main/java/org/apache/druid/query/ordering/StringComparators.java
index dae5cdac2bd..879e5a449f9 100644
--- a/processing/src/main/java/org/apache/druid/query/ordering/StringComparators.java
+++ b/processing/src/main/java/org/apache/druid/query/ordering/StringComparators.java
@@ -24,6 +24,7 @@
 import com.google.common.primitives.UnsignedBytes;
 import org.apache.druid.common.guava.GuavaUtils;
 import org.apache.druid.java.util.common.StringUtils;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
 
 import java.math.BigDecimal;
 import java.util.Comparator;
@@ -34,16 +35,19 @@
   public static final String ALPHANUMERIC_NAME = "alphanumeric";
   public static final String NUMERIC_NAME = "numeric";
   public static final String STRLEN_NAME = "strlen";
+  public static final String VERSION_NAME = "version";
 
   public static final StringComparator LEXICOGRAPHIC = new LexicographicComparator();
   public static final StringComparator ALPHANUMERIC = new AlphanumericComparator();
   public static final StringComparator NUMERIC = new NumericComparator();
   public static final StringComparator STRLEN = new StrlenComparator();
+  public static final StringComparator VERSION = new VersionComparator();
 
   public static final int LEXICOGRAPHIC_CACHE_ID = 0x01;
   public static final int ALPHANUMERIC_CACHE_ID = 0x02;
   public static final int NUMERIC_CACHE_ID = 0x03;
   public static final int STRLEN_CACHE_ID = 0x04;
+  public static final int VERSION_CACHE_ID = 0x05;
 
   public static class LexicographicComparator extends StringComparator
   {
@@ -416,4 +420,51 @@ public boolean equals(Object o)
       return new byte[]{(byte) NUMERIC_CACHE_ID};
     }
   }
+
+  public static class VersionComparator extends StringComparator
+  {
+    @Override
+    public int compare(String o1, String o2)
+    {
+      //noinspection StringEquality
+      if (o1 == o2) {
+        return 0;
+      }
+      if (o1 == null) {
+        return -1;
+      }
+      if (o2 == null) {
+        return 1;
+      }
+
+      DefaultArtifactVersion version1 = new DefaultArtifactVersion(o1);
+      DefaultArtifactVersion version2 = new DefaultArtifactVersion(o2);
+      return version1.compareTo(version2);
+    }
+
+    @Override
+    public String toString()
+    {
+      return StringComparators.VERSION_NAME;
+    }
+
+    @Override
+    public boolean equals(Object o)
+    {
+      if (this == o) {
+        return true;
+      }
+      if (o == null || getClass() != o.getClass()) {
+        return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public byte[] getCacheKey()
+    {
+      return new byte[]{(byte) VERSION_CACHE_ID};
+    }
+  }
 }
diff --git a/processing/src/test/java/org/apache/druid/query/ordering/StringComparatorsTest.java b/processing/src/test/java/org/apache/druid/query/ordering/StringComparatorsTest.java
index 3b48420c824..7fa0a3b82ca 100644
--- a/processing/src/test/java/org/apache/druid/query/ordering/StringComparatorsTest.java
+++ b/processing/src/test/java/org/apache/druid/query/ordering/StringComparatorsTest.java
@@ -142,6 +142,20 @@ public void testNumericComparator()
     Assert.assertTrue(StringComparators.NUMERIC.compare("CAN'T PARSE THIS", "CAN'T TOUCH THIS") < 0);
   }
 
+  @Test
+  public void testVersionComparator()
+  {
+    commonTest(StringComparators.VERSION);
+
+    Assert.assertTrue(StringComparators.VERSION.compare("02", "002") == 0);
+    Assert.assertTrue(StringComparators.VERSION.compare("1.0", "2.0") < 0);
+    Assert.assertTrue(StringComparators.VERSION.compare("9.1", "10.0") < 0);
+    Assert.assertTrue(StringComparators.VERSION.compare("1.1.1", "2.0") < 0);
+    Assert.assertTrue(StringComparators.VERSION.compare("1.0-SNAPSHOT", "1.0") < 0);
+    Assert.assertTrue(StringComparators.VERSION.compare("2.0.1-xyz-1", "2.0.1-1-xyz") < 0);
+    Assert.assertTrue(StringComparators.VERSION.compare("1.0-SNAPSHOT", "1.0-Final") < 0);
+  }
+
   @Test
   public void testLexicographicComparatorSerdeTest() throws IOException
   {


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org