This is an automated email from the ASF dual-hosted git repository.
yuqi1129 pushed a commit to branch branch-1.3
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/branch-1.3 by this push:
new 59e64ba914 [Cherry-pick to branch-1.3] [#13035] fix(core): Add
PostgreSQL group-role batch upsert (#13037) (#13061)
59e64ba914 is described below
commit 59e64ba914396054b552455c85c624b53bd5097a
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Thu Sep 10 20:13:07 2026 +0800
[Cherry-pick to branch-1.3] [#13035] fix(core): Add PostgreSQL group-role
batch upsert (#13037) (#13061)
**Cherry-pick Information:**
- Original commit: 56aedb27f1f46089951a36be136ee18263e46b35
- Target branch: `branch-1.3`
- Status: ✅ Clean cherry-pick (no conflicts)
Co-authored-by: Qi Yu <[email protected]>
Co-authored-by: Jerry Shao <[email protected]>
---
.../postgresql/GroupRoleRelPostgreSQLProvider.java | 34 +++++++++++++
.../TestGroupRoleRelPostgreSQLProvider.java | 58 ++++++++++++++++++++++
2 files changed, 92 insertions(+)
diff --git
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/postgresql/GroupRoleRelPostgreSQLProvider.java
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/postgresql/GroupRoleRelPostgreSQLProvider.java
index 2ab7d9f5c0..29058dbd8d 100644
---
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/postgresql/GroupRoleRelPostgreSQLProvider.java
+++
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/postgresql/GroupRoleRelPostgreSQLProvider.java
@@ -23,6 +23,7 @@ import static
org.apache.gravitino.storage.relational.mapper.GroupRoleRelMapper.
import java.util.List;
import
org.apache.gravitino.storage.relational.mapper.provider.base.GroupRoleRelBaseSQLProvider;
+import org.apache.gravitino.storage.relational.po.GroupRoleRelPO;
import org.apache.ibatis.annotations.Param;
public class GroupRoleRelPostgreSQLProvider extends
GroupRoleRelBaseSQLProvider {
@@ -76,6 +77,39 @@ public class GroupRoleRelPostgreSQLProvider extends
GroupRoleRelBaseSQLProvider
+ " WHERE role_id = #{roleId} AND deleted_at = 0";
}
+ /**
+ * Builds a PostgreSQL batch upsert for group-role relations.
+ *
+ * @param groupRoleRelPOs the group-role relations to insert or update
+ * @return the MyBatis SQL script
+ */
+ @Override
+ public String
batchInsertGroupRoleRelOnDuplicateKeyUpdate(List<GroupRoleRelPO>
groupRoleRelPOs) {
+ return "<script>"
+ + "INSERT INTO "
+ + GROUP_ROLE_RELATION_TABLE_NAME
+ + " (group_id, role_id,"
+ + " audit_info,"
+ + " current_version, last_version, deleted_at)"
+ + " VALUES "
+ + "<foreach collection='groupRoleRels' item='item' separator=','>"
+ + "(#{item.groupId},"
+ + " #{item.roleId},"
+ + " #{item.auditInfo},"
+ + " #{item.currentVersion},"
+ + " #{item.lastVersion},"
+ + " #{item.deletedAt})"
+ + "</foreach>"
+ + " ON CONFLICT (group_id, role_id, deleted_at) DO UPDATE SET"
+ + " group_id = EXCLUDED.group_id,"
+ + " role_id = EXCLUDED.role_id,"
+ + " audit_info = EXCLUDED.audit_info,"
+ + " current_version = EXCLUDED.current_version,"
+ + " last_version = EXCLUDED.last_version,"
+ + " deleted_at = EXCLUDED.deleted_at"
+ + "</script>";
+ }
+
@Override
public String deleteGroupRoleRelMetasByLegacyTimeline(
@Param("legacyTimeline") Long legacyTimeline, @Param("limit") int limit)
{
diff --git
a/core/src/test/java/org/apache/gravitino/storage/relational/mapper/provider/postgresql/TestGroupRoleRelPostgreSQLProvider.java
b/core/src/test/java/org/apache/gravitino/storage/relational/mapper/provider/postgresql/TestGroupRoleRelPostgreSQLProvider.java
index 8fcd67d1a5..b0435202eb 100644
---
a/core/src/test/java/org/apache/gravitino/storage/relational/mapper/provider/postgresql/TestGroupRoleRelPostgreSQLProvider.java
+++
b/core/src/test/java/org/apache/gravitino/storage/relational/mapper/provider/postgresql/TestGroupRoleRelPostgreSQLProvider.java
@@ -18,19 +18,77 @@
*/
package org.apache.gravitino.storage.relational.mapper.provider.postgresql;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import org.apache.gravitino.storage.relational.po.GroupRoleRelPO;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver;
import org.apache.ibatis.session.Configuration;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
public class TestGroupRoleRelPostgreSQLProvider {
+ @ParameterizedTest
+ @ValueSource(ints = {1, 2})
+ void testBatchInsertGroupRoleRelOnDuplicateKeyUpdate(int batchSize) {
+ List<GroupRoleRelPO> relations = new ArrayList<>();
+ List<Object> expectedParameters = new ArrayList<>();
+ for (int i = 0; i < batchSize; i++) {
+ GroupRoleRelPO relation =
+ GroupRoleRelPO.builder()
+ .withGroupId(10L + i)
+ .withRoleId(20L + i)
+ .withAuditInfo("audit-" + i)
+ .withCurrentVersion(30L + i)
+ .withLastVersion(40L + i)
+ .withDeletedAt(50L + i)
+ .build();
+ relations.add(relation);
+ expectedParameters.addAll(
+ Arrays.asList(
+ relation.getGroupId(),
+ relation.getRoleId(),
+ relation.getAuditInfo(),
+ relation.getCurrentVersion(),
+ relation.getLastVersion(),
+ relation.getDeletedAt()));
+ }
+
+ String script =
+ new
GroupRoleRelPostgreSQLProvider().batchInsertGroupRoleRelOnDuplicateKeyUpdate(relations);
+ SqlSource sqlSource =
+ new XMLLanguageDriver().createSqlSource(new Configuration(), script,
Map.class);
+ BoundSql boundSql = sqlSource.getBoundSql(Map.of("groupRoleRels",
relations));
+ String sql = boundSql.getSql().replaceAll("\\s+", " ").trim();
+
+ Assertions.assertTrue(sql.startsWith("INSERT INTO group_role_rel "));
+ Assertions.assertTrue(
+ sql.contains("ON CONFLICT (group_id, role_id, deleted_at) DO UPDATE
SET"));
+ Assertions.assertFalse(sql.contains("ON DUPLICATE KEY UPDATE"));
+ Assertions.assertFalse(sql.contains("VALUES("));
+ for (String column :
+ Arrays.asList(
+ "group_id", "role_id", "audit_info", "current_version",
"last_version", "deleted_at")) {
+ Assertions.assertTrue(sql.contains(column + " = EXCLUDED." + column));
+ }
+
+ List<Object> actualParameters = new ArrayList<>();
+ boundSql
+ .getParameterMappings()
+ .forEach(
+ mapping ->
+
actualParameters.add(boundSql.getAdditionalParameter(mapping.getProperty())));
+ Assertions.assertEquals(expectedParameters, actualParameters);
+ }
+
@Test
void testSoftDeleteGroupRoleRelByGroupAndRolesWithEmptyRoles() {
GroupRoleRelPostgreSQLProvider provider = new
GroupRoleRelPostgreSQLProvider();