mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#2743 - Postgres DDL - For create table, improve column ordering for tighter storage
This commit is contained in:
+6
@@ -198,6 +198,7 @@ public class PlatformDdl {
|
||||
* Write all the table columns converting to platform types as necessary.
|
||||
*/
|
||||
public void writeTableColumns(DdlBuffer apply, List<Column> columns, DdlIdentity identity) {
|
||||
columns = sortColumns(columns);
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
if (i > 0) {
|
||||
apply.append(",");
|
||||
@@ -218,6 +219,11 @@ public class PlatformDdl {
|
||||
}
|
||||
}
|
||||
|
||||
protected List<Column> sortColumns(List<Column> columns) {
|
||||
// do nothing by default
|
||||
return columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the column definition to the create table statement.
|
||||
*/
|
||||
|
||||
+56
@@ -4,6 +4,14 @@ import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.Column;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
/**
|
||||
* Postgres specific DDL.
|
||||
@@ -70,4 +78,52 @@ public class PostgresDdl extends PlatformDdl {
|
||||
.append(columnSetType).append(type)
|
||||
.append(" using ").append(alter.getColumnName()).append("::").append(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Column> sortColumns(List<Column> columns) {
|
||||
List<DDLColumnSort> sorting = new ArrayList<>(columns.size());
|
||||
for (int i = 0, end = columns.size(); i < end; i++) {
|
||||
Column column = columns.get(i);
|
||||
sorting.add(new DDLColumnSort(column, ddlColumnOrdering(i, column)));
|
||||
}
|
||||
Collections.sort(sorting);
|
||||
return sorting.stream().map(it -> it.column).collect(toList());
|
||||
}
|
||||
|
||||
private int ddlColumnOrdering(int i, Column column) {
|
||||
String type = column.getType().toLowerCase();
|
||||
if (type.startsWith("decimal")) {
|
||||
return i + 1_000;
|
||||
}
|
||||
if (isVariableLength(type) || isLob(type)) {
|
||||
return i + 10_000;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
private boolean isLob(String type) {
|
||||
return type.startsWith("clob") || type.startsWith("longvarchar") || type.startsWith("blob") || type.startsWith("longvarbinary");
|
||||
}
|
||||
|
||||
private boolean isVariableLength(String type) {
|
||||
return type.startsWith("varchar") || type.startsWith("varbinary");
|
||||
}
|
||||
|
||||
static final class DDLColumnSort implements Comparable<DDLColumnSort> {
|
||||
|
||||
private final Column column;
|
||||
private final int ordering;
|
||||
|
||||
DDLColumnSort(Column column, int ordering) {
|
||||
this.column = column;
|
||||
this.ordering = ordering;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(DDLColumnSort o) {
|
||||
return Integer.compare(ordering, o.ordering);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+9
-1
@@ -1,11 +1,19 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebeaninternal.dbmigration.migration.Column;
|
||||
|
||||
public class YugabyteDdl extends PostgresDdl {
|
||||
import java.util.List;
|
||||
|
||||
public final class YugabyteDdl extends PostgresDdl {
|
||||
|
||||
public YugabyteDdl(DatabasePlatform platform) {
|
||||
super(platform);
|
||||
this.historyDdl = new YugabyteHistoryDdl();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Column> sortColumns(List<Column> columns) {
|
||||
return columns;
|
||||
}
|
||||
}
|
||||
|
||||
+45
-3
@@ -1,18 +1,60 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.platform.postgres.PostgresPlatform;
|
||||
import io.ebeaninternal.dbmigration.migration.Column;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class PostgresDdlTest {
|
||||
class PostgresDdlTest {
|
||||
|
||||
private PostgresDdl postgresDdl = new PostgresDdl(new PostgresPlatform());
|
||||
|
||||
@Test
|
||||
public void setLockTimeout() {
|
||||
|
||||
void setLockTimeout() {
|
||||
final String sql = postgresDdl.setLockTimeout(5);
|
||||
assertThat(sql).isEqualTo("set lock_timeout = 5000");
|
||||
}
|
||||
|
||||
@Test
|
||||
void sortColumns_noAdjustment() {
|
||||
List<Column> cols = postgresDdl.sortColumns(columns("integer", "bigint"));
|
||||
assertThat(cols).extracting("type").containsExactly("integer", "bigint");
|
||||
|
||||
List<Column> colsReverse = postgresDdl.sortColumns(columns("bigint", "integer"));
|
||||
assertThat(colsReverse).extracting("type").containsExactly("bigint", "integer");
|
||||
}
|
||||
|
||||
@Test
|
||||
void sortColumns_decimalVarchar() {
|
||||
List<Column> cols = postgresDdl.sortColumns(columns("decimal(1)", "varchar(1)", "varchar(2)", "int", "decimal(2)"));
|
||||
assertThat(cols).extracting("type").containsExactly("int", "decimal(1)", "decimal(2)", "varchar(1)", "varchar(2)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void sortColumns_varbinary() {
|
||||
List<Column> cols = postgresDdl.sortColumns(columns("decimal(1)", "varbinary(1)", "varbinary(2)", "int", "decimal(2)"));
|
||||
assertThat(cols).extracting("type").containsExactly("int", "decimal(1)", "decimal(2)", "varbinary(1)", "varbinary(2)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void sortColumns_clobs() {
|
||||
List<Column> cols = postgresDdl.sortColumns(columns("clob", "blob", "longvarchar(1)", "int", "longvarbinary(2)"));
|
||||
assertThat(cols).extracting("type").containsExactly("int", "clob", "blob", "longvarchar(1)", "longvarbinary(2)");
|
||||
}
|
||||
|
||||
private List<Column> columns(String... types) {
|
||||
int counter = 0;
|
||||
List<Column> cols = new ArrayList<>();
|
||||
for (String s : types) {
|
||||
Column col = new Column();
|
||||
col.setName("c" + counter++);
|
||||
col.setType(s);
|
||||
cols.add(col);
|
||||
}
|
||||
return cols;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -16,7 +16,7 @@ import java.io.IOException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ModelBuild_explicitSequencesTest extends BaseTestCase {
|
||||
class ModelBuild_explicitSequencesTest extends BaseTestCase {
|
||||
|
||||
private SpiEbeanServer createServer(boolean postgres) {
|
||||
|
||||
@@ -38,7 +38,7 @@ public class ModelBuild_explicitSequencesTest extends BaseTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws IOException {
|
||||
void test() throws IOException {
|
||||
SpiEbeanServer ebeanServer = createServer(false);
|
||||
try {
|
||||
CurrentModel currentModel = new CurrentModel(ebeanServer);
|
||||
@@ -54,7 +54,7 @@ public class ModelBuild_explicitSequencesTest extends BaseTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_asPostgres() throws IOException {
|
||||
void test_asPostgres() throws IOException {
|
||||
SpiEbeanServer ebeanServer = createServer(true);
|
||||
try {
|
||||
CurrentModel currentModel = new CurrentModel(ebeanServer);
|
||||
|
||||
+1
-1
@@ -7,8 +7,8 @@ create table PERSONS (
|
||||
|
||||
create table PHONES (
|
||||
id bigint generated by default as identity not null,
|
||||
phone_number varchar(7) not null,
|
||||
person_id bigint not null,
|
||||
phone_number varchar(7) not null,
|
||||
constraint uq_phones_phone_number unique (phone_number),
|
||||
constraint pk_phones primary key (id)
|
||||
);
|
||||
|
||||
@@ -14,9 +14,9 @@ create table migtest_ckey_detail (
|
||||
|
||||
create table migtest_ckey_parent (
|
||||
one_key integer not null,
|
||||
version integer not null,
|
||||
two_key varchar(127) not null,
|
||||
name varchar(255),
|
||||
version integer not null,
|
||||
constraint pk_migtest_ckey_parent primary key (one_key,two_key)
|
||||
);
|
||||
|
||||
@@ -56,10 +56,6 @@ create table migtest_fk_set_null (
|
||||
|
||||
create table migtest_e_basic (
|
||||
id integer generated by default as identity not null,
|
||||
status varchar(1),
|
||||
status2 varchar(1) default 'N' not null,
|
||||
name varchar(127),
|
||||
description varchar(127),
|
||||
description_file bytea,
|
||||
json_list json,
|
||||
a_lob varchar(255) default 'X' not null,
|
||||
@@ -67,13 +63,17 @@ create table migtest_e_basic (
|
||||
old_boolean boolean default false not null,
|
||||
old_boolean2 boolean,
|
||||
eref_id integer,
|
||||
user_id integer not null,
|
||||
status varchar(1),
|
||||
status2 varchar(1) default 'N' not null,
|
||||
name varchar(127),
|
||||
description varchar(127),
|
||||
indextest1 varchar(127),
|
||||
indextest2 varchar(127),
|
||||
indextest3 varchar(127),
|
||||
indextest4 varchar(127),
|
||||
indextest5 varchar(127),
|
||||
indextest6 varchar(127),
|
||||
user_id integer not null,
|
||||
constraint ck_migtest_e_basic_status check ( status in ('N','A','I')),
|
||||
constraint ck_migtest_e_basic_status2 check ( status2 in ('N','A','I')),
|
||||
constraint uq_migtest_e_basic_indextest2 unique (indextest2),
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
1014378814, 1.0__initial.sql
|
||||
2094204208, 1.0__initial.sql
|
||||
-2047324426, 1.1.sql
|
||||
-261111052, 1.2__dropsFor_1.1.sql
|
||||
1335621453, 1.3.sql
|
||||
|
||||
@@ -14,9 +14,9 @@ create table migtest_ckey_detail (
|
||||
|
||||
create table migtest_ckey_parent (
|
||||
one_key integer not null,
|
||||
version integer not null,
|
||||
two_key varchar(127) not null,
|
||||
name varchar(255),
|
||||
version integer not null,
|
||||
constraint pk_migtest_ckey_parent primary key (one_key,two_key)
|
||||
);
|
||||
|
||||
@@ -56,10 +56,6 @@ create table migtest_fk_set_null (
|
||||
|
||||
create table migtest_e_basic (
|
||||
id serial not null,
|
||||
status varchar(1),
|
||||
status2 varchar(1) default 'N' not null,
|
||||
name varchar(127),
|
||||
description varchar(127),
|
||||
description_file bytea,
|
||||
json_list json,
|
||||
a_lob varchar(255) default 'X' not null,
|
||||
@@ -67,13 +63,17 @@ create table migtest_e_basic (
|
||||
old_boolean boolean default false not null,
|
||||
old_boolean2 boolean,
|
||||
eref_id integer,
|
||||
user_id integer not null,
|
||||
status varchar(1),
|
||||
status2 varchar(1) default 'N' not null,
|
||||
name varchar(127),
|
||||
description varchar(127),
|
||||
indextest1 varchar(127),
|
||||
indextest2 varchar(127),
|
||||
indextest3 varchar(127),
|
||||
indextest4 varchar(127),
|
||||
indextest5 varchar(127),
|
||||
indextest6 varchar(127),
|
||||
user_id integer not null,
|
||||
constraint ck_migtest_e_basic_status check ( status in ('N','A','I')),
|
||||
constraint ck_migtest_e_basic_status2 check ( status2 in ('N','A','I')),
|
||||
constraint uq_migtest_e_basic_indextest2 unique (indextest2),
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
382349675, 1.0__initial.sql
|
||||
-231429368, 1.0__initial.sql
|
||||
-606251140, 1.1.sql
|
||||
-261111052, 1.2__dropsFor_1.1.sql
|
||||
-893728811, 1.3.sql
|
||||
|
||||
Reference in New Issue
Block a user