This is an automated email from the ASF dual-hosted git repository.
jshao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new 0d73e4c2f8 [#7440] feat(model): Support for altering model version
with multiple URIs (#7881)
0d73e4c2f8 is described below
commit 0d73e4c2f88b77bc8df69ae5f102f521972b99f1
Author: XiaoZ <[email protected]>
AuthorDate: Thu Aug 7 15:17:33 2025 +0800
[#7440] feat(model): Support for altering model version with multiple URIs
(#7881)
### What changes were proposed in this pull request?
Support for altering model version with multiple URIs.
### Why are the changes needed?
Fix: #7440
### Does this PR introduce _any_ user-facing change?
No.
### How was this patch tested?
UT.
---------
Co-authored-by: zhanghan <[email protected]>
---
.../apache/gravitino/model/ModelVersionChange.java | 205 ++++++++++++++++++++-
.../gravitino/model/TestModelVersionChange.java | 136 +++++++++++++-
.../catalog/model/ModelCatalogOperations.java | 31 +++-
.../catalog/model/TestModelCatalogOperations.java | 204 +++++++++++++++++++-
.../relational/mapper/ModelVersionMetaMapper.java | 15 +-
.../mapper/ModelVersionMetaSQLProviderFactory.java | 12 +-
.../base/ModelVersionMetaBaseSQLProvider.java | 45 +++--
.../provider/h2/ModelVersionMetaH2Provider.java | 28 +++
.../service/ModelVersionMetaService.java | 63 ++++---
.../storage/relational/utils/POConverters.java | 9 +-
.../catalog/TestModelOperationDispatcher.java | 168 ++++++++++++++++-
.../gravitino/connector/TestCatalogOperations.java | 18 +-
.../service/TestModelVersionMetaService.java | 8 +-
13 files changed, 839 insertions(+), 103 deletions(-)
diff --git
a/api/src/main/java/org/apache/gravitino/model/ModelVersionChange.java
b/api/src/main/java/org/apache/gravitino/model/ModelVersionChange.java
index 55fa015453..d79235564d 100644
--- a/api/src/main/java/org/apache/gravitino/model/ModelVersionChange.java
+++ b/api/src/main/java/org/apache/gravitino/model/ModelVersionChange.java
@@ -80,6 +80,38 @@ public interface ModelVersionChange {
return new ModelVersionChange.UpdateUri(newUri);
}
+ /**
+ * Create a ModelVersionChange for updating the uri of a model version.
+ *
+ * @param uriName The name of the uri to be updated for the model version.
+ * @param newUri The new uri to be set for the model version.
+ * @return A new ModelVersionChange instance for updating the uri of a model
version.
+ */
+ static ModelVersionChange updateUri(String uriName, String newUri) {
+ return new ModelVersionChange.UpdateUri(uriName, newUri);
+ }
+
+ /**
+ * Create a ModelVersionChange for adding the uri of a model version.
+ *
+ * @param uriName The name of the uri to be added for the model version.
+ * @param uri The uri to be added for the model version.
+ * @return A new ModelVersionChange instance for adding the uri of a model
version.
+ */
+ static ModelVersionChange addUri(String uriName, String uri) {
+ return new ModelVersionChange.AddUri(uriName, uri);
+ }
+
+ /**
+ * Create a ModelVersionChange for removing the uri of a model version.
+ *
+ * @param uriName The name of the uri to be removed for the model version.
+ * @return A new ModelVersionChange instance for removing the uri of a model
version.
+ */
+ static ModelVersionChange removeUri(String uriName) {
+ return new ModelVersionChange.RemoveUri(uriName);
+ }
+
/**
* Create a ModelVersionChange for updating the aliases of a model version.
*
@@ -139,7 +171,7 @@ public interface ModelVersionChange {
* Generates a hash code for this {@link UpdateComment} instance. The hash
code is based on the
* new comment of the model.
*
- * @return A hash code value for this model renaming operation.
+ * @return A hash code value for this comment update operation.
*/
@Override
public int hashCode() {
@@ -294,6 +326,7 @@ public interface ModelVersionChange {
/** A ModelVersionChange to update the uri of a model version. */
final class UpdateUri implements ModelVersionChange {
+ private final String uriName;
private final String newUri;
/**
@@ -302,6 +335,17 @@ public interface ModelVersionChange {
* @param newUri The new uri to be set for the model version.
*/
public UpdateUri(String newUri) {
+ this(ModelVersion.URI_NAME_UNKNOWN, newUri);
+ }
+
+ /**
+ * Creates a new {@link UpdateUri} instance with the specified new uri and
its name.
+ *
+ * @param uriName The name of the uri to be updated for the model version.
+ * @param newUri The new uri to be set for the model version.
+ */
+ public UpdateUri(String uriName, String newUri) {
+ this.uriName = uriName;
this.newUri = newUri;
}
@@ -314,9 +358,18 @@ public interface ModelVersionChange {
return newUri;
}
+ /**
+ * Returns the name of the uri to be updated for the model version.
+ *
+ * @return The name of the uri to be updated for the model version.
+ */
+ public String uriName() {
+ return uriName;
+ }
+
/**
* Compares this UpdateUri instance with another object for equality. The
comparison is based on
- * the new uri of the model version.
+ * the new uri and its name of the model version.
*
* @param obj The object to compare with this instance.
* @return {@code true} if the given object represents the same model
update operation; {@code
@@ -327,29 +380,163 @@ public interface ModelVersionChange {
if (obj == this) return true;
if (!(obj instanceof UpdateUri)) return false;
UpdateUri other = (UpdateUri) obj;
- return Objects.equals(newUri, other.newUri);
+ return Objects.equals(newUri, other.newUri) && Objects.equals(uriName,
other.uriName);
}
/**
- * Generates a hash code for this UpdateUri instance. The hash code is
based on the new uri of
- * the model.
+ * Generates a hash code for this UpdateUri instance. The hash code is
based on the new uri and
+ * its name of the model version.
*
- * @return A hash code value for this model renaming operation.
+ * @return A hash code value for this URI update operation.
*/
@Override
public int hashCode() {
- return Objects.hash(newUri);
+ return Objects.hash(newUri, uriName);
}
/**
* Provides a string representation of the UpdateUri instance. This string
format includes the
- * class name followed by the new uri to be set.
+ * class name followed by the new uri and its name to be updated.
*
* @return A string summary of the UpdateUri instance.
*/
@Override
public String toString() {
- return "UpdateUri " + newUri;
+ return "UpdateUri uriName: (" + uriName + ") newUri: (" + newUri + ")";
+ }
+ }
+
+ /** A ModelVersionChange to add a uri of a model version. */
+ final class AddUri implements ModelVersionChange {
+ private final String uriName;
+ private final String uri;
+
+ /**
+ * Creates a new {@link AddUri} instance with the specified uri and uri
name.
+ *
+ * @param uriName The name of the uri to be added.
+ * @param uri The uri to be added for the model version.
+ */
+ public AddUri(String uriName, String uri) {
+ this.uriName = uriName;
+ this.uri = uri;
+ }
+
+ /**
+ * Returns the uri to be added for the model version.
+ *
+ * @return The uri to be added for the model version.
+ */
+ public String uri() {
+ return uri;
+ }
+
+ /**
+ * Returns the name of the uri to be added for the model version.
+ *
+ * @return The name of the uri to be added for the model version.
+ */
+ public String uriName() {
+ return uriName;
+ }
+
+ /**
+ * Compares this AddUri instance with another object for equality. The
comparison is based on
+ * the uri and its name of the model version.
+ *
+ * @param obj The object to compare with this instance.
+ * @return {@code true} if the given object represents the same model
update operation; {@code
+ * false} otherwise.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) return true;
+ if (!(obj instanceof AddUri)) return false;
+ AddUri other = (AddUri) obj;
+ return Objects.equals(uri, other.uri) && Objects.equals(uriName,
other.uriName);
+ }
+
+ /**
+ * Generates a hash code for this AddUri instance. The hash code is based
on the uri and its
+ * name of the model.
+ *
+ * @return A hash code value for this URI addition operation.
+ */
+ @Override
+ public int hashCode() {
+ return Objects.hash(uri, uriName);
+ }
+
+ /**
+ * Provides a string representation of the AddUri instance. This string
format includes the
+ * class name followed by the uri and its name to be added.
+ *
+ * @return A string summary of the AddUri instance.
+ */
+ @Override
+ public String toString() {
+ return "AddUri uriName: (" + uriName + ") uri: (" + uri + ")";
+ }
+ }
+
+ /** A ModelVersionChange to remove a uri of a model version. */
+ final class RemoveUri implements ModelVersionChange {
+ private final String uriName;
+
+ /**
+ * Creates a new {@link RemoveUri} instance with the specified uri name.
+ *
+ * @param uriName The name of the uri to be removed.
+ */
+ public RemoveUri(String uriName) {
+ this.uriName = uriName;
+ }
+
+ /**
+ * Returns the name of the uri to be removed for the model version.
+ *
+ * @return The name of the uri to be removed for the model version.
+ */
+ public String uriName() {
+ return uriName;
+ }
+
+ /**
+ * Compares this RemoveUri instance with another object for equality. The
comparison is based on
+ * the uri name of the model version.
+ *
+ * @param obj The object to compare with this instance.
+ * @return {@code true} if the given object represents the same model
update operation; {@code
+ * false} otherwise.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) return true;
+ if (!(obj instanceof RemoveUri)) return false;
+ RemoveUri other = (RemoveUri) obj;
+ return Objects.equals(uriName, other.uriName);
+ }
+
+ /**
+ * Generates a hash code for this RemoveUri instance. The hash code is
based on the uri and its
+ * name of the model.
+ *
+ * @return A hash code value for this URI removal operation.
+ */
+ @Override
+ public int hashCode() {
+ return Objects.hash(uriName);
+ }
+
+ /**
+ * Provides a string representation of the RemoveUri instance. This string
format includes the
+ * class name followed by the uri name to be removed.
+ *
+ * @return A string summary of the RemoveUri instance.
+ */
+ @Override
+ public String toString() {
+ return "RemoveUri uriName: (" + uriName + ")";
}
}
diff --git
a/api/src/test/java/org/apache/gravitino/model/TestModelVersionChange.java
b/api/src/test/java/org/apache/gravitino/model/TestModelVersionChange.java
index cd64776390..ac79955fbd 100644
--- a/api/src/test/java/org/apache/gravitino/model/TestModelVersionChange.java
+++ b/api/src/test/java/org/apache/gravitino/model/TestModelVersionChange.java
@@ -169,7 +169,21 @@ public class TestModelVersionChange {
ModelVersionChange.UpdateUri updateUriChange =
(ModelVersionChange.UpdateUri) modelVersionChange;
Assertions.assertEquals(newUri, updateUriChange.newUri());
- Assertions.assertEquals("UpdateUri " + newUri, updateUriChange.toString());
+ Assertions.assertEquals(ModelVersion.URI_NAME_UNKNOWN,
updateUriChange.uriName());
+ Assertions.assertEquals(
+ "UpdateUri uriName: (unknown) newUri: (" + newUri + ")",
updateUriChange.toString());
+
+ String uriName = "n1";
+ modelVersionChange = ModelVersionChange.updateUri(uriName, newUri);
+
+ Assertions.assertEquals(ModelVersionChange.UpdateUri.class,
modelVersionChange.getClass());
+
+ updateUriChange = (ModelVersionChange.UpdateUri) modelVersionChange;
+ Assertions.assertEquals(newUri, updateUriChange.newUri());
+ Assertions.assertEquals(uriName, updateUriChange.uriName());
+ Assertions.assertEquals(
+ "UpdateUri uriName: (" + uriName + ") newUri: (" + newUri + ")",
+ updateUriChange.toString());
}
@Test
@@ -182,7 +196,21 @@ public class TestModelVersionChange {
ModelVersionChange.UpdateUri updateUriChange =
(ModelVersionChange.UpdateUri) modelVersionChange;
Assertions.assertEquals(newUri, updateUriChange.newUri());
- Assertions.assertEquals("UpdateUri " + newUri, updateUriChange.toString());
+ Assertions.assertEquals(ModelVersion.URI_NAME_UNKNOWN,
updateUriChange.uriName());
+ Assertions.assertEquals(
+ "UpdateUri uriName: (unknown) newUri: (" + newUri + ")",
updateUriChange.toString());
+
+ String uriName = "n1";
+ modelVersionChange = new ModelVersionChange.UpdateUri(uriName, newUri);
+
+ Assertions.assertEquals(ModelVersionChange.UpdateUri.class,
modelVersionChange.getClass());
+
+ updateUriChange = (ModelVersionChange.UpdateUri) modelVersionChange;
+ Assertions.assertEquals(newUri, updateUriChange.newUri());
+ Assertions.assertEquals(uriName, updateUriChange.uriName());
+ Assertions.assertEquals(
+ "UpdateUri uriName: (" + uriName + ") newUri: (" + newUri + ")",
+ updateUriChange.toString());
}
@Test
@@ -201,6 +229,110 @@ public class TestModelVersionChange {
Assertions.assertEquals(modelVersionChange1.hashCode(),
modelVersionChange2.hashCode());
Assertions.assertNotEquals(modelVersionChange1.hashCode(),
modelVersionChange3.hashCode());
Assertions.assertNotEquals(modelVersionChange2.hashCode(),
modelVersionChange3.hashCode());
+
+ modelVersionChange1 = ModelVersionChange.updateUri("n1", uri1);
+ modelVersionChange2 = ModelVersionChange.updateUri("n1", uri1);
+ modelVersionChange3 = ModelVersionChange.updateUri("n2", uri2);
+
+ Assertions.assertEquals(modelVersionChange1, modelVersionChange2);
+ Assertions.assertNotEquals(modelVersionChange1, modelVersionChange3);
+ Assertions.assertNotEquals(modelVersionChange2, modelVersionChange3);
+
+ Assertions.assertEquals(modelVersionChange1.hashCode(),
modelVersionChange2.hashCode());
+ Assertions.assertNotEquals(modelVersionChange1.hashCode(),
modelVersionChange3.hashCode());
+ Assertions.assertNotEquals(modelVersionChange2.hashCode(),
modelVersionChange3.hashCode());
+ }
+
+ @Test
+ void testAddUriChangeUseStaticMethod() {
+ String uri = "S3://bucket/key";
+ String uriName = "n1";
+ ModelVersionChange modelVersionChange = ModelVersionChange.addUri(uriName,
uri);
+
+ Assertions.assertEquals(ModelVersionChange.AddUri.class,
modelVersionChange.getClass());
+
+ ModelVersionChange.AddUri change = (ModelVersionChange.AddUri)
modelVersionChange;
+ Assertions.assertEquals(uri, change.uri());
+ Assertions.assertEquals(uriName, change.uriName());
+ Assertions.assertEquals(
+ "AddUri uriName: (" + uriName + ") uri: (" + uri + ")",
change.toString());
+ }
+
+ @Test
+ void testAddUriChangeUseConstructor() {
+ String uri = "S3://bucket/key";
+ String uriName = "n1";
+ ModelVersionChange modelVersionChange = new
ModelVersionChange.AddUri(uriName, uri);
+
+ Assertions.assertEquals(ModelVersionChange.AddUri.class,
modelVersionChange.getClass());
+
+ ModelVersionChange.AddUri change = (ModelVersionChange.AddUri)
modelVersionChange;
+ Assertions.assertEquals(uri, change.uri());
+ Assertions.assertEquals(uriName, change.uriName());
+ Assertions.assertEquals(
+ "AddUri uriName: (" + uriName + ") uri: (" + uri + ")",
change.toString());
+ }
+
+ @Test
+ void testAddUriChangeEquals() {
+ String uri1 = "S3://bucket/key1";
+ String uri2 = "S3://bucket/key2";
+ String uriName1 = "n1";
+ String uriName2 = "n2";
+
+ ModelVersionChange modelVersionChange1 =
ModelVersionChange.addUri(uriName1, uri1);
+ ModelVersionChange modelVersionChange2 =
ModelVersionChange.addUri(uriName1, uri1);
+ ModelVersionChange modelVersionChange3 =
ModelVersionChange.addUri(uriName2, uri2);
+
+ Assertions.assertEquals(modelVersionChange1, modelVersionChange2);
+ Assertions.assertNotEquals(modelVersionChange1, modelVersionChange3);
+ Assertions.assertNotEquals(modelVersionChange2, modelVersionChange3);
+
+ Assertions.assertEquals(modelVersionChange1.hashCode(),
modelVersionChange2.hashCode());
+ Assertions.assertNotEquals(modelVersionChange1.hashCode(),
modelVersionChange3.hashCode());
+ Assertions.assertNotEquals(modelVersionChange2.hashCode(),
modelVersionChange3.hashCode());
+ }
+
+ @Test
+ void testRemoveUriChangeUseStaticMethod() {
+ String uriName = "n1";
+ ModelVersionChange modelVersionChange =
ModelVersionChange.removeUri(uriName);
+
+ Assertions.assertEquals(ModelVersionChange.RemoveUri.class,
modelVersionChange.getClass());
+
+ ModelVersionChange.RemoveUri change = (ModelVersionChange.RemoveUri)
modelVersionChange;
+ Assertions.assertEquals(uriName, change.uriName());
+ Assertions.assertEquals("RemoveUri uriName: (" + uriName + ")",
change.toString());
+ }
+
+ @Test
+ void testRemoveUriChangeUseConstructor() {
+ String uriName = "n1";
+ ModelVersionChange modelVersionChange = new
ModelVersionChange.RemoveUri(uriName);
+
+ Assertions.assertEquals(ModelVersionChange.RemoveUri.class,
modelVersionChange.getClass());
+
+ ModelVersionChange.RemoveUri change = (ModelVersionChange.RemoveUri)
modelVersionChange;
+ Assertions.assertEquals(uriName, change.uriName());
+ Assertions.assertEquals("RemoveUri uriName: (" + uriName + ")",
change.toString());
+ }
+
+ @Test
+ void testRemoveUriChangeEquals() {
+ String uriName1 = "n1";
+ String uriName2 = "n2";
+
+ ModelVersionChange modelVersionChange1 =
ModelVersionChange.removeUri(uriName1);
+ ModelVersionChange modelVersionChange2 =
ModelVersionChange.removeUri(uriName1);
+ ModelVersionChange modelVersionChange3 =
ModelVersionChange.removeUri(uriName2);
+
+ Assertions.assertEquals(modelVersionChange1, modelVersionChange2);
+ Assertions.assertNotEquals(modelVersionChange1, modelVersionChange3);
+ Assertions.assertNotEquals(modelVersionChange2, modelVersionChange3);
+
+ Assertions.assertEquals(modelVersionChange1.hashCode(),
modelVersionChange2.hashCode());
+ Assertions.assertNotEquals(modelVersionChange1.hashCode(),
modelVersionChange3.hashCode());
+ Assertions.assertNotEquals(modelVersionChange2.hashCode(),
modelVersionChange3.hashCode());
}
@Test
diff --git
a/catalogs/catalog-model/src/main/java/org/apache/gravitino/catalog/model/ModelCatalogOperations.java
b/catalogs/catalog-model/src/main/java/org/apache/gravitino/catalog/model/ModelCatalogOperations.java
index 52172136f6..d89d2d9933 100644
---
a/catalogs/catalog-model/src/main/java/org/apache/gravitino/catalog/model/ModelCatalogOperations.java
+++
b/catalogs/catalog-model/src/main/java/org/apache/gravitino/catalog/model/ModelCatalogOperations.java
@@ -19,7 +19,6 @@
package org.apache.gravitino.catalog.model;
import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
@@ -451,7 +450,7 @@ public class ModelCatalogOperations extends
ManagedSchemaOperations
modelVersionEntity.aliases() == null
? Lists.newArrayList()
: Lists.newArrayList(modelVersionEntity.aliases());
- String entityUri =
modelVersionEntity.uris().get(ModelVersion.URI_NAME_UNKNOWN);
+ Map<String, String> entityUris =
Maps.newHashMap(modelVersionEntity.uris());
Map<String, String> entityProperties =
modelVersionEntity.properties() == null
? Maps.newHashMap()
@@ -474,7 +473,15 @@ public class ModelCatalogOperations extends
ManagedSchemaOperations
} else if (change instanceof ModelVersionChange.UpdateUri) {
ModelVersionChange.UpdateUri updateUriChange =
(ModelVersionChange.UpdateUri) change;
- entityUri = updateUriChange.newUri();
+ doUpdateUri(entityUris, updateUriChange);
+
+ } else if (change instanceof ModelVersionChange.AddUri) {
+ ModelVersionChange.AddUri addUriChange = (ModelVersionChange.AddUri)
change;
+ doAddUri(entityUris, addUriChange);
+
+ } else if (change instanceof ModelVersionChange.RemoveUri) {
+ ModelVersionChange.RemoveUri removeUriChange =
(ModelVersionChange.RemoveUri) change;
+ doRemoveUri(entityUris, removeUriChange);
} else if (change instanceof ModelVersionChange.UpdateAliases) {
ModelVersionChange.UpdateAliases updateAliasesChange =
@@ -493,12 +500,16 @@ public class ModelCatalogOperations extends
ManagedSchemaOperations
}
}
+ if (entityUris.isEmpty()) {
+ throw new IllegalArgumentException("Model version URI cannot be empty");
+ }
+
return ModelVersionEntity.builder()
.withVersion(entityVersion)
.withModelIdentifier(entityModelIdentifier)
.withAliases(entityAliases)
.withComment(entityComment)
- .withUris(ImmutableMap.of(ModelVersion.URI_NAME_UNKNOWN, entityUri))
+ .withUris(entityUris)
.withProperties(entityProperties)
.withAuditInfo(
AuditInfo.builder()
@@ -614,6 +625,18 @@ public class ModelCatalogOperations extends
ManagedSchemaOperations
entityProperties.remove(change.property());
}
+ private void doUpdateUri(Map<String, String> entityUris,
ModelVersionChange.UpdateUri change) {
+ entityUris.replace(change.uriName(), change.newUri());
+ }
+
+ private void doAddUri(Map<String, String> entityUris,
ModelVersionChange.AddUri change) {
+ entityUris.putIfAbsent(change.uriName(), change.uri());
+ }
+
+ private void doRemoveUri(Map<String, String> entityUris,
ModelVersionChange.RemoveUri change) {
+ entityUris.remove(change.uriName());
+ }
+
private void doDeleteAlias(List<String> entityAliases, Set<String>
deleteSet) {
entityAliases.removeAll(deleteSet);
}
diff --git
a/catalogs/catalog-model/src/test/java/org/apache/gravtitino/catalog/model/TestModelCatalogOperations.java
b/catalogs/catalog-model/src/test/java/org/apache/gravtitino/catalog/model/TestModelCatalogOperations.java
index dd3fcb830d..980568f769 100644
---
a/catalogs/catalog-model/src/test/java/org/apache/gravtitino/catalog/model/TestModelCatalogOperations.java
+++
b/catalogs/catalog-model/src/test/java/org/apache/gravtitino/catalog/model/TestModelCatalogOperations.java
@@ -1393,9 +1393,8 @@ public class TestModelCatalogOperations {
String modelComment = "model1 comment";
String versionComment = "version1 comment";
- Map<String, String> versionUris =
ImmutableMap.of(ModelVersion.URI_NAME_UNKNOWN, "uri");
+ Map<String, String> versionUris = ImmutableMap.of("n1", "u1", "n2", "u2");
String[] versionAliases = new String[] {"alias1", "alias2"};
- String newVersionUri = "s3://bucket/path/to/new/version";
NameIdentifier modelIdent =
NameIdentifierUtil.ofModel(METALAKE_NAME, CATALOG_NAME, schemaName,
modelName);
@@ -1424,12 +1423,11 @@ public class TestModelCatalogOperations {
Assertions.assertEquals(versionProperties, loadedVersion.properties());
// validate update version uri
- ModelVersionChange updateUriChange =
ModelVersionChange.updateUri(newVersionUri);
+ ModelVersionChange updateUriChange = ModelVersionChange.updateUri("n1",
"u3");
ModelVersion updatedModelVersion = ops.alterModelVersion(modelIdent, 0,
updateUriChange);
Assertions.assertEquals(0, updatedModelVersion.version());
- Assertions.assertEquals(
- ImmutableMap.of(ModelVersion.URI_NAME_UNKNOWN, newVersionUri),
updatedModelVersion.uris());
+ Assertions.assertEquals(ImmutableMap.of("n1", "u3", "n2", "u2"),
updatedModelVersion.uris());
Assertions.assertEquals(versionComment, updatedModelVersion.comment());
Assertions.assertArrayEquals(versionAliases,
updatedModelVersion.aliases());
Assertions.assertEquals(versionProperties,
updatedModelVersion.properties());
@@ -1487,6 +1485,202 @@ public class TestModelCatalogOperations {
Assertions.assertEquals(versionProperties,
updatedModelVersion.properties());
}
+ @Test
+ void testAddModelVersionUri() {
+ String schemaName = randomSchemaName();
+ createSchema(schemaName);
+
+ String modelName = "model1";
+ String modelComment = "model1 comment";
+
+ String versionComment = "version1 comment";
+ Map<String, String> versionUris = ImmutableMap.of("n1", "u1");
+ String[] versionAliases = new String[] {"alias1", "alias2"};
+
+ NameIdentifier modelIdent =
+ NameIdentifierUtil.ofModel(METALAKE_NAME, CATALOG_NAME, schemaName,
modelName);
+ StringIdentifier stringId = StringIdentifier.fromId(idGenerator.nextId());
+ Map<String, String> properties =
StringIdentifier.newPropertiesWithId(stringId, null);
+
+ ops.registerModel(modelIdent, modelComment, properties);
+ StringIdentifier versionId = StringIdentifier.fromId(idGenerator.nextId());
+ Map<String, String> versionProperties =
+ StringIdentifier.newPropertiesWithId(
+ versionId, ImmutableMap.of("key1", "value1", "key2", "value2"));
+
+ ops.linkModelVersion(
+ modelIdent, versionUris, versionAliases, versionComment,
versionProperties);
+
+ // validate loaded model
+ Model loadedModel = ops.getModel(modelIdent);
+ Assertions.assertEquals(1, loadedModel.latestVersion());
+
+ // validate loaded version
+ ModelVersion loadedVersion = ops.getModelVersion(modelIdent, 0);
+ Assertions.assertEquals(0, loadedVersion.version());
+ Assertions.assertArrayEquals(versionAliases, loadedVersion.aliases());
+ Assertions.assertEquals(versionComment, loadedVersion.comment());
+ Assertions.assertEquals(versionUris, loadedVersion.uris());
+ Assertions.assertEquals(versionProperties, loadedVersion.properties());
+
+ // validate add version uri
+ ModelVersionChange change = ModelVersionChange.addUri("n2", "u2");
+ ModelVersion updatedModelVersion = ops.alterModelVersion(modelIdent, 0,
change);
+
+ Assertions.assertEquals(0, updatedModelVersion.version());
+ Assertions.assertEquals(ImmutableMap.of("n1", "u1", "n2", "u2"),
updatedModelVersion.uris());
+ Assertions.assertEquals(versionComment, updatedModelVersion.comment());
+ Assertions.assertArrayEquals(versionAliases,
updatedModelVersion.aliases());
+ Assertions.assertEquals(versionProperties,
updatedModelVersion.properties());
+ }
+
+ @Test
+ void testAddModelVersionUriByAlias() {
+ String schemaName = randomSchemaName();
+ createSchema(schemaName);
+
+ String modelName = "model1";
+ String modelComment = "model1 comment";
+
+ String versionComment = "version1 comment";
+ Map<String, String> versionUris = ImmutableMap.of("n1", "u1");
+ String[] versionAliases = new String[] {"alias1", "alias2"};
+
+ NameIdentifier modelIdent =
+ NameIdentifierUtil.ofModel(METALAKE_NAME, CATALOG_NAME, schemaName,
modelName);
+ StringIdentifier stringId = StringIdentifier.fromId(idGenerator.nextId());
+ Map<String, String> properties =
StringIdentifier.newPropertiesWithId(stringId, null);
+
+ ops.registerModel(modelIdent, modelComment, properties);
+ StringIdentifier versionId = StringIdentifier.fromId(idGenerator.nextId());
+ Map<String, String> versionProperties =
+ StringIdentifier.newPropertiesWithId(
+ versionId, ImmutableMap.of("key1", "value1", "key2", "value2"));
+
+ ops.linkModelVersion(
+ modelIdent, versionUris, versionAliases, versionComment,
versionProperties);
+
+ // validate loaded model
+ Model loadedModel = ops.getModel(modelIdent);
+ Assertions.assertEquals(1, loadedModel.latestVersion());
+
+ // validate loaded version
+ ModelVersion loadedVersion = ops.getModelVersion(modelIdent,
versionAliases[0]);
+ Assertions.assertEquals(0, loadedVersion.version());
+ Assertions.assertArrayEquals(versionAliases, loadedVersion.aliases());
+ Assertions.assertEquals(versionComment, loadedVersion.comment());
+ Assertions.assertEquals(versionUris, loadedVersion.uris());
+ Assertions.assertEquals(versionProperties, loadedVersion.properties());
+
+ // validate add version uri
+ ModelVersionChange change = ModelVersionChange.addUri("n2", "u2");
+ ModelVersion updatedModelVersion = ops.alterModelVersion(modelIdent,
versionAliases[0], change);
+
+ Assertions.assertEquals(0, updatedModelVersion.version());
+ Assertions.assertEquals(ImmutableMap.of("n1", "u1", "n2", "u2"),
updatedModelVersion.uris());
+ Assertions.assertEquals(versionComment, updatedModelVersion.comment());
+ Assertions.assertArrayEquals(versionAliases,
updatedModelVersion.aliases());
+ Assertions.assertEquals(versionProperties,
updatedModelVersion.properties());
+ }
+
+ @Test
+ void testRemoveModelVersionUri() {
+ String schemaName = randomSchemaName();
+ createSchema(schemaName);
+
+ String modelName = "model1";
+ String modelComment = "model1 comment";
+
+ String versionComment = "version1 comment";
+ Map<String, String> versionUris = ImmutableMap.of("n1", "u1", "n2", "u2");
+ String[] versionAliases = new String[] {"alias1", "alias2"};
+
+ NameIdentifier modelIdent =
+ NameIdentifierUtil.ofModel(METALAKE_NAME, CATALOG_NAME, schemaName,
modelName);
+ StringIdentifier stringId = StringIdentifier.fromId(idGenerator.nextId());
+ Map<String, String> properties =
StringIdentifier.newPropertiesWithId(stringId, null);
+
+ ops.registerModel(modelIdent, modelComment, properties);
+ StringIdentifier versionId = StringIdentifier.fromId(idGenerator.nextId());
+ Map<String, String> versionProperties =
+ StringIdentifier.newPropertiesWithId(
+ versionId, ImmutableMap.of("key1", "value1", "key2", "value2"));
+
+ ops.linkModelVersion(
+ modelIdent, versionUris, versionAliases, versionComment,
versionProperties);
+
+ // validate loaded model
+ Model loadedModel = ops.getModel(modelIdent);
+ Assertions.assertEquals(1, loadedModel.latestVersion());
+
+ // validate loaded version
+ ModelVersion loadedVersion = ops.getModelVersion(modelIdent, 0);
+ Assertions.assertEquals(0, loadedVersion.version());
+ Assertions.assertArrayEquals(versionAliases, loadedVersion.aliases());
+ Assertions.assertEquals(versionComment, loadedVersion.comment());
+ Assertions.assertEquals(versionUris, loadedVersion.uris());
+ Assertions.assertEquals(versionProperties, loadedVersion.properties());
+
+ // validate remove version uri
+ ModelVersionChange change = ModelVersionChange.removeUri("n1");
+ ModelVersion updatedModelVersion = ops.alterModelVersion(modelIdent, 0,
change);
+
+ Assertions.assertEquals(0, updatedModelVersion.version());
+ Assertions.assertEquals(ImmutableMap.of("n2", "u2"),
updatedModelVersion.uris());
+ Assertions.assertEquals(versionComment, updatedModelVersion.comment());
+ Assertions.assertArrayEquals(versionAliases,
updatedModelVersion.aliases());
+ Assertions.assertEquals(versionProperties,
updatedModelVersion.properties());
+ }
+
+ @Test
+ void testRemoveModelVersionUriByAlias() {
+ String schemaName = randomSchemaName();
+ createSchema(schemaName);
+
+ String modelName = "model1";
+ String modelComment = "model1 comment";
+
+ String versionComment = "version1 comment";
+ Map<String, String> versionUris = ImmutableMap.of("n1", "u1", "n2", "u2");
+ String[] versionAliases = new String[] {"alias1", "alias2"};
+
+ NameIdentifier modelIdent =
+ NameIdentifierUtil.ofModel(METALAKE_NAME, CATALOG_NAME, schemaName,
modelName);
+ StringIdentifier stringId = StringIdentifier.fromId(idGenerator.nextId());
+ Map<String, String> properties =
StringIdentifier.newPropertiesWithId(stringId, null);
+
+ ops.registerModel(modelIdent, modelComment, properties);
+ StringIdentifier versionId = StringIdentifier.fromId(idGenerator.nextId());
+ Map<String, String> versionProperties =
+ StringIdentifier.newPropertiesWithId(
+ versionId, ImmutableMap.of("key1", "value1", "key2", "value2"));
+
+ ops.linkModelVersion(
+ modelIdent, versionUris, versionAliases, versionComment,
versionProperties);
+
+ // validate loaded model
+ Model loadedModel = ops.getModel(modelIdent);
+ Assertions.assertEquals(1, loadedModel.latestVersion());
+
+ // validate loaded version
+ ModelVersion loadedVersion = ops.getModelVersion(modelIdent,
versionAliases[0]);
+ Assertions.assertEquals(0, loadedVersion.version());
+ Assertions.assertArrayEquals(versionAliases, loadedVersion.aliases());
+ Assertions.assertEquals(versionComment, loadedVersion.comment());
+ Assertions.assertEquals(versionUris, loadedVersion.uris());
+ Assertions.assertEquals(versionProperties, loadedVersion.properties());
+
+ // validate remove version uri
+ ModelVersionChange change = ModelVersionChange.removeUri("n2");
+ ModelVersion updatedModelVersion = ops.alterModelVersion(modelIdent,
versionAliases[0], change);
+
+ Assertions.assertEquals(0, updatedModelVersion.version());
+ Assertions.assertEquals(ImmutableMap.of("n1", "u1"),
updatedModelVersion.uris());
+ Assertions.assertEquals(versionComment, updatedModelVersion.comment());
+ Assertions.assertArrayEquals(versionAliases,
updatedModelVersion.aliases());
+ Assertions.assertEquals(versionProperties,
updatedModelVersion.properties());
+ }
+
@Test
void testUpdateModelAlias() {
String schemaName = randomSchemaName();
diff --git
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/ModelVersionMetaMapper.java
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/ModelVersionMetaMapper.java
index ccf6ea48d4..591f232c8b 100644
---
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/ModelVersionMetaMapper.java
+++
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/ModelVersionMetaMapper.java
@@ -19,7 +19,6 @@
package org.apache.gravitino.storage.relational.mapper;
import java.util.List;
-import java.util.Map;
import org.apache.gravitino.storage.relational.po.ModelVersionPO;
import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.annotations.InsertProvider;
@@ -36,6 +35,12 @@ public interface ModelVersionMetaMapper {
method = "insertModelVersionMetas")
void insertModelVersionMetas(@Param("modelVersionMetas")
List<ModelVersionPO> modelVersionPOs);
+ @InsertProvider(
+ type = ModelVersionMetaSQLProviderFactory.class,
+ method = "insertModelVersionMetasWithVersionNumber")
+ void insertModelVersionMetasWithVersionNumber(
+ @Param("modelVersionMetas") List<ModelVersionPO> modelVersionPOs);
+
@SelectProvider(
type = ModelVersionMetaSQLProviderFactory.class,
method = "listModelVersionMetasByModelId")
@@ -98,12 +103,4 @@ public interface ModelVersionMetaMapper {
Integer updateModelVersionMeta(
@Param("newModelVersionMeta") ModelVersionPO newModelVersionPO,
@Param("oldModelVersionMeta") ModelVersionPO oldModelVersionPO);
-
- @UpdateProvider(
- type = ModelVersionMetaSQLProviderFactory.class,
- method = "updateModelVersionUris")
- Integer updateModelVersionUris(
- @Param("modelId") Long modelId,
- @Param("modelVersion") Integer modelVersion,
- @Param("uris") Map<String, String> uris);
}
diff --git
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/ModelVersionMetaSQLProviderFactory.java
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/ModelVersionMetaSQLProviderFactory.java
index f0dce961b7..5e1a9e3308 100644
---
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/ModelVersionMetaSQLProviderFactory.java
+++
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/ModelVersionMetaSQLProviderFactory.java
@@ -56,6 +56,11 @@ public class ModelVersionMetaSQLProviderFactory {
return getProvider().insertModelVersionMetas(modelVersionPOs);
}
+ public static String insertModelVersionMetasWithVersionNumber(
+ @Param("modelVersionMetas") List<ModelVersionPO> modelVersionPOs) {
+ return
getProvider().insertModelVersionMetasWithVersionNumber(modelVersionPOs);
+ }
+
public static String listModelVersionMetasByModelId(@Param("modelId") Long
modelId) {
return getProvider().listModelVersionMetasByModelId(modelId);
}
@@ -108,11 +113,4 @@ public class ModelVersionMetaSQLProviderFactory {
@Param("oldModelVersionMeta") ModelVersionPO oldModelVersionPO) {
return getProvider().updateModelVersionMeta(newModelVersionPO,
oldModelVersionPO);
}
-
- public static String updateModelVersionUris(
- @Param("modelId") Long modelId,
- @Param("modelVersion") Integer modelVersion,
- @Param("uris") Map<String, String> uris) {
- return getProvider().updateModelVersionUris(modelId, modelVersion, uris);
- }
}
diff --git
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/ModelVersionMetaBaseSQLProvider.java
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/ModelVersionMetaBaseSQLProvider.java
index 7baf7bb3ac..09bce00eed 100644
---
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/ModelVersionMetaBaseSQLProvider.java
+++
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/ModelVersionMetaBaseSQLProvider.java
@@ -19,7 +19,6 @@
package org.apache.gravitino.storage.relational.mapper.provider.base;
import java.util.List;
-import java.util.Map;
import org.apache.gravitino.storage.relational.mapper.ModelMetaMapper;
import
org.apache.gravitino.storage.relational.mapper.ModelVersionAliasRelMapper;
import org.apache.gravitino.storage.relational.mapper.ModelVersionMetaMapper;
@@ -55,6 +54,33 @@ public class ModelVersionMetaBaseSQLProvider {
+ "</script>";
}
+ public String insertModelVersionMetasWithVersionNumber(
+ @Param("modelVersionMetas") List<ModelVersionPO> modelVersionPOs) {
+ return "<script>"
+ + "INSERT INTO "
+ + ModelVersionMetaMapper.TABLE_NAME
+ + "(metalake_id, catalog_id, schema_id, model_id, version,
model_version_comment,"
+ + " model_version_properties, model_version_uri_name,
model_version_uri, audit_info, deleted_at)"
+ + " SELECT m.metalake_id, m.catalog_id, m.schema_id, m.model_id,
v.model_version_number, v.model_version_comment,"
+ + " v.model_version_properties, v.model_version_uri_name,
v.model_version_uri, v.audit_info, v.deleted_at"
+ + " FROM ("
+ + "<foreach collection='modelVersionMetas' item='version'
separator='UNION ALL'>"
+ + " SELECT"
+ + " #{version.modelId} AS model_id, #{version.modelVersionComment} AS
model_version_comment,"
+ + " #{version.modelVersionProperties} AS model_version_properties,
#{version.auditInfo} AS audit_info,"
+ + " #{version.deletedAt} AS deleted_at, #{version.modelVersionUriName}
AS model_version_uri_name,"
+ + " #{version.modelVersionUri} AS model_version_uri,
#{version.modelVersion} AS model_version_number "
+ + "</foreach>"
+ + " ) v"
+ + " JOIN"
+ + " (SELECT metalake_id, catalog_id, schema_id, model_id"
+ + " FROM "
+ + ModelMetaMapper.TABLE_NAME
+ + " WHERE model_id = #{modelVersionMetas[0].modelId} AND deleted_at =
0) m"
+ + " ON v.model_id = m.model_id"
+ + "</script>";
+ }
+
public String listModelVersionMetasByModelId(@Param("modelId") Long modelId)
{
return "SELECT metalake_id AS metalakeId, catalog_id AS catalogId,
schema_id AS schemaId,"
+ " model_id AS modelId, version AS modelVersion,
model_version_comment AS modelVersionComment,"
@@ -185,21 +211,4 @@ public class ModelVersionMetaBaseSQLProvider {
+ "AND audit_info = #{oldModelVersionMeta.auditInfo} "
+ "AND deleted_at = 0";
}
-
- public String updateModelVersionUris(
- @Param("modelId") Long modelId,
- @Param("modelVersion") Integer modelVersion,
- @Param("uris") Map<String, String> uris) {
- return "<script>"
- + "UPDATE "
- + ModelVersionMetaMapper.TABLE_NAME
- + " SET"
- + " model_version_uri = CASE"
- + "<foreach collection='uris' index='k' item='v' separator=''>"
- + " WHEN model_version_uri_name = #{k} THEN #{v}"
- + "</foreach>"
- + " ELSE model_version_uri END"
- + " WHERE model_id = #{modelId} AND version = #{modelVersion} AND
deleted_at = 0"
- + "</script>";
- }
}
diff --git
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/h2/ModelVersionMetaH2Provider.java
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/h2/ModelVersionMetaH2Provider.java
index 81d33e435e..13f8cff362 100644
---
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/h2/ModelVersionMetaH2Provider.java
+++
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/h2/ModelVersionMetaH2Provider.java
@@ -54,4 +54,32 @@ public class ModelVersionMetaH2Provider extends
ModelVersionMetaBaseSQLProvider
+ " ON v.model_id = m.model_id"
+ "</script>";
}
+
+ @Override
+ public String insertModelVersionMetasWithVersionNumber(
+ @Param("modelVersionMetas") List<ModelVersionPO> modelVersionPOs) {
+ return "<script>"
+ + "INSERT INTO "
+ + ModelVersionMetaMapper.TABLE_NAME
+ + "(metalake_id, catalog_id, schema_id, model_id, version,
model_version_comment,"
+ + " model_version_properties, model_version_uri_name,
model_version_uri, audit_info, deleted_at)"
+ + " SELECT m.metalake_id, m.catalog_id, m.schema_id, m.model_id,
v.model_version_number, v.model_version_comment,"
+ + " v.model_version_properties, v.model_version_uri_name,
v.model_version_uri, v.audit_info, v.deleted_at"
+ + " FROM ("
+ + "<foreach collection='modelVersionMetas' item='version'
separator='UNION ALL'>"
+ + " SELECT"
+ + " CAST(#{version.modelId} AS BIGINT) AS model_id,
CAST(#{version.modelVersionComment} AS TEXT) AS model_version_comment,"
+ + " CAST(#{version.modelVersionProperties} AS MEDIUMTEXT) AS
model_version_properties, CAST(#{version.auditInfo} AS MEDIUMTEXT) AS
audit_info,"
+ + " CAST(#{version.deletedAt} AS BIGINT) AS deleted_at,
CAST(#{version.modelVersionUriName} AS VARCHAR(128)) AS model_version_uri_name,"
+ + " CAST(#{version.modelVersionUri} AS TEXT) AS model_version_uri,
CAST(#{version.modelVersion} AS INT) AS model_version_number "
+ + "</foreach>"
+ + " ) v"
+ + " JOIN"
+ + " (SELECT metalake_id, catalog_id, schema_id, model_id"
+ + " FROM "
+ + ModelMetaMapper.TABLE_NAME
+ + " WHERE model_id = #{modelVersionMetas[0].modelId} AND deleted_at =
0) m"
+ + " ON v.model_id = m.model_id"
+ + "</script>";
+ }
}
diff --git
a/core/src/main/java/org/apache/gravitino/storage/relational/service/ModelVersionMetaService.java
b/core/src/main/java/org/apache/gravitino/storage/relational/service/ModelVersionMetaService.java
index cadd262059..085ae844dd 100644
---
a/core/src/main/java/org/apache/gravitino/storage/relational/service/ModelVersionMetaService.java
+++
b/core/src/main/java/org/apache/gravitino/storage/relational/service/ModelVersionMetaService.java
@@ -21,7 +21,6 @@ package org.apache.gravitino.storage.relational.service;
import com.google.common.base.Preconditions;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import java.io.IOException;
@@ -41,7 +40,6 @@ import org.apache.gravitino.Namespace;
import org.apache.gravitino.exceptions.NoSuchEntityException;
import org.apache.gravitino.meta.ModelEntity;
import org.apache.gravitino.meta.ModelVersionEntity;
-import org.apache.gravitino.model.ModelVersion;
import org.apache.gravitino.storage.relational.mapper.ModelMetaMapper;
import
org.apache.gravitino.storage.relational.mapper.ModelVersionAliasRelMapper;
import org.apache.gravitino.storage.relational.mapper.ModelVersionMetaMapper;
@@ -326,10 +324,36 @@ public class ModelVersionMetaService {
List<ModelVersionAliasRelPO> newAliasRelPOs =
POConverters.updateModelVersionAliasRelPO(oldAliasRelPOs,
newModelVersionEntity);
+ boolean isModelVersionUriUpdated =
+ isModelVersionUriUpdated(oldModelVersionEntity, newModelVersionEntity);
+
final AtomicInteger updateResult = new AtomicInteger(0);
try {
SessionUtils.doMultipleWithCommit(
- () ->
+ () -> {
+ if (isModelVersionUriUpdated) {
+ // delete old model version POs first
+ updateResult.addAndGet(
+ SessionUtils.doWithoutCommitAndFetchResult(
+ ModelVersionMetaMapper.class,
+ mapper -> {
+ if (isVersionNumber) {
+ return
mapper.softDeleteModelVersionMetaByModelIdAndVersion(
+ modelEntity.id(), Integer.valueOf(ident.name()));
+ } else {
+ return
mapper.softDeleteModelVersionMetaByModelIdAndAlias(
+ modelEntity.id(), ident.name());
+ }
+ }));
+
+ // insert model version POs with updated URIs
+ List<ModelVersionPO> modelVersionPOs =
+ POConverters.initializeModelVersionPO(newModelVersionEntity,
modelEntity.id());
+ SessionUtils.doWithoutCommit(
+ ModelVersionMetaMapper.class,
+ mapper ->
mapper.insertModelVersionMetasWithVersionNumber(modelVersionPOs));
+ } else {
+ // update model version POs directly
updateResult.addAndGet(
SessionUtils.doWithoutCommitAndFetchResult(
ModelVersionMetaMapper.class,
@@ -337,25 +361,9 @@ public class ModelVersionMetaService {
mapper.updateModelVersionMeta(
POConverters.updateModelVersionPO(
oldModelVersionPOs.get(0),
newModelVersionEntity),
- oldModelVersionPOs.get(0)))),
- () ->
- oldModelVersionPOs.stream()
- .filter(v -> isModelVersionUriUpdated(v,
newModelVersionEntity.uris()))
- .findAny()
- .ifPresent(
- v ->
- updateResult.addAndGet(
- SessionUtils.doWithoutCommitAndFetchResult(
- ModelVersionMetaMapper.class,
- mapper ->
- mapper.updateModelVersionUris(
- v.getModelId(),
- v.getModelVersion(),
- ImmutableMap.of(
- ModelVersion.URI_NAME_UNKNOWN,
- newModelVersionEntity
- .uris()
-
.get(ModelVersion.URI_NAME_UNKNOWN)))))),
+ oldModelVersionPOs.get(0))));
+ }
+ },
() -> {
if (isAliasChanged) {
SessionUtils.doWithoutCommit(
@@ -399,13 +407,10 @@ public class ModelVersionMetaService {
return !oldAliases.equals(newAliases);
}
- // TODO Only modifying the unknown URI is supported currently.
private boolean isModelVersionUriUpdated(
- ModelVersionPO oldModelVersionPO, Map<String, String>
newModelVersionUris) {
- return
ModelVersion.URI_NAME_UNKNOWN.equals(oldModelVersionPO.getModelVersionUriName())
- && newModelVersionUris.containsKey(ModelVersion.URI_NAME_UNKNOWN)
- && !oldModelVersionPO
- .getModelVersionUri()
- .equals(newModelVersionUris.get(ModelVersion.URI_NAME_UNKNOWN));
+ ModelVersionEntity oldModelVersionEntity, ModelVersionEntity
newModelVersionEntity) {
+ Map<String, String> oldUris = oldModelVersionEntity.uris();
+ Map<String, String> newUris = newModelVersionEntity.uris();
+ return !oldUris.equals(newUris);
}
}
diff --git
a/core/src/main/java/org/apache/gravitino/storage/relational/utils/POConverters.java
b/core/src/main/java/org/apache/gravitino/storage/relational/utils/POConverters.java
index 7d00cbd947..28d0388745 100644
---
a/core/src/main/java/org/apache/gravitino/storage/relational/utils/POConverters.java
+++
b/core/src/main/java/org/apache/gravitino/storage/relational/utils/POConverters.java
@@ -1617,11 +1617,10 @@ public class POConverters {
.withMetalakeId(oldModelVersionPO.getMetalakeId())
.withCatalogId(oldModelVersionPO.getCatalogId())
.withSchemaId(oldModelVersionPO.getSchemaId())
- // TODO The modelVersionUriName and modelVersionUri here are not
actually used.
- // They are only used for occupying positions to avoid verification
failures. They will
- // be removed when the model version with multiple URIs is supported
to be modified later
- .withModelVersionUriName("uriName")
- .withModelVersionUri("uri")
+ // The modelVersionUriName and modelVersionUri here are not actually
used.
+ // They are only used for occupying positions to avoid verification
failures.
+ .withModelVersionUriName(oldModelVersionPO.getModelVersionUriName())
+ .withModelVersionUri(oldModelVersionPO.getModelVersionUri())
.withModelVersion(oldModelVersionPO.getModelVersion())
.withModelVersionComment(newModelVersion.comment())
.withModelVersionProperties(
diff --git
a/core/src/test/java/org/apache/gravitino/catalog/TestModelOperationDispatcher.java
b/core/src/test/java/org/apache/gravitino/catalog/TestModelOperationDispatcher.java
index bbfd791096..c9f2cb069a 100644
---
a/core/src/test/java/org/apache/gravitino/catalog/TestModelOperationDispatcher.java
+++
b/core/src/test/java/org/apache/gravitino/catalog/TestModelOperationDispatcher.java
@@ -774,9 +774,8 @@ public class TestModelOperationDispatcher extends
TestOperationDispatcher {
String modelName = randomModelName();
String modelComment = "model which tests update";
Map<String, String> props = ImmutableMap.of("k1", "v1", "k2", "v2");
- String newUri = "s3://new-bucket/new-path/new-model.json";
- Map<String, String> versionUris =
ImmutableMap.of(ModelVersion.URI_NAME_UNKNOWN, "uri");
+ Map<String, String> versionUris = ImmutableMap.of("n1", "u1");
String[] versionAliases = {"alias1", "alias2"};
String versionComment = "version which tests update";
@@ -790,12 +789,14 @@ public class TestModelOperationDispatcher extends
TestOperationDispatcher {
modelOperationDispatcher.linkModelVersion(
modelIdent, versionUris, versionAliases, versionComment, props);
- ModelVersionChange change = ModelVersionChange.updateUri(newUri);
+ String newUri = "u2";
+ Map<String, String> newVersionUris = ImmutableMap.of("n1", newUri);
+ ModelVersionChange change = ModelVersionChange.updateUri("n1", newUri);
ModelVersion modelVersion =
modelOperationDispatcher.getModelVersion(modelIdent, 0);
ModelVersion alteredModelVersion =
modelOperationDispatcher.alterModelVersion(modelIdent, 0, change);
- Assertions.assertEquals(newUri, alteredModelVersion.uri());
+ Assertions.assertEquals(newVersionUris, alteredModelVersion.uris());
Assertions.assertEquals(modelVersion.version(),
alteredModelVersion.version());
Assertions.assertEquals(modelVersion.aliases(),
alteredModelVersion.aliases());
Assertions.assertEquals(modelVersion.comment(),
alteredModelVersion.comment());
@@ -810,9 +811,159 @@ public class TestModelOperationDispatcher extends
TestOperationDispatcher {
String modelName = randomModelName();
String modelComment = "model which tests update";
Map<String, String> props = ImmutableMap.of("k1", "v1", "k2", "v2");
- String newUri = "s3://new-bucket/new-path/new-model.json";
- Map<String, String> versionUris =
ImmutableMap.of(ModelVersion.URI_NAME_UNKNOWN, "uri");
+ Map<String, String> versionUris = ImmutableMap.of("n1", "u1");
+ String[] versionAliases = {"alias1", "alias2"};
+ String versionComment = "version which tests update";
+
+ NameIdentifier schemaIdent = NameIdentifier.of(metalake, catalog,
schemaName);
+ schemaOperationDispatcher.createSchema(schemaIdent, schemaComment, props);
+
+ NameIdentifier modelIdent =
+ NameIdentifierUtil.ofModel(metalake, catalog, schemaName, modelName);
+ modelOperationDispatcher.registerModel(modelIdent, modelComment, props);
+
+ modelOperationDispatcher.linkModelVersion(
+ modelIdent, versionUris, versionAliases, versionComment, props);
+
+ String newUri = "u2";
+ Map<String, String> newVersionUris = ImmutableMap.of("n1", newUri);
+ ModelVersionChange change = ModelVersionChange.updateUri("n1", newUri);
+ ModelVersion modelVersion =
+ modelOperationDispatcher.getModelVersion(modelIdent,
versionAliases[0]);
+ ModelVersion alteredModelVersion =
+ modelOperationDispatcher.alterModelVersion(modelIdent,
versionAliases[0], change);
+
+ Assertions.assertEquals(newVersionUris, alteredModelVersion.uris());
+ Assertions.assertEquals(modelVersion.version(),
alteredModelVersion.version());
+ Assertions.assertEquals(modelVersion.aliases(),
alteredModelVersion.aliases());
+ Assertions.assertEquals(modelVersion.comment(),
alteredModelVersion.comment());
+ Assertions.assertEquals(modelVersion.properties(),
alteredModelVersion.properties());
+ }
+
+ @Test
+ void testAddModelVersionUri() {
+ String schemaName = randomSchemaName();
+ String schemaComment = "schema which tests update";
+
+ String modelName = randomModelName();
+ String modelComment = "model which tests update";
+ Map<String, String> props = ImmutableMap.of("k1", "v1", "k2", "v2");
+
+ Map<String, String> versionUris = ImmutableMap.of("n1", "u1");
+ String[] versionAliases = {"alias1", "alias2"};
+ String versionComment = "version which tests update";
+
+ NameIdentifier schemaIdent = NameIdentifier.of(metalake, catalog,
schemaName);
+ schemaOperationDispatcher.createSchema(schemaIdent, schemaComment, props);
+
+ NameIdentifier modelIdent =
+ NameIdentifierUtil.ofModel(metalake, catalog, schemaName, modelName);
+ modelOperationDispatcher.registerModel(modelIdent, modelComment, props);
+
+ modelOperationDispatcher.linkModelVersion(
+ modelIdent, versionUris, versionAliases, versionComment, props);
+
+ String newUriName = "n2";
+ String newUri = "u2";
+ Map<String, String> newVersionUris = ImmutableMap.of("n1", "u1", "n2",
"u2");
+ ModelVersionChange change = ModelVersionChange.addUri(newUriName, newUri);
+ ModelVersion modelVersion =
modelOperationDispatcher.getModelVersion(modelIdent, 0);
+ ModelVersion alteredModelVersion =
+ modelOperationDispatcher.alterModelVersion(modelIdent, 0, change);
+
+ Assertions.assertEquals(newVersionUris, alteredModelVersion.uris());
+ Assertions.assertEquals(modelVersion.version(),
alteredModelVersion.version());
+ Assertions.assertEquals(modelVersion.aliases(),
alteredModelVersion.aliases());
+ Assertions.assertEquals(modelVersion.comment(),
alteredModelVersion.comment());
+ Assertions.assertEquals(modelVersion.properties(),
alteredModelVersion.properties());
+ }
+
+ @Test
+ void testAddModelVersionUriByAlias() {
+ String schemaName = randomSchemaName();
+ String schemaComment = "schema which tests update";
+
+ String modelName = randomModelName();
+ String modelComment = "model which tests update";
+ Map<String, String> props = ImmutableMap.of("k1", "v1", "k2", "v2");
+
+ Map<String, String> versionUris = ImmutableMap.of("n1", "u1");
+ String[] versionAliases = {"alias1", "alias2"};
+ String versionComment = "version which tests update";
+
+ NameIdentifier schemaIdent = NameIdentifier.of(metalake, catalog,
schemaName);
+ schemaOperationDispatcher.createSchema(schemaIdent, schemaComment, props);
+
+ NameIdentifier modelIdent =
+ NameIdentifierUtil.ofModel(metalake, catalog, schemaName, modelName);
+ modelOperationDispatcher.registerModel(modelIdent, modelComment, props);
+
+ modelOperationDispatcher.linkModelVersion(
+ modelIdent, versionUris, versionAliases, versionComment, props);
+
+ String newUriName = "n2";
+ String newUri = "u2";
+ Map<String, String> newVersionUris = ImmutableMap.of("n1", "u1", "n2",
"u2");
+ ModelVersionChange change = ModelVersionChange.addUri(newUriName, newUri);
+ ModelVersion modelVersion =
+ modelOperationDispatcher.getModelVersion(modelIdent,
versionAliases[0]);
+ ModelVersion alteredModelVersion =
+ modelOperationDispatcher.alterModelVersion(modelIdent,
versionAliases[0], change);
+
+ Assertions.assertEquals(newVersionUris, alteredModelVersion.uris());
+ Assertions.assertEquals(modelVersion.version(),
alteredModelVersion.version());
+ Assertions.assertEquals(modelVersion.aliases(),
alteredModelVersion.aliases());
+ Assertions.assertEquals(modelVersion.comment(),
alteredModelVersion.comment());
+ Assertions.assertEquals(modelVersion.properties(),
alteredModelVersion.properties());
+ }
+
+ @Test
+ void testRemoveModelVersionUri() {
+ String schemaName = randomSchemaName();
+ String schemaComment = "schema which tests update";
+
+ String modelName = randomModelName();
+ String modelComment = "model which tests update";
+ Map<String, String> props = ImmutableMap.of("k1", "v1", "k2", "v2");
+
+ Map<String, String> versionUris = ImmutableMap.of("n1", "u1", "n2", "u2");
+ String[] versionAliases = {"alias1", "alias2"};
+ String versionComment = "version which tests update";
+
+ NameIdentifier schemaIdent = NameIdentifier.of(metalake, catalog,
schemaName);
+ schemaOperationDispatcher.createSchema(schemaIdent, schemaComment, props);
+
+ NameIdentifier modelIdent =
+ NameIdentifierUtil.ofModel(metalake, catalog, schemaName, modelName);
+ modelOperationDispatcher.registerModel(modelIdent, modelComment, props);
+
+ modelOperationDispatcher.linkModelVersion(
+ modelIdent, versionUris, versionAliases, versionComment, props);
+
+ Map<String, String> newVersionUris = ImmutableMap.of("n2", "u2");
+ ModelVersionChange change = ModelVersionChange.removeUri("n1");
+ ModelVersion modelVersion =
modelOperationDispatcher.getModelVersion(modelIdent, 0);
+ ModelVersion alteredModelVersion =
+ modelOperationDispatcher.alterModelVersion(modelIdent, 0, change);
+
+ Assertions.assertEquals(newVersionUris, alteredModelVersion.uris());
+ Assertions.assertEquals(modelVersion.version(),
alteredModelVersion.version());
+ Assertions.assertEquals(modelVersion.aliases(),
alteredModelVersion.aliases());
+ Assertions.assertEquals(modelVersion.comment(),
alteredModelVersion.comment());
+ Assertions.assertEquals(modelVersion.properties(),
alteredModelVersion.properties());
+ }
+
+ @Test
+ void testRemoveModelVersionUriByAlias() {
+ String schemaName = randomSchemaName();
+ String schemaComment = "schema which tests update";
+
+ String modelName = randomModelName();
+ String modelComment = "model which tests update";
+ Map<String, String> props = ImmutableMap.of("k1", "v1", "k2", "v2");
+
+ Map<String, String> versionUris = ImmutableMap.of("n1", "u1", "n2", "u2");
String[] versionAliases = {"alias1", "alias2"};
String versionComment = "version which tests update";
@@ -826,13 +977,14 @@ public class TestModelOperationDispatcher extends
TestOperationDispatcher {
modelOperationDispatcher.linkModelVersion(
modelIdent, versionUris, versionAliases, versionComment, props);
- ModelVersionChange change = ModelVersionChange.updateUri(newUri);
+ Map<String, String> newVersionUris = ImmutableMap.of("n2", "u2");
+ ModelVersionChange change = ModelVersionChange.removeUri("n1");
ModelVersion modelVersion =
modelOperationDispatcher.getModelVersion(modelIdent,
versionAliases[0]);
ModelVersion alteredModelVersion =
modelOperationDispatcher.alterModelVersion(modelIdent,
versionAliases[0], change);
- Assertions.assertEquals(newUri, alteredModelVersion.uri());
+ Assertions.assertEquals(newVersionUris, alteredModelVersion.uris());
Assertions.assertEquals(modelVersion.version(),
alteredModelVersion.version());
Assertions.assertEquals(modelVersion.aliases(),
alteredModelVersion.aliases());
Assertions.assertEquals(modelVersion.comment(),
alteredModelVersion.comment());
diff --git
a/core/src/test/java/org/apache/gravitino/connector/TestCatalogOperations.java
b/core/src/test/java/org/apache/gravitino/connector/TestCatalogOperations.java
index 61cdef1f1d..10b6bc123c 100644
---
a/core/src/test/java/org/apache/gravitino/connector/TestCatalogOperations.java
+++
b/core/src/test/java/org/apache/gravitino/connector/TestCatalogOperations.java
@@ -1133,7 +1133,7 @@ public class TestCatalogOperations
String newComment = testModelVersion.comment();
int newVersion = testModelVersion.version();
String[] newAliases = testModelVersion.aliases();
- String newUri = testModelVersion.uri();
+ Map<String, String> newUris = Maps.newHashMap(testModelVersion.uris());
for (ModelVersionChange change : changes) {
if (change instanceof ModelVersionChange.UpdateComment) {
@@ -1162,20 +1162,32 @@ public class TestCatalogOperations
} else if (change instanceof ModelVersionChange.UpdateUri) {
ModelVersionChange.UpdateUri updateUriChange =
(ModelVersionChange.UpdateUri) change;
- newUri = updateUriChange.newUri();
+ newUris.replace(updateUriChange.uriName(), updateUriChange.newUri());
+
+ } else if (change instanceof ModelVersionChange.AddUri) {
+ ModelVersionChange.AddUri addUriChange = (ModelVersionChange.AddUri)
change;
+ newUris.putIfAbsent(addUriChange.uriName(), addUriChange.uri());
+
+ } else if (change instanceof ModelVersionChange.RemoveUri) {
+ ModelVersionChange.RemoveUri removeUriChange =
(ModelVersionChange.RemoveUri) change;
+ newUris.remove(removeUriChange.uriName());
} else {
throw new IllegalArgumentException("Unsupported model version change:
" + change);
}
}
+ if (newUris.isEmpty()) {
+ throw new IllegalArgumentException("Model version URI cannot be empty");
+ }
+
TestModelVersion updatedModelVersion =
TestModelVersion.builder()
.withVersion(newVersion)
.withComment(newComment)
.withProperties(newProps)
.withAuditInfo(updatedAuditInfo)
- .withUris(ImmutableMap.of(ModelVersion.URI_NAME_UNKNOWN, newUri))
+ .withUris(newUris)
.withAliases(newAliases)
.build();
diff --git
a/core/src/test/java/org/apache/gravitino/storage/relational/service/TestModelVersionMetaService.java
b/core/src/test/java/org/apache/gravitino/storage/relational/service/TestModelVersionMetaService.java
index b0e2c1a866..3d59e8591a 100644
---
a/core/src/test/java/org/apache/gravitino/storage/relational/service/TestModelVersionMetaService.java
+++
b/core/src/test/java/org/apache/gravitino/storage/relational/service/TestModelVersionMetaService.java
@@ -753,10 +753,9 @@ public class TestModelVersionMetaService extends
TestJDBCBackend {
Map<String, String> properties = ImmutableMap.of("k1", "v1", "k2", "v2");
String modelName = randomModelName();
String modelComment = "model1 comment";
- String modelVersionUri = "S3://test/path/to/model/version";
+ Map<String, String> modelVersionUris = ImmutableMap.of("n1", "u1");
List<String> modelVersionAliases = ImmutableList.of("alias1", "alias2");
String modelVersionComment = "test comment";
- String updatedUri = "S3://test/path/to/new/model/version";
int version = 0;
ModelEntity modelEntity =
@@ -773,17 +772,18 @@ public class TestModelVersionMetaService extends
TestJDBCBackend {
createModelVersionEntity(
modelEntity.nameIdentifier(),
version,
- ImmutableMap.of(ModelVersion.URI_NAME_UNKNOWN, modelVersionUri),
+ modelVersionUris,
modelVersionAliases,
modelVersionComment,
properties,
auditInfo);
+ Map<String, String> newModelVersionUris = ImmutableMap.of("n1", "u1-1",
"n2", "u2");
ModelVersionEntity updatedModelVersionEntity =
createModelVersionEntity(
modelVersionEntity.modelIdentifier(),
modelVersionEntity.version(),
- ImmutableMap.of(ModelVersion.URI_NAME_UNKNOWN, updatedUri),
+ newModelVersionUris,
modelVersionEntity.aliases(),
modelVersionEntity.comment(),
modelVersionEntity.properties(),