Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions api/src/main/java/org/apache/iceberg/catalog/Namespace.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
package org.apache.iceberg.catalog;

import java.util.Arrays;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import org.apache.iceberg.relocated.com.google.common.base.Joiner;
import org.apache.iceberg.relocated.com.google.common.base.Preconditions;

Expand All @@ -29,6 +31,8 @@
public class Namespace {
private static final Namespace EMPTY_NAMESPACE = new Namespace(new String[] {});
private static final Joiner DOT = Joiner.on('.');
private static final Predicate<String> CONTAINS_NULL_CHARACTER =
Pattern.compile("\u0000", Pattern.UNICODE_CHARACTER_CLASS).asPredicate();

public static Namespace empty() {
return EMPTY_NAMESPACE;
Expand All @@ -40,6 +44,13 @@ public static Namespace of(String... levels) {
return empty();
}

for (String level : levels) {
Preconditions.checkNotNull(level,
"Cannot create a namespace with a null level");
Preconditions.checkArgument(!CONTAINS_NULL_CHARACTER.test(level),
"Cannot create a namespace with the null-byte character");
}

return new Namespace(levels);
}

Expand Down
25 changes: 25 additions & 0 deletions api/src/test/java/org/apache/iceberg/catalog/TestNamespace.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

package org.apache.iceberg.catalog;

import org.apache.iceberg.AssertHelpers;
import org.assertj.core.api.Assertions;
import org.junit.Test;

Expand All @@ -44,4 +45,28 @@ public void testNamespace() {
Assertions.assertThat(namespace.level(i)).isEqualTo(levels[i]);
}
}

@Test
public void testWithNullInLevel() {
AssertHelpers.assertThrows(
"An individual level of a namespace cannot be null",
NullPointerException.class,
"Cannot create a namespace with a null level",
() -> Namespace.of("a", null, "b"));
}

@Test
public void testDisallowsNamespaceWithNullByte() {
AssertHelpers.assertThrows(
"An individual level of a namespace cannot contain the standard null-byte character",
IllegalArgumentException.class,
"Cannot create a namespace with the null-byte character",
() -> Namespace.of("ac", "\u0000c", "b"));

AssertHelpers.assertThrows(
"An individual level of a namespace cannot contain the original ASCII null-byte character",
IllegalArgumentException.class,
"Cannot create a namespace with the null-byte character",
() -> Namespace.of("ac", "c\0", "b"));
}
}