You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polaris.apache.org by di...@apache.org on 2026/06/12 22:10:15 UTC
(polaris) branch main updated: Run JDBC schema validation tests on PostgreSQL (#4602)
This is an automated email from the ASF dual-hosted git repository.
dimas-b pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/polaris.git
The following commit(s) were added to refs/heads/main by this push:
new b1300e4c73 Run JDBC schema validation tests on PostgreSQL (#4602)
b1300e4c73 is described below
commit b1300e4c73ec37d1ae5105e97dcc83166dc7d3d4
Author: venkateshwaran shanmugham <ve...@gmail.com>
AuthorDate: Sat Jun 13 03:40:10 2026 +0530
Run JDBC schema validation tests on PostgreSQL (#4602)
* Run JDBC schema tests on PostgreSQL
* JDBC: Remove targeted H2 schema validation test
* Use semantic equality for JSON-backed persistence fields
---
...ithJdbcBasePersistenceImplPostgresSchemaIT.java | 114 +++++++++++++++++++++
...nagerWithJdbcBasePersistenceImplSchemaTest.java | 45 --------
...toreManagerWithJdbcBasePersistenceImplTest.java | 67 ++++++------
.../relational/jdbc/ResultSetIteratorTest.java | 25 ++++-
.../{H2SchemaVersions.java => SchemaVersions.java} | 45 ++++----
.../jdbc/SimpleRelationalJdbcConfiguration.java | 59 +++++++++++
.../polaris/core/entity/PolarisBaseEntity.java | 8 +-
.../core/policy/PolarisPolicyMappingRecord.java | 5 +-
.../persistence/PolarisObjectMapperUtilTest.java | 22 ++++
.../BasePolarisMetaStoreManagerTest.java | 2 +-
10 files changed, 282 insertions(+), 110 deletions(-)
diff --git a/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/AtomicMetastoreManagerWithJdbcBasePersistenceImplPostgresSchemaIT.java b/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/AtomicMetastoreManagerWithJdbcBasePersistenceImplPostgresSchemaIT.java
new file mode 100644
index 0000000000..23500a019b
--- /dev/null
+++ b/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/AtomicMetastoreManagerWithJdbcBasePersistenceImplPostgresSchemaIT.java
@@ -0,0 +1,114 @@
+/*
+ * 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.polaris.persistence.relational.jdbc;
+
+import static org.apache.polaris.containerspec.ContainerSpecHelper.containerSpecHelper;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.stream.Stream;
+import javax.sql.DataSource;
+import org.apache.polaris.test.commons.PostgresRelationalJdbcLifeCycleManagement;
+import org.junit.jupiter.params.Parameter;
+import org.junit.jupiter.params.ParameterizedClass;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.postgresql.ds.PGSimpleDataSource;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
+import org.testcontainers.postgresql.PostgreSQLContainer;
+
+/**
+ * Runs {@link org.apache.polaris.core.persistence.BasePolarisMetaStoreManagerTest} integration
+ * tests against every PostgreSQL schema version on the classpath.
+ */
+@Testcontainers
+@ParameterizedClass
+@MethodSource("schemaVersions")
+public class AtomicMetastoreManagerWithJdbcBasePersistenceImplPostgresSchemaIT
+ extends AtomicMetastoreManagerWithJdbcBasePersistenceImplTest {
+
+ @Container
+ private static final PostgreSQLContainer POSTGRES =
+ new PostgreSQLContainer(
+ containerSpecHelper("postgres", PostgresRelationalJdbcLifeCycleManagement.class)
+ .dockerImageName(null)
+ .asCompatibleSubstituteFor("postgres"));
+
+ @Parameter int schemaVersion;
+
+ private DataSource dataSource;
+
+ static Stream<Integer> schemaVersions() {
+ return SchemaVersions.discoverAsStream(DatabaseType.POSTGRES);
+ }
+
+ @Override
+ protected DatabaseType databaseType() {
+ return DatabaseType.POSTGRES;
+ }
+
+ @Override
+ public int schemaVersion() {
+ return schemaVersion;
+ }
+
+ @Override
+ protected DataSource createDataSource() {
+ if (dataSource == null) {
+ dataSource = createPostgresDataSource(schemaVersion());
+ }
+ return dataSource;
+ }
+
+ private static DataSource createPostgresDataSource(int schemaVersion) {
+ String databaseName = "polaris_schema_v" + schemaVersion;
+ createDatabaseIfNotExists(databaseName);
+
+ PGSimpleDataSource postgresDataSource = new PGSimpleDataSource();
+ postgresDataSource.setURL(jdbcUrlForDatabase(databaseName));
+ postgresDataSource.setUser(POSTGRES.getUsername());
+ postgresDataSource.setPassword(POSTGRES.getPassword());
+ return postgresDataSource;
+ }
+
+ private static void createDatabaseIfNotExists(String databaseName) {
+ try (Connection connection =
+ DriverManager.getConnection(
+ POSTGRES.getJdbcUrl(), POSTGRES.getUsername(), POSTGRES.getPassword());
+ Statement statement = connection.createStatement()) {
+ statement.execute("CREATE DATABASE " + databaseName);
+ } catch (SQLException e) {
+ // 42P04 is PostgreSQL's duplicate_database error; ignore when the schema DB already exists.
+ if (!"42P04".equals(e.getSQLState())) {
+ throw new RuntimeException("Failed to create database " + databaseName, e);
+ }
+ }
+ }
+
+ private static String jdbcUrlForDatabase(String databaseName) {
+ String baseUrl = POSTGRES.getJdbcUrl();
+ int lastSlash = baseUrl.lastIndexOf('/');
+ if (lastSlash < 0) {
+ throw new IllegalStateException("Unexpected JDBC URL: " + baseUrl);
+ }
+ return baseUrl.substring(0, lastSlash + 1) + databaseName;
+ }
+}
diff --git a/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/AtomicMetastoreManagerWithJdbcBasePersistenceImplSchemaTest.java b/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/AtomicMetastoreManagerWithJdbcBasePersistenceImplSchemaTest.java
deleted file mode 100644
index 58e30de267..0000000000
--- a/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/AtomicMetastoreManagerWithJdbcBasePersistenceImplSchemaTest.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.polaris.persistence.relational.jdbc;
-
-import java.util.stream.Stream;
-import org.junit.jupiter.params.Parameter;
-import org.junit.jupiter.params.ParameterizedClass;
-import org.junit.jupiter.params.provider.MethodSource;
-
-/**
- * Runs {@link org.apache.polaris.core.persistence.BasePolarisMetaStoreManagerTest} integration
- * tests against every H2 schema version on the classpath.
- */
-@ParameterizedClass
-@MethodSource("schemaVersions")
-public class AtomicMetastoreManagerWithJdbcBasePersistenceImplSchemaTest
- extends AtomicMetastoreManagerWithJdbcBasePersistenceImplTest {
-
- @Parameter int schemaVersion;
-
- static Stream<Integer> schemaVersions() {
- return H2SchemaVersions.discoverAsStream();
- }
-
- @Override
- public int schemaVersion() {
- return schemaVersion;
- }
-}
diff --git a/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/AtomicMetastoreManagerWithJdbcBasePersistenceImplTest.java b/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/AtomicMetastoreManagerWithJdbcBasePersistenceImplTest.java
index 54199d286b..3a78ca39ba 100644
--- a/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/AtomicMetastoreManagerWithJdbcBasePersistenceImplTest.java
+++ b/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/AtomicMetastoreManagerWithJdbcBasePersistenceImplTest.java
@@ -20,6 +20,7 @@ package org.apache.polaris.persistence.relational.jdbc;
import static org.apache.polaris.core.persistence.PrincipalSecretsGenerator.RANDOM_SECRETS;
+import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.List;
@@ -48,30 +49,49 @@ import org.mockito.Mockito;
public abstract class AtomicMetastoreManagerWithJdbcBasePersistenceImplTest
extends BasePolarisMetaStoreManagerTest {
- public DataSource createH2DataSource() {
- return JdbcConnectionPool.create(
- String.format("jdbc:h2:file:./build/test_data/polaris/db_%s", schemaVersion()), "sa", "");
+ protected DatabaseType databaseType() {
+ return DatabaseType.H2;
}
public abstract int schemaVersion();
+ protected DataSource createDataSource() {
+ return JdbcConnectionPool.create(
+ String.format(
+ "jdbc:h2:file:./build/test_data/polaris/db_%s_%d",
+ databaseType().getDisplayName(), schemaVersion()),
+ "sa",
+ "");
+ }
+
+ protected InputStream openSchemaScript() {
+ ClassLoader classLoader = DatasourceOperations.class.getClassLoader();
+ String resource =
+ String.format("%s/schema-v%d.sql", databaseType().getDisplayName(), schemaVersion());
+ InputStream scriptStream = classLoader.getResourceAsStream(resource);
+ if (scriptStream == null) {
+ throw new IllegalStateException("Schema resource not found: " + resource);
+ }
+ return scriptStream;
+ }
+
@Override
protected PolarisTestMetaStoreManager createPolarisTestMetaStoreManager() {
PolarisDiagnostics diagServices = new PolarisDefaultDiagServiceImpl();
DatasourceOperations datasourceOperations;
try {
datasourceOperations =
- new DatasourceOperations(createH2DataSource(), new H2JdbcConfiguration());
- ClassLoader classLoader = DatasourceOperations.class.getClassLoader();
- InputStream scriptStream =
- classLoader.getResourceAsStream(
- String.format(
- "%s/schema-v%s.sql", DatabaseType.H2.getDisplayName(), schemaVersion()));
- datasourceOperations.executeScript(scriptStream);
- } catch (SQLException e) {
+ new DatasourceOperations(
+ createDataSource(),
+ SimpleRelationalJdbcConfiguration.forDatabaseType(databaseType()));
+ try (InputStream scriptStream = openSchemaScript()) {
+ datasourceOperations.executeScript(scriptStream);
+ }
+ } catch (SQLException | IOException e) {
throw new RuntimeException(
String.format(
- "Error executing %s script: %s", DatabaseType.H2.getDisplayName(), e.getMessage()),
+ "Error executing %s schema-v%d script: %s",
+ databaseType(), schemaVersion(), e.getMessage()),
e);
}
@@ -165,27 +185,4 @@ public abstract class AtomicMetastoreManagerWithJdbcBasePersistenceImplTest
return getPropertiesAsMap().get(PolarisEntityConstants.ENTITY_BASE_LOCATION);
}
}
-
- private static class H2JdbcConfiguration implements RelationalJdbcConfiguration {
-
- @Override
- public Optional<Integer> maxRetries() {
- return Optional.of(2);
- }
-
- @Override
- public Optional<Long> maxDurationInMs() {
- return Optional.of(100L);
- }
-
- @Override
- public Optional<Long> initialDelayInMs() {
- return Optional.of(100L);
- }
-
- @Override
- public Optional<String> databaseType() {
- return Optional.of("h2");
- }
- }
}
diff --git a/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/ResultSetIteratorTest.java b/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/ResultSetIteratorTest.java
index 36b0d8fdb5..be2897b0eb 100644
--- a/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/ResultSetIteratorTest.java
+++ b/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/ResultSetIteratorTest.java
@@ -28,6 +28,7 @@ import static org.mockito.Mockito.when;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
+import java.util.Map;
import java.util.NoSuchElementException;
import org.apache.polaris.persistence.relational.jdbc.models.Converter;
import org.junit.jupiter.api.Test;
@@ -37,10 +38,9 @@ public class ResultSetIteratorTest {
@Test
public void testIteration() throws SQLException {
ResultSet resultSet = mock(ResultSet.class);
- Converter<String> converter = mock(Converter.class);
+ Converter<String> converter = converterReturning("first", "second");
when(resultSet.next()).thenReturn(true, true, false);
- when(converter.fromResultSet(resultSet)).thenReturn("first").thenReturn("second");
ResultSetIterator<String> iterator = new ResultSetIterator<>(resultSet, converter);
@@ -56,7 +56,7 @@ public class ResultSetIteratorTest {
@Test
public void testNextThrowsWhenExhausted() throws SQLException {
ResultSet resultSet = mock(ResultSet.class);
- Converter<String> converter = mock(Converter.class);
+ Converter<String> converter = converterReturning();
when(resultSet.next()).thenReturn(false);
@@ -69,10 +69,9 @@ public class ResultSetIteratorTest {
@Test
public void testToStream() throws SQLException {
ResultSet resultSet = mock(ResultSet.class);
- Converter<String> converter = mock(Converter.class);
+ Converter<String> converter = converterReturning("first", "second");
when(resultSet.next()).thenReturn(true, true, false);
- when(converter.fromResultSet(resultSet)).thenReturn("first").thenReturn("second");
ResultSetIterator<String> iterator = new ResultSetIterator<>(resultSet, converter);
@@ -80,4 +79,20 @@ public class ResultSetIteratorTest {
assertEquals(List.of("first", "second"), results);
}
+
+ private static Converter<String> converterReturning(String... values) {
+ return new Converter<String>() {
+ private int index = 0;
+
+ @Override
+ public String fromResultSet(ResultSet rs) {
+ return values[index++];
+ }
+
+ @Override
+ public Map<String, Object> toMap(DatabaseType databaseType) {
+ throw new UnsupportedOperationException("read-only converter stub");
+ }
+ };
+ }
}
diff --git a/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/H2SchemaVersions.java b/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/SchemaVersions.java
similarity index 52%
rename from persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/H2SchemaVersions.java
rename to persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/SchemaVersions.java
index 6103b8dda1..ddebc385e6 100644
--- a/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/H2SchemaVersions.java
+++ b/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/SchemaVersions.java
@@ -24,27 +24,27 @@ import java.util.SortedSet;
import java.util.TreeSet;
import java.util.stream.Stream;
-/** Discovers H2 schema versions available on the test classpath. */
-final class H2SchemaVersions {
+/** Discovers JDBC schema versions available on the test classpath for a {@link DatabaseType}. */
+final class SchemaVersions {
- private H2SchemaVersions() {}
+ private SchemaVersions() {}
/**
- * Returns sorted schema versions for which {@code h2/schema-vN.sql} exists on the classpath.
+ * Returns sorted schema versions for which {@code <database>/schema-vN.sql} exists on the
+ * classpath.
*
- * <p>Every version from {@code 0} through {@link DatabaseType#H2}{@linkplain
- * DatabaseType#getLatestSchemaVersion() latest} must be present. {@code schema-v0.sql} lives in
- * test resources to cover legacy bootstrap behavior; newer H2 schema files live in main
- * resources.
+ * <p>Every version from the type's first schema version through {@link
+ * DatabaseType#getLatestSchemaVersion()} must be present. H2 {@code schema-v0.sql} lives in test
+ * resources to cover legacy bootstrap behavior; production schema files live in main resources.
*/
- static SortedSet<Integer> discover() {
- ClassLoader classLoader = H2SchemaVersions.class.getClassLoader();
- int latestVersion = DatabaseType.H2.getLatestSchemaVersion();
+ static SortedSet<Integer> discover(DatabaseType databaseType) {
+ ClassLoader classLoader = SchemaVersions.class.getClassLoader();
+ int firstVersion = firstSchemaVersion(databaseType);
+ int latestVersion = databaseType.getLatestSchemaVersion();
SortedSet<Integer> versions = new TreeSet<>();
List<Integer> missingVersions = new ArrayList<>();
- for (int version = 0; version <= latestVersion; version++) {
- String resource =
- String.format("%s/schema-v%d.sql", DatabaseType.H2.getDisplayName(), version);
+ for (int version = firstVersion; version <= latestVersion; version++) {
+ String resource = String.format("%s/schema-v%d.sql", databaseType.getDisplayName(), version);
if (classLoader.getResource(resource) == null) {
missingVersions.add(version);
} else {
@@ -54,20 +54,29 @@ final class H2SchemaVersions {
if (!missingVersions.isEmpty()) {
throw new IllegalStateException(
String.format(
- "Missing H2 schema resource(s) %s for version(s) %s (expected versions 0-%d)",
+ "Missing %s schema resource(s) %s for version(s) %s (expected versions %d-%d)",
+ databaseType,
missingVersions.stream()
.map(
version ->
String.format(
- "%s/schema-v%d.sql", DatabaseType.H2.getDisplayName(), version))
+ "%s/schema-v%d.sql", databaseType.getDisplayName(), version))
.toList(),
missingVersions,
+ firstVersion,
latestVersion));
}
return versions;
}
- static Stream<Integer> discoverAsStream() {
- return discover().stream();
+ static Stream<Integer> discoverAsStream(DatabaseType databaseType) {
+ return discover(databaseType).stream();
+ }
+
+ private static int firstSchemaVersion(DatabaseType databaseType) {
+ return switch (databaseType) {
+ case H2 -> 0;
+ case POSTGRES, COCKROACHDB -> 1;
+ };
}
}
diff --git a/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/SimpleRelationalJdbcConfiguration.java b/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/SimpleRelationalJdbcConfiguration.java
new file mode 100644
index 0000000000..bbc28c12d8
--- /dev/null
+++ b/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/SimpleRelationalJdbcConfiguration.java
@@ -0,0 +1,59 @@
+/*
+ * 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.polaris.persistence.relational.jdbc;
+
+import java.util.Optional;
+
+/** Minimal {@link RelationalJdbcConfiguration} for JDBC persistence integration tests. */
+final class SimpleRelationalJdbcConfiguration implements RelationalJdbcConfiguration {
+
+ private final String databaseType;
+
+ private SimpleRelationalJdbcConfiguration(String databaseType) {
+ this.databaseType = databaseType;
+ }
+
+ static SimpleRelationalJdbcConfiguration forDatabaseType(DatabaseType databaseType) {
+ return switch (databaseType) {
+ case H2 -> new SimpleRelationalJdbcConfiguration("h2");
+ case POSTGRES -> new SimpleRelationalJdbcConfiguration("postgresql");
+ case COCKROACHDB -> new SimpleRelationalJdbcConfiguration("cockroachdb");
+ };
+ }
+
+ @Override
+ public Optional<Integer> maxRetries() {
+ return Optional.of(2);
+ }
+
+ @Override
+ public Optional<Long> maxDurationInMs() {
+ return Optional.of(100L);
+ }
+
+ @Override
+ public Optional<Long> initialDelayInMs() {
+ return Optional.of(100L);
+ }
+
+ @Override
+ public Optional<String> databaseType() {
+ return Optional.of(databaseType);
+ }
+}
diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisBaseEntity.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisBaseEntity.java
index a7c59ade77..1c42de1d42 100644
--- a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisBaseEntity.java
+++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisBaseEntity.java
@@ -343,8 +343,8 @@ public class PolarisBaseEntity extends PolarisEntityCore {
&& toPurgeTimestamp == that.toPurgeTimestamp
&& lastUpdateTimestamp == that.lastUpdateTimestamp
&& grantRecordsVersion == that.grantRecordsVersion
- && Objects.equals(properties, that.properties)
- && Objects.equals(internalProperties, that.internalProperties);
+ && Objects.equals(getPropertiesAsMap(), that.getPropertiesAsMap())
+ && Objects.equals(getInternalPropertiesAsMap(), that.getInternalPropertiesAsMap());
}
@Override
@@ -362,8 +362,8 @@ public class PolarisBaseEntity extends PolarisEntityCore {
purgeTimestamp,
toPurgeTimestamp,
lastUpdateTimestamp,
- properties,
- internalProperties,
+ getPropertiesAsMap(),
+ getInternalPropertiesAsMap(),
grantRecordsVersion);
}
diff --git a/polaris-core/src/main/java/org/apache/polaris/core/policy/PolarisPolicyMappingRecord.java b/polaris-core/src/main/java/org/apache/polaris/core/policy/PolarisPolicyMappingRecord.java
index 4b13896d22..5112895525 100644
--- a/polaris-core/src/main/java/org/apache/polaris/core/policy/PolarisPolicyMappingRecord.java
+++ b/polaris-core/src/main/java/org/apache/polaris/core/policy/PolarisPolicyMappingRecord.java
@@ -205,11 +205,12 @@ public class PolarisPolicyMappingRecord {
&& policyCatalogId == that.policyCatalogId
&& policyId == that.policyId
&& policyTypeCode == that.policyTypeCode
- && Objects.equals(parameters, that.parameters);
+ && Objects.equals(getParametersAsMap(), that.getParametersAsMap());
}
@Override
public int hashCode() {
- return java.util.Objects.hash(targetId, policyId, policyCatalogId, policyTypeCode, parameters);
+ return Objects.hash(
+ targetCatalogId, targetId, policyCatalogId, policyId, policyTypeCode, getParametersAsMap());
}
}
diff --git a/polaris-core/src/test/java/org/apache/polaris/core/persistence/PolarisObjectMapperUtilTest.java b/polaris-core/src/test/java/org/apache/polaris/core/persistence/PolarisObjectMapperUtilTest.java
index 62cb51319a..93af87ea13 100644
--- a/polaris-core/src/test/java/org/apache/polaris/core/persistence/PolarisObjectMapperUtilTest.java
+++ b/polaris-core/src/test/java/org/apache/polaris/core/persistence/PolarisObjectMapperUtilTest.java
@@ -134,4 +134,26 @@ class PolarisObjectMapperUtilTest {
PolarisObjectMapperUtil.parseTaskState(entity);
Assertions.assertThat(state).isNull();
}
+
+ @Test
+ void entityEqualsIgnoresJsonFormatting() {
+ PolarisBaseEntity compact =
+ new PolarisBaseEntity.Builder()
+ .catalogId(1L)
+ .id(2L)
+ .typeCode(PolarisEntityType.TASK.getCode())
+ .subTypeCode(PolarisEntitySubType.NULL_SUBTYPE.getCode())
+ .parentId(0L)
+ .name("entity")
+ .properties("{\"key\":\"value\"}")
+ .internalProperties("{\"internal\":true}")
+ .build();
+ PolarisBaseEntity spaced =
+ new PolarisBaseEntity.Builder(compact)
+ .properties("{\"key\": \"value\"}")
+ .internalProperties("{\"internal\": true}")
+ .build();
+
+ Assertions.assertThat(compact).isEqualTo(spaced);
+ }
}
diff --git a/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/BasePolarisMetaStoreManagerTest.java b/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/BasePolarisMetaStoreManagerTest.java
index 5bda228ab1..fb35ea1c67 100644
--- a/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/BasePolarisMetaStoreManagerTest.java
+++ b/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/BasePolarisMetaStoreManagerTest.java
@@ -129,7 +129,7 @@ public abstract class BasePolarisMetaStoreManagerTest {
.isNotNull()
.hasSize(2)
.extracting(PolarisEntity::toCore)
- .containsExactly(PolarisEntity.toCore(task1), PolarisEntity.toCore(task2));
+ .containsExactlyInAnyOrder(PolarisEntity.toCore(task1), PolarisEntity.toCore(task2));
Assertions.assertThat(createdEntities).containsExactlyInAnyOrderElementsOf(listedEntities);
}