-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Core: IRC: Implement Events Endpoint Request & Response Objects #14142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2ce33af
6973875
297617e
64c3350
f284c3c
b3aa3a5
9af725a
c06726d
a86efc1
8816be1
ec01ec7
5839653
e4526bf
223396b
e7a6501
a038642
7b4715e
db37555
e92afa6
97c8215
32d0f2b
398645e
589deee
c14d184
39f5b72
82010f2
17ef50a
ecc1cb5
0f6dfc4
a4c180c
870a12f
4e40fcc
850916b
3b1bc94
e0a8ca2
d8178ca
fd92ec1
fbf9ab6
8872937
aafe0b3
b128f93
0fb7224
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,111 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one | ||
| * or more contributor license agreements. See the NOTICE file | ||
| * distributed with this work for additional information | ||
| * regarding copyright ownership. The ASF licenses this file | ||
| * to you under the Apache License, Version 2.0 (the | ||
| * "License"); you may not use this file except in compliance | ||
| * with the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, | ||
| * software distributed under the License is distributed on an | ||
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| * KIND, either express or implied. See the License for the | ||
| * specific language governing permissions and limitations | ||
| * under the License. | ||
| */ | ||
| 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; | ||
|
|
||
| /** | ||
| * Reference to a named object in a {@link Catalog}, such as {@link Namespace}, {@link | ||
| * org.apache.iceberg.Table}, or {@link org.apache.iceberg.view.View}. | ||
| */ | ||
| public class CatalogObjectIdentifier { | ||
| private static final CatalogObjectIdentifier EMPTY_CATALOG_OBJECT = | ||
| new CatalogObjectIdentifier(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 CatalogObjectIdentifier empty() { | ||
| return EMPTY_CATALOG_OBJECT; | ||
| } | ||
|
|
||
| public static CatalogObjectIdentifier of(String... levels) { | ||
| Preconditions.checkArgument( | ||
| null != levels, "Cannot create CatalogObjectIdentifier from null array"); | ||
| if (levels.length == 0) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should not be allowed. A valid catalog object identifier should have at least one level of non-empty string value. For comparison with existing code, namespace can be empty, but table identifier name must be non-empty. |
||
| return empty(); | ||
| } | ||
|
|
||
| for (String level : levels) { | ||
| Preconditions.checkNotNull( | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see the current |
||
| level, "Cannot create a CatalogObjectIdentifier with a null level"); | ||
| Preconditions.checkArgument( | ||
| !CONTAINS_NULL_CHARACTER.test(level), | ||
| "Cannot create a CatalogObjectIdentifier with the null-byte character"); | ||
| } | ||
|
|
||
| return new CatalogObjectIdentifier(levels); | ||
| } | ||
|
|
||
| public static CatalogObjectIdentifier of(String name) { | ||
| Preconditions.checkNotNull(name, "Cannot create CatalogObjectIdentifier from null name"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not null and not empty |
||
|
|
||
| return of(name.split("\\.")); | ||
| } | ||
|
|
||
| private final String[] levels; | ||
|
|
||
| private CatalogObjectIdentifier(String[] levels) { | ||
| this.levels = levels; | ||
| } | ||
|
|
||
| public String[] levels() { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: add javadoc to public API methods |
||
| return levels; | ||
| } | ||
|
|
||
| public String level(int pos) { | ||
| return levels[pos]; | ||
| } | ||
|
|
||
| public boolean isEmpty() { | ||
| return levels.length == 0; | ||
| } | ||
|
|
||
| public int length() { | ||
| return levels.length; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean equals(Object other) { | ||
| if (this == other) { | ||
| return true; | ||
| } | ||
|
|
||
| if (other == null || getClass() != other.getClass()) { | ||
| return false; | ||
| } | ||
|
|
||
| CatalogObjectIdentifier catalogObjectIdentifier = (CatalogObjectIdentifier) other; | ||
| return Arrays.equals(levels, catalogObjectIdentifier.levels); | ||
| } | ||
|
|
||
| @Override | ||
| public int hashCode() { | ||
| return Arrays.hashCode(levels); | ||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return DOT.join(levels); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one | ||
| * or more contributor license agreements. See the NOTICE file | ||
| * distributed with this work for additional information | ||
| * regarding copyright ownership. The ASF licenses this file | ||
| * to you under the Apache License, Version 2.0 (the | ||
| * "License"); you may not use this file except in compliance | ||
| * with the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, | ||
| * software distributed under the License is distributed on an | ||
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| * KIND, either express or implied. See the License for the | ||
| * specific language governing permissions and limitations | ||
| * under the License. | ||
| */ | ||
| package org.apache.iceberg.catalog; | ||
|
|
||
| import java.util.Arrays; | ||
| import org.apache.iceberg.relocated.com.google.common.base.Preconditions; | ||
|
|
||
| /** | ||
| * Enum representing a CatalogObject i.e., {@link Namespace}, {@link org.apache.iceberg.Table}, or | ||
| * {@link org.apache.iceberg.view.View}. | ||
| */ | ||
| public enum CatalogObjectType { | ||
| NAMESPACE("namespace"), | ||
|
aheev marked this conversation as resolved.
|
||
| TABLE("table"), | ||
| VIEW("view"); | ||
|
|
||
| private final String type; | ||
|
|
||
| CatalogObjectType(String type) { | ||
| this.type = type; | ||
| } | ||
|
|
||
| public String type() { | ||
| return type; | ||
| } | ||
|
|
||
| public static CatalogObjectType fromType(String type) { | ||
| Preconditions.checkNotNull(type, "Invalid CatalogObjectType: null"); | ||
| return Arrays.stream(CatalogObjectType.values()) | ||
| .filter(catalogObjectType -> catalogObjectType.type.equalsIgnoreCase(type)) | ||
| .findFirst() | ||
| .orElseThrow(() -> new IllegalArgumentException("Invalid CatalogObjectType: " + type)); | ||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return type; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one | ||
| * or more contributor license agreements. See the NOTICE file | ||
| * distributed with this work for additional information | ||
| * regarding copyright ownership. The ASF licenses this file | ||
| * to you under the Apache License, Version 2.0 (the | ||
| * "License"); you may not use this file except in compliance | ||
| * with the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, | ||
| * software distributed under the License is distributed on an | ||
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| * KIND, either express or implied. See the License for the | ||
| * specific language governing permissions and limitations | ||
| * under the License. | ||
| */ | ||
| package org.apache.iceberg.catalog; | ||
|
|
||
| import java.util.Objects; | ||
| import org.apache.iceberg.relocated.com.google.common.base.MoreObjects; | ||
| import org.apache.iceberg.relocated.com.google.common.base.Preconditions; | ||
|
|
||
| /** | ||
| * Identifies a {@link org.apache.iceberg.Table} or {@link org.apache.iceberg.view.View} by UUID. | ||
| */ | ||
| public class CatalogObjectUuid { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't quite understand the need of this class. |
||
| private final String uuid; | ||
|
|
||
| /** one of ["table", "view"]. Assign using {@link CatalogObjectType#type()} */ | ||
| private final String type; | ||
|
|
||
| public CatalogObjectUuid(String uuid, String type) { | ||
| Preconditions.checkNotNull(uuid, "Invalid UUID: null"); | ||
|
|
||
| if (uuid.isEmpty()) { | ||
| throw new IllegalArgumentException("Invalid UUID: empty"); | ||
| } | ||
|
|
||
| if (!type.equals(CatalogObjectType.TABLE.type()) | ||
| && !type.equals(CatalogObjectType.VIEW.type())) { | ||
| throw new IllegalArgumentException("Invalid type: " + type); | ||
| } | ||
|
|
||
| this.uuid = uuid; | ||
| this.type = type; | ||
| } | ||
|
|
||
| public String uuid() { | ||
| return uuid; | ||
| } | ||
|
|
||
| public String type() { | ||
| return type; | ||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return MoreObjects.toStringHelper(this).add("uuid", uuid).add("type", type).toString(); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean equals(Object o) { | ||
| if (this == o) { | ||
| return true; | ||
| } | ||
|
|
||
| if (o == null || getClass() != o.getClass()) { | ||
| return false; | ||
| } | ||
|
|
||
| CatalogObjectUuid that = (CatalogObjectUuid) o; | ||
| return uuid.equals(that.uuid) && type.equals(that.type); | ||
| } | ||
|
|
||
| @Override | ||
| public int hashCode() { | ||
| return Objects.hash(uuid, type); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one | ||
| * or more contributor license agreements. See the NOTICE file | ||
| * distributed with this work for additional information | ||
| * regarding copyright ownership. The ASF licenses this file | ||
| * to you under the Apache License, Version 2.0 (the | ||
| * "License"); you may not use this file except in compliance | ||
| * with the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, | ||
| * software distributed under the License is distributed on an | ||
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| * KIND, either express or implied. See the License for the | ||
| * specific language governing permissions and limitations | ||
| * under the License. | ||
| */ | ||
| package org.apache.iceberg.catalog; | ||
|
|
||
| import static org.assertj.core.api.Assertions.assertThat; | ||
| import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
|
|
||
| import org.junit.jupiter.api.Test; | ||
|
|
||
| public class TestCatalogObjectIdentifier { | ||
|
|
||
| @Test | ||
| public void testWithNullAndEmpty() { | ||
| assertThatThrownBy(() -> CatalogObjectIdentifier.of((String[]) null)) | ||
| .isInstanceOf(IllegalArgumentException.class) | ||
| .hasMessage("Cannot create CatalogObjectIdentifier from null array"); | ||
|
|
||
| assertThat(CatalogObjectIdentifier.of()).isEqualTo(CatalogObjectIdentifier.empty()); | ||
| } | ||
|
|
||
| @Test | ||
| public void testCatalogObjectIdentifier() { | ||
| String[] levels = {"a", "b", "c", "d"}; | ||
| CatalogObjectIdentifier catalogObjectIdentifier = CatalogObjectIdentifier.of(levels); | ||
| assertThat(catalogObjectIdentifier).isNotNull(); | ||
| assertThat(catalogObjectIdentifier.levels()).hasSize(4); | ||
| assertThat(catalogObjectIdentifier).hasToString("a.b.c.d"); | ||
| for (int i = 0; i < levels.length; i++) { | ||
| assertThat(catalogObjectIdentifier.level(i)).isEqualTo(levels[i]); | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| public void testWithNullInLevel() { | ||
| assertThatThrownBy(() -> CatalogObjectIdentifier.of("a", null, "b")) | ||
| .isInstanceOf(NullPointerException.class) | ||
| .hasMessage("Cannot create a CatalogObjectIdentifier with a null level"); | ||
| } | ||
|
|
||
| @Test | ||
| public void testDisallowsCatalogObjectIdentifierWithNullByte() { | ||
| assertThatThrownBy(() -> CatalogObjectIdentifier.of("ac", "\u0000c", "b")) | ||
| .isInstanceOf(IllegalArgumentException.class) | ||
| .hasMessage("Cannot create a CatalogObjectIdentifier with the null-byte character"); | ||
|
|
||
| assertThatThrownBy(() -> CatalogObjectIdentifier.of("ac", "c\0", "b")) | ||
| .isInstanceOf(IllegalArgumentException.class) | ||
| .hasMessage("Cannot create a CatalogObjectIdentifier with the null-byte character"); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one | ||
| * or more contributor license agreements. See the NOTICE file | ||
| * distributed with this work for additional information | ||
| * regarding copyright ownership. The ASF licenses this file | ||
| * to you under the Apache License, Version 2.0 (the | ||
| * "License"); you may not use this file except in compliance | ||
| * with the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, | ||
| * software distributed under the License is distributed on an | ||
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| * KIND, either express or implied. See the License for the | ||
| * specific language governing permissions and limitations | ||
| * under the License. | ||
| */ | ||
| package org.apache.iceberg.catalog; | ||
|
|
||
| import static org.assertj.core.api.Assertions.assertThat; | ||
| import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
|
|
||
| import org.junit.jupiter.api.Test; | ||
|
|
||
| public class TestCatalogObjectType { | ||
|
|
||
| @Test | ||
| void testFromType() { | ||
| assertThat(CatalogObjectType.fromType("namespace")).isEqualTo(CatalogObjectType.NAMESPACE); | ||
|
|
||
| assertThatThrownBy(() -> CatalogObjectType.fromType(null)) | ||
| .isInstanceOf(NullPointerException.class) | ||
| .hasMessage("Invalid CatalogObjectType: null"); | ||
|
|
||
| assertThatThrownBy(() -> CatalogObjectType.fromType("invalid_type")) | ||
| .isInstanceOf(IllegalArgumentException.class) | ||
| .hasMessage("Invalid CatalogObjectType: invalid_type"); | ||
| } | ||
|
|
||
| @Test | ||
| void testToString() { | ||
| assertThat(CatalogObjectType.TABLE.toString()).isEqualTo("table"); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this new concept makes sense to me. It is also useful for the universal load endpoint (table, view, MV, index) that we talked about in the community discussion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we update
NamespaceandTableIdentifierto extend from this class to reduce code duplication?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am wondering if the
CatalogObjectIdentifiercan still have two partsnamespaceandname, where object name can be optional.In yesterday's catalog sync, there is also a discussion about global scope UDF function. We decided not to allow it for now. But if global scope is going to be allowed in the future, then namespace can be optional. At least one of the two parts must be not null or empty.