-
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a check for identifiers with maximum length (#466)
* Add AnyObject and PgObjectType * Add tests for AnyObject and PgObjectType * Fix mutation tests * Add new check and test * Add PossibleObjectNameOverflowCheckOnCluster * Add PossibleObjectNameOverflowCheckOnCluster to DatabaseChecks * Extend HealthLogger and Spring Boot autoconfiguration
- Loading branch information
Showing
63 changed files
with
1,023 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
...src/main/java/io/github/mfvanek/pg/checks/host/PossibleObjectNameOverflowCheckOnHost.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* Copyright (c) 2019-2024. Ivan Vakhrushev and others. | ||
* https://github.com/mfvanek/pg-index-health | ||
* | ||
* This file is a part of "pg-index-health" - a Java library for | ||
* analyzing and maintaining indexes health in PostgreSQL databases. | ||
* | ||
* Licensed under the Apache License 2.0 | ||
*/ | ||
|
||
package io.github.mfvanek.pg.checks.host; | ||
|
||
import io.github.mfvanek.pg.common.maintenance.Diagnostic; | ||
import io.github.mfvanek.pg.connection.PgConnection; | ||
import io.github.mfvanek.pg.model.PgContext; | ||
import io.github.mfvanek.pg.model.object.AnyObject; | ||
|
||
import java.util.List; | ||
import javax.annotation.Nonnull; | ||
|
||
/** | ||
* Check for objects whose names have a length of {@code max_identifier_length} (usually it is 63) on a specific host. | ||
* <p> | ||
* The problem is that Postgres silently truncates such long names. | ||
* For example, if you have a migration where you are trying to create two objects with very long names | ||
* that start the same way (such as an index or constraint) and you use the "if not exists" statement, | ||
* you might end up with only one object in the database instead of two. | ||
* <p> | ||
* If there is an object with a name of maximum length in the database, then an overflow may have occurred. | ||
* It is advisable to avoid such situations and use shorter names. | ||
* | ||
* @author Ivan Vahrushev | ||
* @see <a href="https://www.postgresql.org/docs/current/limits.html">PostgreSQL Limits</a> | ||
* @since 0.13.2 | ||
*/ | ||
public class PossibleObjectNameOverflowCheckOnHost extends AbstractCheckOnHost<AnyObject> { | ||
|
||
public PossibleObjectNameOverflowCheckOnHost(@Nonnull final PgConnection pgConnection) { | ||
super(AnyObject.class, pgConnection, Diagnostic.POSSIBLE_OBJECT_NAME_OVERFLOW); | ||
} | ||
|
||
/** | ||
* Returns objects whose names have a length of {@code max_identifier_length} in the specified schema. | ||
* | ||
* @param pgContext check's context with the specified schema; must not be null | ||
* @return list of objects whose names have a length of {@code max_identifier_length} | ||
*/ | ||
@Nonnull | ||
@Override | ||
protected List<AnyObject> doCheck(@Nonnull final PgContext pgContext) { | ||
return executeQuery(pgContext, rs -> { | ||
final String objectName = rs.getString("object_name"); | ||
final String objectType = rs.getString("object_type"); | ||
return AnyObject.ofRaw(objectName, objectType); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
...test/java/io/github/mfvanek/pg/checks/host/PossibleObjectNameOverflowCheckOnHostTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* | ||
* Copyright (c) 2019-2024. Ivan Vakhrushev and others. | ||
* https://github.com/mfvanek/pg-index-health | ||
* | ||
* This file is a part of "pg-index-health" - a Java library for | ||
* analyzing and maintaining indexes health in PostgreSQL databases. | ||
* | ||
* Licensed under the Apache License 2.0 | ||
*/ | ||
|
||
package io.github.mfvanek.pg.checks.host; | ||
|
||
import io.github.mfvanek.pg.common.maintenance.DatabaseCheckOnHost; | ||
import io.github.mfvanek.pg.common.maintenance.Diagnostic; | ||
import io.github.mfvanek.pg.model.PgContext; | ||
import io.github.mfvanek.pg.model.object.AnyObject; | ||
import io.github.mfvanek.pg.model.object.PgObjectType; | ||
import io.github.mfvanek.pg.support.DatabaseAwareTestBase; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.ValueSource; | ||
|
||
import static io.github.mfvanek.pg.support.AbstractCheckOnHostAssert.assertThat; | ||
|
||
class PossibleObjectNameOverflowCheckOnHostTest extends DatabaseAwareTestBase { | ||
|
||
private final DatabaseCheckOnHost<AnyObject> check = new PossibleObjectNameOverflowCheckOnHost(getPgConnection()); | ||
|
||
@Test | ||
void shouldSatisfyContract() { | ||
assertThat(check) | ||
.hasType(AnyObject.class) | ||
.hasDiagnostic(Diagnostic.POSSIBLE_OBJECT_NAME_OVERFLOW) | ||
.hasHost(getHost()) | ||
.isStatic(); | ||
} | ||
|
||
@ParameterizedTest | ||
@ValueSource(strings = {PgContext.DEFAULT_SCHEMA_NAME, "custom"}) | ||
void onDatabaseWithThem(final String schemaName) { | ||
executeTestOnDatabase(schemaName, dbp -> dbp.withReferences().withMaterializedView().withIdentityPrimaryKey(), ctx -> { | ||
final String matViewName = ctx.enrichWithSchema("accounts_materialized_view_with_length_63_1234567890_1234567890"); | ||
final String constraintName = ctx.enrichWithSchema("num_less_than_million_constraint_with_length_63_1234567890_1234"); | ||
assertThat(check) | ||
.executing(ctx) | ||
.hasSize(2) | ||
.containsExactlyInAnyOrder( | ||
AnyObject.ofType(matViewName, PgObjectType.MATERIALIZED_VIEW), | ||
AnyObject.ofType(constraintName, PgObjectType.CONSTRAINT)); | ||
|
||
assertThat(check) | ||
.executing(ctx, t -> !(t.getName().equals(matViewName) || t.getName().equals(constraintName))) | ||
.isEmpty(); | ||
}); | ||
} | ||
} |
Oops, something went wrong.