This is an automated email from the ASF dual-hosted git repository. vladimirsitnikov pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/calcite.git
commit 9422fd444f0cb01cf5659045d1bb3bc71b59b73e Author: Vladimir Sitnikov <sitnikov.vladi...@gmail.com> AuthorDate: Fri Sep 4 23:29:30 2020 +0300 [CALCITE-4226] Add Mappings#asListNonNull as a null-safe alternative for Mappings#asList --- .../org/apache/calcite/util/mapping/Mappings.java | 27 ++++++++++++++++++++++ .../apache/calcite/util/mapping/MappingTest.java | 13 ++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/apache/calcite/util/mapping/Mappings.java b/core/src/main/java/org/apache/calcite/util/mapping/Mappings.java index 9162d40..88d2c7e 100644 --- a/core/src/main/java/org/apache/calcite/util/mapping/Mappings.java +++ b/core/src/main/java/org/apache/calcite/util/mapping/Mappings.java @@ -326,6 +326,33 @@ public abstract class Mappings { } /** + * Returns a mapping as a list such that {@code list.get(source)} is + * {@code mapping.getTarget(source)} and {@code list.size()} is + * {@code mapping.getSourceCount()}. + * + * <p>The resulting list never contains null elements</p> + * + * <p>Converse of {@link #target(List, int)}</p> + * @see #asList(TargetMapping) + */ + public static List<Integer> asListNonNull(final TargetMapping mapping) { + return new AbstractList<Integer>() { + public Integer get(int source) { + int target = mapping.getTargetOpt(source); + if (target < 0) { + throw new IllegalArgumentException("Element " + source + " is not found in mapping " + + mapping); + } + return target; + } + + public int size() { + return mapping.getSourceCount(); + } + }; + } + + /** * Converts a {@link Map} of integers to a {@link TargetMapping}. */ public static TargetMapping target( diff --git a/core/src/test/java/org/apache/calcite/util/mapping/MappingTest.java b/core/src/test/java/org/apache/calcite/util/mapping/MappingTest.java index 9be5938..42a41a7 100644 --- a/core/src/test/java/org/apache/calcite/util/mapping/MappingTest.java +++ b/core/src/test/java/org/apache/calcite/util/mapping/MappingTest.java @@ -171,7 +171,10 @@ class MappingTest { assertThrows(IndexOutOfBoundsException.class, () -> mapping.getTarget(-1)); final List<Integer> integers = Mappings.asList(mapping); - assertThat(integers, equalTo(targets)); + assertThat("Mappings.asList" + mapping + ")", integers, equalTo(targets)); + assertThat( + "Mappings.asListNonNull(" + mapping + ")", + Mappings.asListNonNull(mapping), equalTo(targets)); final Mapping inverse = mapping.inverse(); assertThat(inverse.toString(), @@ -200,6 +203,14 @@ class MappingTest { final List<Integer> integers = Mappings.asList(mapping); assertThat(integers, equalTo(Arrays.asList(null, 1, null, 0, 2, 3, null, null, 4, null))); + + // Note: exception is thrown on list.get, so it is needed to trigger the exception + IllegalArgumentException exception = + assertThrows(IllegalArgumentException.class, () -> + Mappings.asListNonNull(mapping).get(0)); + assertThat(exception.getMessage(), + equalTo("Element 0 is not found in mapping [size=5, sourceCount=10, targetCount=5" + + ", elements=[1:1, 3:0, 4:2, 5:3, 8:4]]")); } /** Unit test for {@link Mappings#bijection(List)}. */