Skip to content

Commit 7a24e05

Browse files
committed
DS-1064: Add workaround for postgres bug on "DROP SCHEMA CASCADE"
Signed-off-by: Benjamin Rögner <benjamin.roegner@here.com>
1 parent adaad9f commit 7a24e05

1 file changed

Lines changed: 36 additions & 7 deletions

File tree

  • xyz-util/src/main/java/com/here/xyz/util/db/pg

xyz-util/src/main/java/com/here/xyz/util/db/pg/Script.java

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2017-2024 HERE Europe B.V.
2+
* Copyright (C) 2017-2025 HERE Europe B.V.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -29,7 +29,6 @@
2929
import com.here.xyz.util.db.datasource.DataSourceProvider;
3030
import com.here.xyz.util.db.datasource.DatabaseSettings.ScriptResourcePath;
3131
import java.io.BufferedReader;
32-
import java.io.File;
3332
import java.io.FileNotFoundException;
3433
import java.io.IOException;
3534
import java.io.InputStream;
@@ -153,9 +152,11 @@ private void install(String targetSchema, boolean deleteBefore) throws SQLExcept
153152
}
154153

155154
List<SQLQuery> installationQueries = new ArrayList<>();
156-
// TODO: Remove uncommented code once "drop schema cascade" issue creating orphan functions is resolved
157-
// if (deleteBefore)
158-
// installationQueries.add(buildDeleteSchemaQuery(getTargetSchema(targetSchema)));
155+
if (deleteBefore) {
156+
//TODO: Remove following workaround once "drop schema cascade"-bug creating orphaned functions is fixed in postgres
157+
installationQueries.addAll(buildDeleteFunctionQueries(loadSchemaFunctions(targetSchema)));
158+
installationQueries.add(buildDeleteSchemaQuery(getTargetSchema(targetSchema)));
159+
}
159160
installationQueries.addAll(List.of(buildCreateSchemaQuery(targetSchema), buildSetCurrentSearchPathQuery(targetSchema),
160161
buildHashFunctionQuery(), buildVersionFunctionQuery(), scriptContent));
161162

@@ -359,11 +360,39 @@ private void uninstall(String scriptVersion) throws SQLException {
359360
if (scriptVersion.equals(loadLatestVersion()))
360361
throw new IllegalStateException("The script version " + getScriptName() + ":" + scriptVersion
361362
+ " is still in use on DB " + getDbId() + " and can not be uninstalled.");
362-
// TODO: Remove uncommented code once "drop schema cascade" issue creating orphan functions is resolved
363-
// buildDeleteSchemaQuery(getTargetSchema(scriptVersion)).write(dataSourceProvider);
363+
364+
//TODO: Remove following workaround once "drop schema cascade"-bug creating orphaned functions is fixed in postgres
365+
String schema = getTargetSchema(scriptVersion);
366+
batchDeleteFunctions(loadSchemaFunctions(schema));
367+
buildDeleteSchemaQuery(schema).write(dataSourceProvider);
368+
364369
compatibleVersions = new HashMap<>(); //Reset the cache
365370
}
366371

372+
private void batchDeleteFunctions(List<String> functionSignatures) throws SQLException {
373+
SQLQuery.batchOf(buildDeleteFunctionQueries(functionSignatures))
374+
.writeBatch(dataSourceProvider);
375+
}
376+
377+
private static List<SQLQuery> buildDeleteFunctionQueries(List<String> functionSignatures) {
378+
return functionSignatures.stream()
379+
.map(signature -> new SQLQuery("DROP FUNCTION " + signature))
380+
.toList();
381+
}
382+
383+
private List<String> loadSchemaFunctions(String schema) throws SQLException {
384+
return new SQLQuery("""
385+
SELECT proc.oid::REGPROCEDURE FROM pg_proc proc LEFT JOIN pg_namespace ns ON proc.pronamespace = ns.oid
386+
WHERE ns.nspname = #schema
387+
"""
388+
).run(dataSourceProvider, rs -> {
389+
List<String> signatures = new ArrayList<>();
390+
while (rs.next())
391+
signatures.add(rs.getString("schema_name"));
392+
return signatures;
393+
});
394+
}
395+
367396
public void cleanupOldScriptVersions(int versionsToKeep) {
368397
try {
369398
final List<String> scriptVersions = listInstalledScriptVersions();

0 commit comments

Comments
 (0)