DDL - Refactor DDL for Postgres and YugabyteDB to just create a default partition table

Removes the need and use of  PostgresPlatform.tablePartitionsExist() and PostgresPlatform.tablePartitionInit() altogether.
This commit is contained in:
Rob Bygrave
2022-06-14 16:00:54 +12:00
parent 06ad2edfc1
commit 403556d8b2
8 changed files with 16 additions and 112 deletions
@@ -802,20 +802,6 @@ public class DatabasePlatform {
}
}
/**
* Return true if partitions exist for the given table.
*/
public boolean tablePartitionsExist(Connection connection, String table) throws SQLException {
return true;
}
/**
* Return the SQL to create an initial partition for the given table.
*/
public String tablePartitionInit(String tableName, PartitionMode mode) {
return null;
}
/**
* Escapes the like string for this DB-Platform
*/
@@ -10,19 +10,12 @@ import io.ebean.util.JdbcClose;
import io.ebeaninternal.api.SpiDdlGenerator;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.dbmigration.model.CurrentModel;
import io.ebeaninternal.dbmigration.model.MTable;
import io.ebeaninternal.extraddl.model.ExtraDdlXmlReader;
import io.ebeaninternal.server.deploy.PartitionMeta;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.persistence.PersistenceException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.LineNumberReader;
import java.io.Reader;
import java.io.Writer;
import java.io.*;
import java.sql.Connection;
import java.sql.SQLException;
@@ -205,7 +198,6 @@ public class DdlGenerator implements SpiDdlGenerator {
createAllContent = readFile(getCreateFileName());
}
runScript(connection, false, createAllContent, getCreateFileName());
if (extraDdl && jaxbPresent) {
if (currentModel().isTablePartitioning()) {
String extraPartitioning = ExtraDdlXmlReader.buildPartitioning(platform);
@@ -213,43 +205,10 @@ public class DdlGenerator implements SpiDdlGenerator {
runScript(connection, false, extraPartitioning, "builtin-partitioning-ddl");
}
}
String extraApply = ExtraDdlXmlReader.buildExtra(platform, false);
if (extraApply != null) {
runScript(connection, false, extraApply, "extra-ddl");
}
if (currentModel().isTablePartitioning()) {
checkInitialTablePartitions(connection);
}
}
}
/**
* Check if table partitions exist and if not create some. The expectation is that
* extra-ddl.xml should have some partition initialisation but this helps people get going.
*/
private void checkInitialTablePartitions(Connection connection) {
DatabasePlatform databasePlatform = server.databasePlatform();
try {
StringBuilder sb = new StringBuilder();
for (MTable table : currentModel.getPartitionedTables()) {
String tableName = table.getName();
if (!databasePlatform.tablePartitionsExist(connection, tableName)) {
log.info("No table partitions for table {}", tableName);
PartitionMeta meta = table.getPartitionMeta();
String initPart = databasePlatform.tablePartitionInit(tableName, meta.getMode());
sb.append(initPart).append("\n");
}
}
String initialPartitionSql = sb.toString();
if (!initialPartitionSql.isEmpty()) {
runScript(connection, false, initialPartitionSql, "initial table partitions");
}
} catch (SQLException e) {
log.error("Error checking initial table partitions", e);
}
}
@@ -213,6 +213,8 @@ public class BaseTableDdl implements TableDdl {
String partitionMode = createTable.getPartitionMode();
if (partitionMode != null) {
platformDdl.addTablePartition(apply, partitionMode, createTable.getPartitionColumn());
apply.endOfStatement().newLine();
platformDdl.addDefaultTablePartition(apply, createTable.getName());
}
apply.endOfStatement();
@@ -733,7 +733,11 @@ public class PlatformDdl {
}
public void addTablePartition(DdlBuffer apply, String partitionMode, String partitionColumn) {
// only supported by postgres initially
// only supported by postgres and yugabyte
}
public void addDefaultTablePartition(DdlBuffer apply, String tableName) {
// only supported by postgres and yugabyte
}
/**
@@ -45,6 +45,11 @@ public class PostgresDdl extends PlatformDdl {
apply.append(" partition by range (").append(partitionColumn).append(")");
}
@Override
public void addDefaultTablePartition(DdlBuffer apply, String tableName) {
apply.append("create table ").append(tableName).append("_default partition of ").append(tableName).append(" default");
}
@Override
public String dropIndex(String indexName, String tableName, boolean concurrent) {
return (concurrent ? dropIndexConcurrentlyIfExists : dropIndexIfExists) + maxConstraintName(indexName);
@@ -7,11 +7,10 @@ import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class PostgresPlatformTest {
class PostgresPlatformTest {
@Test
public void testTypeConversion() {
void testTypeConversion() {
PostgresPlatform platform = new PostgresPlatform();
PlatformDdl ddl = PlatformDdlBuilder.create(platform);
@@ -147,40 +147,4 @@ public class PostgresPlatform extends DatabasePlatform {
}
return FOR_UPDATE;
}
@Override
public boolean tablePartitionsExist(Connection connection, String table) throws SQLException {
try (PreparedStatement statement = connection.prepareStatement("select count(*) from pg_inherits i WHERE i.inhparent = ?::regclass")) {
statement.setString(1, table);
try (ResultSet resultSet = statement.executeQuery()) {
return resultSet.next() && resultSet.getInt(1) > 0;
}
}
}
/**
* Return SQL using built in partition helper functions to create some initial partitions.
* <p>
* Only use this if extra-ddl doesn't have some initial partitions defined (which it should).
*/
@Override
public String tablePartitionInit(String tableName, PartitionMode mode) {
// default partition required pg11 but this is only used for testing but bumped test docker container to pg14 by default
String[] schemaTable = SplitName.split(tableName);
String baseTable;
String plusSchema;
if (schemaTable[0] == null) {
plusSchema = "";
baseTable = tableName;
} else {
// table in an explicit schema
plusSchema = ",'" + schemaTable[0] + "'";
baseTable = schemaTable[1];
}
return
"create table " + tableName + "_default" + " partition of " + tableName + " default;\n" +
"select partition('" + mode.name().toLowerCase() + "','" + baseTable + "',1" + plusSchema + ");";
}
}
@@ -1,6 +1,5 @@
package io.ebean.platform.postgres;
import io.ebean.annotation.PartitionMode;
import io.ebean.annotation.Platform;
import io.ebean.config.PlatformConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
@@ -16,7 +15,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
class PostgresPlatformTest {
@Test
void testUuidType() {
void testUuidType() {
PostgresPlatform platform = new PostgresPlatform();
platform.configure(new PlatformConfig());
@@ -26,20 +25,6 @@ class PostgresPlatformTest {
assertThat(columnDefn).isEqualTo("uuid");
}
@Test
void tablePartitionInit() {
String sql = new PostgresPlatform().tablePartitionInit("foo", PartitionMode.WEEK);
assertThat(sql).isEqualTo("create table foo_default partition of foo default;\n" +
"select partition('week','foo',1);");
}
@Test
void tablePartitionInit_withSchema() {
String sql = new PostgresPlatform().tablePartitionInit("bar.foo", PartitionMode.WEEK);
assertThat(sql).isEqualTo("create table bar.foo_default partition of bar.foo default;\n" +
"select partition('week','foo',1,'bar');");
}
@Test
void default_forUpdate_expect_noKeyUsed() {
PostgresPlatform platform = new PostgresPlatform();