-
Notifications
You must be signed in to change notification settings - Fork 28
Feature/ignore partition tables postgres #333
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
9e9f3d4
30f66d7
1422ab2
178ccbc
a010d49
862e8a2
4c4ca2f
35ab449
bf047dd
c51e18c
dc1fa5b
b0266b9
7592278
d7fadd5
babd7e3
f33a5a4
2935597
a98fc77
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -56,6 +56,7 @@ | |
| import com.google.common.cache.LoadingCache; | ||
| import com.google.common.collect.ImmutableList; | ||
| import com.google.common.collect.ImmutableMap; | ||
| import com.google.common.collect.ImmutableSet; | ||
| import com.google.common.collect.Maps; | ||
|
|
||
| /** | ||
|
|
@@ -116,6 +117,8 @@ public abstract class DatabaseMetaDataProvider implements Schema { | |
| private final LoadingCache<AName, Sequence> sequenceCache = CacheBuilder.newBuilder().build(CacheLoader.from(this::loadSequence)); | ||
|
|
||
| private final Supplier<Map<String, String>> databaseInformation = Suppliers.memoize(this::loadDatabaseInformation); | ||
| protected Supplier<ImmutableSet<String>> ignoredTables = Suppliers.memoize(this::loadIgnoredTables); | ||
| protected Supplier<ImmutableSet<String>> partitionedTables = Suppliers.memoize(this::loadPartitionedTables); | ||
|
|
||
| /** | ||
| * @param connection The database connection from which meta data should be provided. | ||
|
|
@@ -148,6 +151,9 @@ private Map<String, String> loadDatabaseInformation() { | |
| } | ||
| } | ||
|
|
||
| protected ImmutableSet<String> loadIgnoredTables() { return ImmutableSet.of(); } | ||
|
|
||
| protected ImmutableSet<String> loadPartitionedTables() { return ImmutableSet.of(); } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change the return type of these to |
||
|
|
||
| /** | ||
| * @see org.alfasoftware.morf.metadata.Schema#isEmptyDatabase() | ||
|
|
@@ -306,6 +312,11 @@ protected Map<AName, RealName> loadAllTableNames() { | |
| throw new RuntimeSqlException("Error reading metadata for table ["+tableName+"]", e); | ||
| } | ||
| } | ||
| // add partitioned tables to list | ||
| partitionedTables.get().forEach(table -> { | ||
| RealName partionedTableName = createRealName(table, table); | ||
| tableNameMappings.put(partionedTableName, partionedTableName); | ||
| }); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was wondering, these get ignored via If we add support for Oracle's partitioning, this might become problematic, unless Oracle also excludes those tables during the above and will need us to also add those tables here. |
||
|
|
||
| long end = System.currentTimeMillis(); | ||
| Map<AName, RealName> tableNameMap = tableNameMappings.build(); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| package org.alfasoftware.morf.metadata; | ||
|
|
||
| import java.util.Collection; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
|
|
||
|
|
@@ -18,6 +19,26 @@ default Map<String, String> primaryKeyIndexNames() { | |
| throw new NotImplementedException("Not implemented yet."); | ||
| } | ||
|
|
||
| /** | ||
| * Provides the names of all partitioned tables in the database. This applies for now for postgres. Note that the order of | ||
| * the tables in the result is not specified. The case of the | ||
| * table names may be preserved when logging progress, but should not be relied on for schema | ||
| * processing. A partitioned table is a table that has partitions. | ||
| * | ||
| * @return A collection of all partitioned table names available in the database. | ||
| */ | ||
| default Collection<String> partitionedTableNames() { throw new NotImplementedException("Not implemented yet."); } | ||
|
|
||
| /** | ||
| * Provides the names of all partition tables in the database. This applies for now for postgres. Note that the order of | ||
| * the tables in the result is not specified. The case of the | ||
| * table names may be preserved when logging progress, but should not be relied on for schema | ||
| * processing. A partition table is a table that is a partition of a partitioned table. | ||
| * | ||
| * @return A collection of all partition table names available in the database. | ||
| */ | ||
| default Collection<String> partitionTableNames() { throw new NotImplementedException("Not implemented yet."); } | ||
|
BrunoSMonteiro74 marked this conversation as resolved.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not particularly important, but if you make further changes, change both of these to |
||
|
|
||
| default Map<String, List<Index>> ignoredIndexes() { | ||
| return Map.of(); | ||
| } | ||
|
|
||
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -82,6 +82,8 @@ public void setup() { | |
| public void tearDown() { | ||
| dropUpgradeStatusTable(); | ||
| schemaManager.invalidateCache(); | ||
| // to make following test on test suite run clean - org.alfasoftware.morf.upgrade.TestFullDeployment | ||
| schemaManager.dropAllTables(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree with the change, but the comment is unnecessary, since the order of tests will change in the future. It will be other tests that benefit from properly clearing down the database. |
||
| } | ||
|
|
||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,8 +9,10 @@ | |
| import java.sql.SQLException; | ||
| import java.sql.Statement; | ||
| import java.sql.Types; | ||
| import java.util.Collection; | ||
| import java.util.HashSet; | ||
| import java.util.List; | ||
| import java.util.Locale; | ||
| import java.util.Map; | ||
| import java.util.Optional; | ||
| import java.util.Set; | ||
|
|
@@ -30,6 +32,7 @@ | |
|
|
||
| import com.google.common.base.Suppliers; | ||
| import com.google.common.collect.ImmutableMap; | ||
| import com.google.common.collect.ImmutableSet; | ||
|
|
||
| /** | ||
| * Provides meta data from a PostgreSQL database connection. | ||
|
|
@@ -51,6 +54,47 @@ public PostgreSQLMetaDataProvider(Connection connection, String schemaName) { | |
| } | ||
|
|
||
|
|
||
| @Override | ||
| protected ImmutableSet<String> loadIgnoredTables() { | ||
| ImmutableSet.Builder<String> ignoredTables = new ImmutableSet.Builder<>(); | ||
| try(Statement ignoredTablesStmt = connection.createStatement()) { | ||
| // distinguish partitioned tables from regular ones: relkind = 'p' (partition) or 'r' (regular) also can use boolean col relispartition | ||
| // a partition table attached has (r, true) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Below, you've got the full explanation or partitions and partitioned tables: Add that same here as well, as this thing is kind of confusing at first. |
||
| try (ResultSet ignoredTablesRs = ignoredTablesStmt.executeQuery("select relname from pg_class where relispartition and relkind = 'r'")) { | ||
| while (ignoredTablesRs.next()) { | ||
| ignoredTables.add(ignoredTablesRs.getString(1).toLowerCase(Locale.ROOT)); | ||
| } | ||
| } | ||
| } catch (SQLException e) { | ||
| // ignore exception, if it fails then incompatible Postgres version | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could be a problem. Connections where statements fail are usually marked as rollback-only on Postgres.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't expect to get an incompatible postgres version. The partition support for list and range has been around since 2017 version 10. The hash partition was added on version 11.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At least add a log line :) |
||
| } | ||
| return ignoredTables.build(); | ||
| } | ||
|
|
||
| @Override | ||
| protected ImmutableSet<String> loadPartitionedTables() { | ||
| ImmutableSet.Builder<String> partitionedTables = new ImmutableSet.Builder<>(); | ||
| try(Statement partitionedTablesStmt = connection.createStatement()) { | ||
| // distinguish partitioned tables from regular ones: relkind = 'p' (partition) or 'r' (regular) also can use boolean col relispartition | ||
| // a partition table attached has (r, true) | ||
| // a partition table has (p, false) | ||
| try (ResultSet ignoredTablesRs = partitionedTablesStmt.executeQuery("select relname from pg_class where not relispartition and relkind = 'p'")) { | ||
| while (ignoredTablesRs.next()) { | ||
| partitionedTables.add(ignoredTablesRs.getString(1).toLowerCase(Locale.ROOT)); | ||
| } | ||
| } | ||
| } catch (SQLException e) { | ||
| // ignore exception, if it fails then incompatible Postgres version | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could this be a problem? Connections where statements fail are usually marked as rollback-only on Postgres.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't expect to get an incompatible postgres version. The partition support for list and range has been around since 2017 version 10. The hash partition was added on version 11.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As above, at least add a log line :) |
||
| } | ||
| return partitionedTables.build(); | ||
| } | ||
|
|
||
|
|
||
| @Override | ||
| protected boolean isIgnoredTable(RealName tableName) { | ||
| return ignoredTables.get().contains(tableName.getDbName().toLowerCase(Locale.ROOT)) || super.isIgnoredTable(tableName); | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You have added |
||
|
|
||
| @Override | ||
| protected boolean isPrimaryKeyIndex(RealName indexName) { | ||
| return indexName.getDbName().endsWith("_pk"); | ||
|
|
@@ -233,4 +277,15 @@ protected String buildSequenceSql(String schemaName) { | |
|
|
||
| return sequenceSqlBuilder.toString(); | ||
| } | ||
|
|
||
|
|
||
| @Override | ||
| public Collection<String> partitionedTableNames() { | ||
| return super.partitionedTables.get(); | ||
| } | ||
|
|
||
| @Override | ||
| public Collection<String> partitionTableNames() { | ||
| return super.ignoredTables.get(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, as soon as someone adds something else to |
||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change these two to
Supplier<Set<RealName>>(orSupplier<Set<AName>>if not RealName).Both for consistency and also to deal with case-sensitivity problem (see my comment about moving
isIgnoredTable()below).