mirror of https://github.com/apache/druid.git
add version comparator for StringComparator (#6745)
* add version comparator for StringComparator * add more test case and docs
This commit is contained in:
parent
c4716d1639
commit
def823124c
|
@ -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|
|
|upper|String|The upper bound for the filter|no|
|
||||||
|lowerStrict|Boolean|Perform strict comparison on the lower bound (">" instead of ">=")|no, default: false|
|
|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|
|
|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|
|
|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.
|
Bound filters support the use of extraction functions, see [Filtering with Extraction Functions](#filtering-with-extraction-functions) for details.
|
||||||
|
|
|
@ -47,3 +47,8 @@ When comparing two unparseable values (e.g., "hello" and "world"), this ordering
|
||||||
|
|
||||||
## Strlen
|
## Strlen
|
||||||
Sorts values by the their string lengths. When there is a tie, this comparator falls back to using the String compareTo method.
|
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.
|
5
pom.xml
5
pom.xml
|
@ -749,6 +749,11 @@
|
||||||
<artifactId>caffeine</artifactId>
|
<artifactId>caffeine</artifactId>
|
||||||
<version>${caffeine.version}</version>
|
<version>${caffeine.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.maven</groupId>
|
||||||
|
<artifactId>maven-artifact</artifactId>
|
||||||
|
<version>3.6.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.calcite</groupId>
|
<groupId>org.apache.calcite</groupId>
|
||||||
|
|
|
@ -116,6 +116,11 @@
|
||||||
<artifactId>checker</artifactId>
|
<artifactId>checker</artifactId>
|
||||||
<version>${checkerframework.version}</version>
|
<version>${checkerframework.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.maven</groupId>
|
||||||
|
<artifactId>maven-artifact</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<!-- Tests -->
|
<!-- Tests -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -36,7 +36,8 @@ public class StringComparatorModule extends SimpleModule
|
||||||
new NamedType(StringComparators.LexicographicComparator.class, StringComparators.LEXICOGRAPHIC_NAME),
|
new NamedType(StringComparators.LexicographicComparator.class, StringComparators.LEXICOGRAPHIC_NAME),
|
||||||
new NamedType(StringComparators.AlphanumericComparator.class, StringComparators.ALPHANUMERIC_NAME),
|
new NamedType(StringComparators.AlphanumericComparator.class, StringComparators.ALPHANUMERIC_NAME),
|
||||||
new NamedType(StringComparators.StrlenComparator.class, StringComparators.STRLEN_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)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,8 @@ public abstract class StringComparator implements Comparator<String>
|
||||||
return StringComparators.STRLEN;
|
return StringComparators.STRLEN;
|
||||||
case StringComparators.NUMERIC_NAME:
|
case StringComparators.NUMERIC_NAME:
|
||||||
return StringComparators.NUMERIC;
|
return StringComparators.NUMERIC;
|
||||||
|
case StringComparators.VERSION_NAME:
|
||||||
|
return StringComparators.VERSION;
|
||||||
default:
|
default:
|
||||||
throw new IAE("Unknown string comparator[%s]", type);
|
throw new IAE("Unknown string comparator[%s]", type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import com.google.common.primitives.Ints;
|
||||||
import com.google.common.primitives.UnsignedBytes;
|
import com.google.common.primitives.UnsignedBytes;
|
||||||
import org.apache.druid.common.guava.GuavaUtils;
|
import org.apache.druid.common.guava.GuavaUtils;
|
||||||
import org.apache.druid.java.util.common.StringUtils;
|
import org.apache.druid.java.util.common.StringUtils;
|
||||||
|
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
@ -34,16 +35,19 @@ public class StringComparators
|
||||||
public static final String ALPHANUMERIC_NAME = "alphanumeric";
|
public static final String ALPHANUMERIC_NAME = "alphanumeric";
|
||||||
public static final String NUMERIC_NAME = "numeric";
|
public static final String NUMERIC_NAME = "numeric";
|
||||||
public static final String STRLEN_NAME = "strlen";
|
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 LEXICOGRAPHIC = new LexicographicComparator();
|
||||||
public static final StringComparator ALPHANUMERIC = new AlphanumericComparator();
|
public static final StringComparator ALPHANUMERIC = new AlphanumericComparator();
|
||||||
public static final StringComparator NUMERIC = new NumericComparator();
|
public static final StringComparator NUMERIC = new NumericComparator();
|
||||||
public static final StringComparator STRLEN = new StrlenComparator();
|
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 LEXICOGRAPHIC_CACHE_ID = 0x01;
|
||||||
public static final int ALPHANUMERIC_CACHE_ID = 0x02;
|
public static final int ALPHANUMERIC_CACHE_ID = 0x02;
|
||||||
public static final int NUMERIC_CACHE_ID = 0x03;
|
public static final int NUMERIC_CACHE_ID = 0x03;
|
||||||
public static final int STRLEN_CACHE_ID = 0x04;
|
public static final int STRLEN_CACHE_ID = 0x04;
|
||||||
|
public static final int VERSION_CACHE_ID = 0x05;
|
||||||
|
|
||||||
public static class LexicographicComparator extends StringComparator
|
public static class LexicographicComparator extends StringComparator
|
||||||
{
|
{
|
||||||
|
@ -416,4 +420,51 @@ public class StringComparators
|
||||||
return new byte[]{(byte) NUMERIC_CACHE_ID};
|
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};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,6 +142,20 @@ public class StringComparatorsTest
|
||||||
Assert.assertTrue(StringComparators.NUMERIC.compare("CAN'T PARSE THIS", "CAN'T TOUCH THIS") < 0);
|
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
|
@Test
|
||||||
public void testLexicographicComparatorSerdeTest() throws IOException
|
public void testLexicographicComparatorSerdeTest() throws IOException
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue