Compare commits

..
Author SHA1 Message Date
Rob Bygrave b6b666013e ClickHouse: Support optimised inserts for ClickHouse 2024-04-17 22:50:28 +12:00
32 changed files with 499 additions and 153 deletions
@@ -199,12 +199,21 @@ public class DatabasePlatform {
protected SqlExceptionTranslator exceptionTranslator = new SqlCodeTranslator();
protected InsertSqlSyntaxExtension insertSqlSyntaxExtension = new StandardInsertSqlSyntax();
/**
* Instantiates a new database platform.
*/
public DatabasePlatform() {
}
/**
* Return the Insert SQL syntax helper.
*/
public InsertSqlSyntaxExtension insertSqlSyntaxExtension() {
return insertSqlSyntaxExtension;
}
/**
* Translate the SQLException into a specific persistence exception if possible.
*/
@@ -0,0 +1,32 @@
package io.ebean.config.dbplatform;
/**
* Insert SQL syntax to allow support for ClickHouse type optimisation for inserts.
*/
public interface InsertSqlSyntaxExtension {
/**
* Start the columns.
*/
String startColumns();
/**
* End of the columns.
*/
String endColumns();
/**
* Return true for insert to use standard binding.
*/
boolean useBinding();
/**
* Start types for non-standard binding (e.g. ClickHouse).
*/
String startTypes();
/**
* End types for non-standard binding (e.g. ClickHouse).
*/
String endTypes();
}
@@ -0,0 +1,32 @@
package io.ebean.config.dbplatform;
/**
* Standard Insert SQL syntax.
*/
public final class StandardInsertSqlSyntax implements InsertSqlSyntaxExtension {
@Override
public String startColumns() {
return " (";
}
@Override
public String endColumns() {
return ") values (";
}
@Override
public boolean useBinding() {
return true;
}
@Override
public String startTypes() {
throw new IllegalStateException();
}
@Override
public String endTypes() {
throw new IllegalStateException();
}
}
@@ -5,6 +5,7 @@ import io.ebean.DatabaseBuilder;
import io.ebean.Model;
import io.ebean.RawSqlBuilder;
import io.ebean.annotation.ConstraintMode;
import io.ebean.annotation.Platform;
import io.ebean.bean.BeanCollection;
import io.ebean.bean.EntityBean;
import io.ebean.config.*;
@@ -632,6 +633,8 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
}
private void registerDescriptor(DeployBeanInfo<?> info) {
platformUsesColumnDefinitions(info);
BeanDescriptor<?> desc = new BeanDescriptor<>(this, info.getDescriptor());
descMap.put(desc.type().getName(), desc);
if (desc.isDocStoreMapped()) {
@@ -644,6 +647,23 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
}
}
private void platformUsesColumnDefinitions(DeployBeanInfo<?> info) {
if (databasePlatform.isPlatform(Platform.CLICKHOUSE) && !DbOffline.isGenerateMigration()) {
// ClickHouse uses column definition to optimise JDBC bulk inserts
DbPlatformTypeMapping typeMapping = databasePlatform.dbTypeMap();
for (DeployBeanProperty property : info.getDescriptor().propertiesAll()) {
if (property.getDbColumnDefn() == null) {
DbPlatformType dbPlatformType = typeMapping.get(property.getDbType());
String columnDefn = dbPlatformType.renderType(property.getDbLength(), property.getDbScale());
if (property.isNullable()) {
columnDefn = "Nullable(" + columnDefn + ")";
}
property.setDbColumnDefn(columnDefn);
}
}
}
}
/**
* Read the initial deployment information for the entities.
* <p>
@@ -43,6 +43,11 @@ public interface ImportedId {
*/
void dmlAppend(GenerateDmlRequest request);
/**
* Append column and type for Insert (ClickHouse).
*/
void dmlType(GenerateDmlRequest request);
/**
* Bind the value from the bean.
*/
@@ -66,6 +66,16 @@ public final class ImportedIdEmbedded implements ImportedId {
}
}
@Override
public void dmlType(GenerateDmlRequest request) {
boolean update = request.isUpdate();
for (ImportedIdSimple anImported : imported) {
if (anImported.isInclude(update)) {
anImported.dmlType(request);
}
}
}
@Override
public String importedIdClause() {
StringBuilder sb = new StringBuilder();
@@ -37,6 +37,7 @@ public final class ImportedIdSimple implements ImportedId, Comparable<ImportedId
final BeanPropertyAssoc<?> owner;
final String localDbColumn;
private final String localColumnDefn;
private final String localSqlFormula;
final BeanProperty foreignProperty;
private final int position;
@@ -49,6 +50,7 @@ public final class ImportedIdSimple implements ImportedId, Comparable<ImportedId
this.localDbColumn = InternString.intern(localDbColumn);
this.localSqlFormula = InternString.intern(localSqlFormula);
this.foreignProperty = foreignProperty;
this.localColumnDefn = foreignProperty.dbColumnDefn();
this.position = position;
this.insertable = insertable;
this.updateable = updateable;
@@ -143,6 +145,11 @@ public final class ImportedIdSimple implements ImportedId, Comparable<ImportedId
request.appendColumn(localDbColumn);
}
@Override
public void dmlType(GenerateDmlRequest request) {
request.appendColumnDefn(localDbColumn, localColumnDefn);
}
@Override
public String importedIdClause() {
return localDbColumn + " = ?";
@@ -15,14 +15,26 @@ public final class GenerateDmlRequest {
private String prefix2;
private int insertMode;
private int bindColumnCount;
private boolean hasColumnDefn;
GenerateDmlRequest append(String s) {
sb.append(s);
return this;
}
/**
* Append column and type for Insert (ClickHouse).
*/
public void appendColumnDefn(String columnName, String columnDefn) {
if (hasColumnDefn) {
sb.append(", ");
} else {
hasColumnDefn = true;
}
sb.append(columnName).append(' ').append(columnDefn);
}
public void appendColumn(String column) {
//String bind = (insertMode > 0) ? "?" : "=?";
appendColumn(column, "?");
}
@@ -4,6 +4,7 @@ import io.ebean.InsertOptions;
import io.ebean.annotation.Platform;
import io.ebean.bean.EntityBean;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.config.dbplatform.InsertSqlSyntaxExtension;
import io.ebeaninternal.server.core.PersistRequestBean;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.deploy.InheritInfo;
@@ -37,10 +38,13 @@ final class InsertMeta {
private final Bindable shadowFKey;
private final String[] identityDbColumns;
private final Platform platform;
private final InsertSqlSyntaxExtension insertMetaSql;
private final InsertMetaOptions options;
InsertMeta(DatabasePlatform dbPlatform, BeanDescriptor<?> desc, Bindable shadowFKey, BindableId id, BindableList all) {
this.platform = dbPlatform.platform();
this.insertMetaSql = dbPlatform.insertSqlSyntaxExtension();
this.options = InsertMetaPlatform.create(platform, desc, this);
this.discriminator = discriminator(desc);
this.id = id;
@@ -174,7 +178,7 @@ final class InsertMeta {
request.append(defaultValues());
return;
}
request.append(" (");
request.append(insertMetaSql.startColumns());
if (!nullId) {
id.dmlAppend(request);
}
@@ -189,9 +193,28 @@ final class InsertMeta {
} else {
allExcludeDraftOnly.dmlAppend(request);
}
request.append(") values (");
request.append(request.insertBindBuffer());
request.append(")");
request.append(insertMetaSql.endColumns());
if (insertMetaSql.useBinding()) {
request.append(request.insertBindBuffer());
request.append(")");
} else {
request.append(insertMetaSql.startTypes());
if (!nullId) {
id.dmlType(request);
}
if (shadowFKey != null) {
shadowFKey.dmlType(request);
}
if (discriminator != null) {
discriminator.dmlType(request);
}
if (draftTable) {
all.dmlType(request);
} else {
allExcludeDraftOnly.dmlType(request);
}
request.append(insertMetaSql.endTypes());
}
}
private String defaultValues() {
@@ -33,6 +33,11 @@ public interface Bindable {
*/
void dmlAppend(GenerateDmlRequest request);
/**
* Append column and type for Insert (ClickHouse).
*/
void dmlType(GenerateDmlRequest request);
/**
* Bind given the request and bean. The bean could be the oldValues bean
* when binding a update or delete where clause with ALL concurrency mode.
@@ -40,6 +40,11 @@ class BindableAssocOne implements Bindable {
importedId.dmlAppend(request);
}
@Override
public void dmlType(GenerateDmlRequest request) {
importedId.dmlType(request);
}
@Override
public void dmlBind(BindableRequest request, EntityBean bean) throws SQLException {
EntityBean assocBean = (EntityBean) assocOne.getValue(bean);
@@ -39,6 +39,11 @@ public final class BindableDiscriminator implements Bindable {
request.appendColumn(columnName);
}
@Override
public void dmlType(GenerateDmlRequest request) {
throw new IllegalArgumentException("Not supported");
}
@Override
public void dmlBind(BindableRequest bindRequest, EntityBean bean) throws SQLException {
bindRequest.bind(discValue, sqlType);
@@ -35,6 +35,13 @@ final class BindableEmbedded implements Bindable {
}
}
@Override
public void dmlType(GenerateDmlRequest request) {
for (Bindable item : items) {
item.dmlType(request);
}
}
@Override
public void addToUpdate(PersistRequestBean<?> request, List<Bindable> list) {
if (request.isAddToUpdate(embProp)) {
@@ -41,6 +41,11 @@ final class BindableEncryptedProperty implements Bindable {
request.appendColumn(prop.dbColumn(), prop.dbBind());
}
@Override
public void dmlType(GenerateDmlRequest request) {
request.appendColumnDefn(prop.dbColumn(), prop.dbColumnDefn());
}
@Override
public void dmlBind(BindableRequest request, EntityBean bean) throws SQLException {
Object value = null;
@@ -81,6 +81,13 @@ final class BindableIdEmbedded implements BindableId {
}
}
@Override
public void dmlType(GenerateDmlRequest request) {
for (BeanProperty prop : props) {
request.appendColumn(prop.dbColumnDefn());
}
}
@Override
public boolean deriveConcatenatedId(PersistRequestBean<?> persist) {
if (matches == null) {
@@ -28,6 +28,11 @@ final class BindableIdEmpty implements BindableId {
// nothing
}
@Override
public void dmlType(GenerateDmlRequest request) {
// nothing
}
@Override
public void dmlBind(BindableRequest request, EntityBean bean) {
// nothing
@@ -58,17 +58,18 @@ final class BindableIdScalar implements BindableId {
@Override
public void dmlAppend(GenerateDmlRequest request) {
request.appendColumn(uidProp.dbColumn());
}
@Override
public void dmlType(GenerateDmlRequest request) {
request.appendColumnDefn(uidProp.dbColumn(), uidProp.dbColumnDefn());
}
@Override
public void dmlBind(BindableRequest request, EntityBean bean) throws SQLException {
Object value = uidProp.getValue(bean);
request.bind(value, uidProp);
// used for summary logging
request.setIdValue(value);
}
@@ -60,6 +60,13 @@ public final class BindableList implements Bindable {
}
}
@Override
public void dmlType(GenerateDmlRequest request) {
for (Bindable item : items) {
item.dmlType(request);
}
}
@Override
public void dmlBind(BindableRequest bindRequest, EntityBean bean) throws SQLException {
for (Bindable item : items) {
@@ -36,6 +36,11 @@ class BindableProperty implements Bindable {
request.appendColumn(prop.dbColumn());
}
@Override
public void dmlType(GenerateDmlRequest request) {
request.appendColumnDefn(prop.dbColumn(), prop.dbColumnDefn());
}
/**
* Normal binding of a property value from the bean.
*/
@@ -41,6 +41,11 @@ final class BindablePropertyVersion implements Bindable {
request.appendColumn(prop.dbColumn());
}
@Override
public void dmlType(GenerateDmlRequest request) {
request.appendColumnDefn(prop.dbColumn(), prop.dbColumnDefn());
}
/**
* Normal binding of a property value from the bean.
*/
@@ -45,6 +45,11 @@ public final class BindableUnidirectional implements Bindable {
importedId.dmlAppend(request);
}
@Override
public void dmlType(GenerateDmlRequest request) {
importedId.dmlType(request);
}
@Override
public void dmlBind(BindableRequest request, EntityBean bean) throws SQLException {
PersistRequestBean<?> persistRequest = request.persistRequest();
@@ -5,6 +5,7 @@ import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlHandler;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
import io.ebeaninternal.dbmigration.migration.Column;
public class ClickHouseDdl extends PlatformDdl {
@@ -17,6 +18,16 @@ public class ClickHouseDdl extends PlatformDdl {
this.columnNotNull = null;
}
@Override
protected String columnDefn(Column column) {
String defn = super.columnDefn(column);
if (isTrue(column.isNotnull()) || isTrue(column.isPrimaryKey())) {
return defn;
} else {
return "Nullable(" + defn + ")";
}
}
@Override
public DdlHandler createDdlHandler(DatabaseBuilder.Settings config) {
return new ClickHouseDdlHandler(config, this);
@@ -230,13 +230,13 @@ public class PlatformDdl {
* Write the column definition to the create table statement.
*/
protected void writeColumnDefinition(DdlBuffer buffer, Column column, DdlIdentity identity) {
String columnDefn = convert(column.getType());
buffer.append(" ");
buffer.append(quote(column.getName()), 29);
String columnDefn = columnDefn(column);
if (identity.useIdentity() && isTrue(column.isPrimaryKey())) {
columnDefn = asIdentityColumn(columnDefn, identity);
}
buffer.append(" ");
buffer.append(quote(column.getName()), 29);
buffer.append(columnDefn);
if (!Boolean.TRUE.equals(column.isPrimaryKey())) {
String defaultValue = convertDefaultValue(column.getDefaultValue());
@@ -251,6 +251,13 @@ public class PlatformDdl {
// so that the database can potentially provide a nice SQL error
}
/**
* Return the plaform specific column type definition.
*/
protected String columnDefn(Column column) {
return convert(column.getType());
}
/**
* Returns the check constraint.
*/
@@ -0,0 +1,28 @@
package io.ebeaninternal.dbmigration;
import io.ebean.platform.clickhouse.ClickHousePlatform;
import io.ebeaninternal.dbmigration.ddlgeneration.PlatformDdlBuilder;
import io.ebeaninternal.dbmigration.ddlgeneration.platform.PlatformDdl;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class ClickHousePlatformTest {
@Test
void testTypeConversion() {
PlatformDdl ddl = PlatformDdlBuilder.create(new ClickHousePlatform());
assertThat(ddl.convert("clob")).isEqualTo("String");
assertThat(ddl.convert("varchar(20)")).isEqualTo("String");
assertThat(ddl.convert("json")).isEqualTo("JSON");
assertThat(ddl.convert("jsonb")).isEqualTo("JSON");
assertThat(ddl.convert("decimal(10)")).isEqualTo("Decimal(10)");
assertThat(ddl.convert("decimal(8,4)")).isEqualTo("Decimal(8,4)");
assertThat(ddl.convert("decimal")).isEqualTo("Decimal(16,3)");
assertThat(ddl.convert("boolean")).isEqualTo("Bool");
assertThat(ddl.convert("bit")).isEqualTo("bit");
}
}
@@ -0,0 +1,56 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.platform.clickhouse.ClickHousePlatform;
import io.ebeaninternal.dbmigration.migration.Column;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class ClickHouseDdlTest {
private final ClickHouseDdl ddl = new ClickHouseDdl(new ClickHousePlatform());
@Test
void convert() {
assertThat(ddl.convert("boolean")).isEqualTo("Bool");
assertThat(ddl.convert("integer")).isEqualTo("UInt32");
assertThat(ddl.convert("bigint")).isEqualTo("UInt64");
assertThat(ddl.convert("decimal(20,3)")).isEqualTo("Decimal(20,3)");
assertThat(ddl.convert("varchar(20)")).isEqualTo("String");
assertThat(ddl.convert("hstore")).isEqualTo("Map(String,String)");
assertThat(ddl.convert("json")).isEqualTo("JSON");
assertThat(ddl.convert("varchar[]")).isEqualTo("Array(String)");
}
@Test
void columnDefnNullable() {
Column column = new Column();
column.setType("varchar(20)");
column.setNotnull(null);
assertThat(ddl.columnDefn(column)).isEqualTo("Nullable(String)");
}
@Test
void columnDefnNullable2() {
Column column = new Column();
column.setType("varchar(20)");
column.setNotnull(Boolean.FALSE);
assertThat(ddl.columnDefn(column)).isEqualTo("Nullable(String)");
}
@Test
void columnDefnNotNull() {
Column column = new Column();
column.setType("varchar(20)");
column.setNotnull(Boolean.TRUE);
assertThat(ddl.columnDefn(column)).isEqualTo("String");
}
@Test
void columnDefnNotNullPrimaryKey() {
Column column = new Column();
column.setType("varchar(20)");
column.setPrimaryKey(Boolean.TRUE);
assertThat(ddl.columnDefn(column)).isEqualTo("String");
}
}
@@ -123,8 +123,8 @@ class DbTypeMapTest {
assertThat(dbTypeMap.lookup("varchar", true).renderType(20, 0)).isEqualTo("String");
assertThat(dbTypeMap.lookup("timestamp", false).renderType(0, 0)).isEqualTo("DateTime");
assertThat(dbTypeMap.lookup("localdatetime", false).renderType(0, 0)).isEqualTo("DateTime");
assertThat(dbTypeMap.lookup("json", false).renderType(0, 0)).isEqualTo("String");
assertThat(dbTypeMap.lookup("jsonb", false).renderType(0, 0)).isEqualTo("String");
assertThat(dbTypeMap.lookup("json", false).renderType(0, 0)).isEqualTo("JSON");
assertThat(dbTypeMap.lookup("jsonb", false).renderType(0, 0)).isEqualTo("JSON");
assertThat(dbTypeMap.lookup("jsonclob", false).renderType(0, 0)).isEqualTo("String");
assertThat(dbTypeMap.lookup("jsonblob", false).renderType(0, 0)).isEqualTo("blob");
assertThat(dbTypeMap.lookup("jsonvarchar", false).renderType(200, 0)).isEqualTo("String");
@@ -2,24 +2,24 @@
-- apply changes
create table migtest_ckey_assoc (
id UInt32,
assoc_one String
assoc_one Nullable(String)
) ENGINE = Log();
create table migtest_ckey_detail (
id UInt32,
something String
something Nullable(String)
) ENGINE = Log();
create table migtest_ckey_parent (
one_key UInt32,
two_key String,
name String,
name Nullable(String),
version UInt32
) ENGINE = Log();
create table migtest_fk_cascade (
id UInt64,
one_id UInt64
one_id Nullable(UInt64)
) ENGINE = Log();
create table migtest_fk_cascade_one (
@@ -28,12 +28,12 @@ create table migtest_fk_cascade_one (
create table migtest_fk_none (
id UInt64,
one_id UInt64
one_id Nullable(UInt64)
) ENGINE = Log();
create table migtest_fk_none_via_join (
id UInt64,
one_id UInt64
one_id Nullable(UInt64)
) ENGINE = Log();
create table migtest_fk_one (
@@ -42,73 +42,73 @@ create table migtest_fk_one (
create table migtest_fk_set_null (
id UInt64,
one_id UInt64
one_id Nullable(UInt64)
) ENGINE = Log();
create table migtest_e_basic (
id UInt32,
status String,
status Nullable(String),
status2 String default 'N',
name String,
description String,
description_file blob,
json_list String,
name Nullable(String),
description Nullable(String),
description_file Nullable(blob),
json_list Nullable(JSON),
a_lob String default 'X',
some_date DateTime,
old_boolean UInt8 default 0,
old_boolean2 UInt8,
eref_id UInt32,
indextest1 String,
indextest2 String,
indextest3 String,
indextest4 String,
indextest5 String,
indextest6 String,
some_date Nullable(DateTime),
old_boolean Bool default false,
old_boolean2 Nullable(Bool),
eref_id Nullable(UInt32),
indextest1 Nullable(String),
indextest2 Nullable(String),
indextest3 Nullable(String),
indextest4 Nullable(String),
indextest5 Nullable(String),
indextest6 Nullable(String),
user_id UInt32
) ENGINE = Log();
create table migtest_e_enum (
id UInt32,
test_status String
test_status Nullable(String)
) ENGINE = Log();
create table migtest_e_history (
id UInt32,
test_string String
test_string Nullable(String)
) ENGINE = Log();
create table migtest_e_history2 (
id UInt32,
test_string String,
obsolete_string1 String,
obsolete_string2 String
test_string Nullable(String),
obsolete_string1 Nullable(String),
obsolete_string2 Nullable(String)
) ENGINE = Log();
create table migtest_e_history3 (
id UInt32,
test_string String
test_string Nullable(String)
) ENGINE = Log();
create table migtest_e_history4 (
id UInt32,
test_number UInt32
test_number Nullable(UInt32)
) ENGINE = Log();
create table migtest_e_history5 (
id UInt32,
test_number UInt32
test_number Nullable(UInt32)
) ENGINE = Log();
create table migtest_e_history6 (
id UInt32,
test_number1 UInt32,
test_number1 Nullable(UInt32),
test_number2 UInt32
) ENGINE = Log();
create table "migtest_QuOtEd" (
id String,
status1 String,
status2 String
status1 Nullable(String),
status2 Nullable(String)
) ENGINE = Log();
create table migtest_e_ref (
@@ -118,35 +118,35 @@ create table migtest_e_ref (
create table migtest_e_softdelete (
id UInt32,
test_string String
test_string Nullable(String)
) ENGINE = Log();
create table "table" (
"index" String,
"from" String,
"to" String,
"varchar" String,
"foreign" String,
"from" Nullable(String),
"to" Nullable(String),
"varchar" Nullable(String),
"foreign" Nullable(String),
textfield String
) ENGINE = Log();
create table migtest_mtm_c (
id UInt32,
name String
name Nullable(String)
) ENGINE = Log();
create table migtest_mtm_m (
id UInt64,
name String
name Nullable(String)
) ENGINE = Log();
create table migtest_oto_child (
id UInt32,
name String
name Nullable(String)
) ENGINE = Log();
create table migtest_oto_master (
id UInt64,
name String
name Nullable(String)
) ENGINE = Log();
@@ -21,104 +21,104 @@ create table drop_ref_many (
create table drop_ref_one (
id UInt32,
parent_id UInt32
parent_id Nullable(UInt32)
) ENGINE = Log();
create table drop_ref_one_to_one (
id UInt32,
parent_id UInt32
parent_id Nullable(UInt32)
) ENGINE = Log();
create table migtest_e_test_binary (
id UInt32,
test_byte16 String,
test_byte256 String,
test_byte512 String,
test_byte1k String,
test_byte2k String,
test_byte4k String,
test_byte8k String,
test_byte16k String,
test_byte32k String,
test_byte64k String,
test_byte128k String,
test_byte256k String,
test_byte512k String,
test_byte1m String,
test_byte2m String,
test_byte4m String,
test_byte8m String,
test_byte16m String,
test_byte32m String
test_byte16 Nullable(String),
test_byte256 Nullable(String),
test_byte512 Nullable(String),
test_byte1k Nullable(String),
test_byte2k Nullable(String),
test_byte4k Nullable(String),
test_byte8k Nullable(String),
test_byte16k Nullable(String),
test_byte32k Nullable(String),
test_byte64k Nullable(String),
test_byte128k Nullable(String),
test_byte256k Nullable(String),
test_byte512k Nullable(String),
test_byte1m Nullable(String),
test_byte2m Nullable(String),
test_byte4m Nullable(String),
test_byte8m Nullable(String),
test_byte16m Nullable(String),
test_byte32m Nullable(String)
) ENGINE = Log();
create table migtest_e_test_json (
id UInt32,
json255 String,
json256 String,
json512 String,
json1k String,
json2k String,
json4k String,
json8k String,
json16k String,
json32k String,
json64k String,
json128k String,
json256k String,
json512k String,
json1m String,
json2m String,
json4m String,
json8m String,
json16m String,
json32m String
json255 Nullable(JSON),
json256 Nullable(JSON),
json512 Nullable(JSON),
json1k Nullable(JSON),
json2k Nullable(JSON),
json4k Nullable(JSON),
json8k Nullable(JSON),
json16k Nullable(JSON),
json32k Nullable(JSON),
json64k Nullable(JSON),
json128k Nullable(JSON),
json256k Nullable(JSON),
json512k Nullable(JSON),
json1m Nullable(JSON),
json2m Nullable(JSON),
json4m Nullable(JSON),
json8m Nullable(JSON),
json16m Nullable(JSON),
json32m Nullable(JSON)
) ENGINE = Log();
create table migtest_e_test_lob (
id UInt32,
lob255 String,
lob256 String,
lob512 String,
lob1k String,
lob2k String,
lob4k String,
lob8k String,
lob16k String,
lob32k String,
lob64k String,
lob128k String,
lob256k String,
lob512k String,
lob1m String,
lob2m String,
lob4m String,
lob8m String,
lob16m String,
lob32m String
lob255 Nullable(String),
lob256 Nullable(String),
lob512 Nullable(String),
lob1k Nullable(String),
lob2k Nullable(String),
lob4k Nullable(String),
lob8k Nullable(String),
lob16k Nullable(String),
lob32k Nullable(String),
lob64k Nullable(String),
lob128k Nullable(String),
lob256k Nullable(String),
lob512k Nullable(String),
lob1m Nullable(String),
lob2m Nullable(String),
lob4m Nullable(String),
lob8m Nullable(String),
lob16m Nullable(String),
lob32m Nullable(String)
) ENGINE = Log();
create table migtest_e_test_varchar (
id UInt32,
varchar255 String,
varchar256 String,
varchar512 String,
varchar1k String,
varchar2k String,
varchar4k String,
varchar8k String,
varchar16k String,
varchar32k String,
varchar64k String,
varchar128k String,
varchar256k String,
varchar512k String,
varchar1m String,
varchar2m String,
varchar4m String,
varchar8m String,
varchar16m String,
varchar32m String
varchar255 Nullable(String),
varchar256 Nullable(String),
varchar512 Nullable(String),
varchar1k Nullable(String),
varchar2k Nullable(String),
varchar4k Nullable(String),
varchar8k Nullable(String),
varchar16k Nullable(String),
varchar32k Nullable(String),
varchar64k Nullable(String),
varchar128k Nullable(String),
varchar256k Nullable(String),
varchar512k Nullable(String),
varchar1m Nullable(String),
varchar2m Nullable(String),
varchar4m Nullable(String),
varchar8m Nullable(String),
varchar16m Nullable(String),
varchar32m Nullable(String)
) ENGINE = Log();
create table migtest_e_user (
@@ -168,8 +168,8 @@ alter table migtest_e_basic alter column a_lob drop default;
alter table migtest_e_basic alter column a_lob set null;
alter table migtest_e_basic alter column user_id set null;
alter table migtest_e_basic add column new_string_field String default 'foo''bar';
alter table migtest_e_basic add column new_boolean_field UInt8 default 1;
alter table migtest_e_basic add column new_boolean_field2 UInt8 default 1;
alter table migtest_e_basic add column new_boolean_field Bool default true;
alter table migtest_e_basic add column new_boolean_field2 Bool default true;
alter table migtest_e_basic add column progress UInt32 default 0;
alter table migtest_e_basic add column new_integer UInt32 default 42;
alter table migtest_e_history alter column test_string UInt64;
@@ -179,11 +179,11 @@ alter table migtest_e_history2 add column test_string2 String;
alter table migtest_e_history2 add column test_string3 String default 'unknown';
alter table migtest_e_history2 add column new_column String;
alter table migtest_e_history4 alter column test_number UInt64;
alter table migtest_e_history5 add column test_boolean UInt8 default 0;
alter table migtest_e_history5 add column test_boolean Bool default false;
alter table migtest_e_history6 alter column test_number1 set default 42;
alter table migtest_e_history6 alter column test_number1 set not null;
alter table migtest_e_history6 alter column test_number2 set null;
alter table migtest_e_softdelete add column deleted UInt8 default 0;
alter table migtest_e_softdelete add column deleted Bool default false;
alter table migtest_oto_child add column master_id UInt64;
-- apply post alter
alter table migtest_e_basic add constraint ck_migtest_e_basic_status check ( status in ('N','A','I','?'));
@@ -11,8 +11,8 @@ alter table migtest_e_enum drop constraint if exists ck_migtest_e_enum_test_stat
-- apply changes
create table "migtest_QuOtEd" (
id String,
status1 String,
status2 String
status1 Nullable(String),
status2 Nullable(String)
) ENGINE = Log();
create table migtest_e_ref (
@@ -41,8 +41,8 @@ alter table migtest_e_basic alter column a_lob set not null;
alter table migtest_e_basic alter column user_id set default 23;
alter table migtest_e_basic alter column user_id set not null;
alter table migtest_e_basic add column description_file blob;
alter table migtest_e_basic add column old_boolean UInt8 default 0;
alter table migtest_e_basic add column old_boolean2 UInt8;
alter table migtest_e_basic add column old_boolean Bool default false;
alter table migtest_e_basic add column old_boolean2 Bool;
alter table migtest_e_basic add column eref_id UInt32;
alter table migtest_e_history2 alter column test_string drop default;
alter table migtest_e_history2 alter column test_string set null;
@@ -1,6 +1,6 @@
193400547, 1.0__initial.sql
-1021430823, 1.1.sql
1470313592, 1.0__initial.sql
-1717710527, 1.1.sql
688811494, 1.2__dropsFor_1.1.sql
1015552567, 1.3.sql
864347736, 1.3.sql
1436420661, 1.4__dropsFor_1.3.sql
@@ -0,0 +1,33 @@
package io.ebean.platform.clickhouse;
import io.ebean.config.dbplatform.InsertSqlSyntaxExtension;
public final class ClickHouseInsertSqlSyntax implements InsertSqlSyntaxExtension {
// insert into mytable select col1, col2 from input('col1 String, col2 DateTime64(3), col3 Int32')
@Override
public String startColumns() {
return " select ";
}
@Override
public String endColumns() {
return " from";
}
@Override
public boolean useBinding() {
return false;
}
@Override
public String startTypes() {
return " input('";
}
@Override
public String endTypes() {
return "')";
}
}
@@ -13,13 +13,9 @@ public class ClickHousePlatform extends DatabasePlatform {
public ClickHousePlatform() {
super();
this.platform = Platform.CLICKHOUSE;
//this.dbEncrypt =
//this.historySupport =
//this.exceptionTranslator =
this.insertSqlSyntaxExtension = new ClickHouseInsertSqlSyntax();
this.nativeUuidType = true;
this.dbDefaultValue.setNow("now()");
this.dbDefaultValue.setFalse("0");
this.dbDefaultValue.setTrue("1");
this.dbIdentity.setIdType(IdType.IDENTITY);
this.dbIdentity.setSupportsGetGeneratedKeys(false);
@@ -27,7 +23,7 @@ public class ClickHousePlatform extends DatabasePlatform {
this.dbIdentity.setSupportsIdentity(true);
this.booleanDbType = Types.INTEGER;
dbTypeMap.put(DbType.BOOLEAN, new DbPlatformType("UInt8"));
dbTypeMap.put(DbType.BOOLEAN, new DbPlatformType("Bool"));
// using unsigned as default types ...
dbTypeMap.put(DbType.TINYINT, new DbPlatformType("UInt8", false));
dbTypeMap.put(DbType.SMALLINT, new DbPlatformType("UInt16", false));
@@ -41,7 +37,10 @@ public class ClickHousePlatform extends DatabasePlatform {
dbTypeMap.put(DbType.VARCHAR, new DbPlatformType("String", false));
dbTypeMap.put(DbType.LONGVARCHAR, new DbPlatformType("String", false));
dbTypeMap.put(DbType.CLOB, new DbPlatformType("String", false));
dbTypeMap.put(DbType.JSONVARCHAR, new DbPlatformType("String", false));
dbTypeMap.put(DbType.HSTORE, new DbPlatformType("Map(String,String)", false));
dbTypeMap.put(DbType.JSON, new DbPlatformType("JSON", false));
dbTypeMap.put(DbType.JSONB, new DbPlatformType("JSON", false));
dbTypeMap.put(DbType.JSONVARCHAR, new DbPlatformType("JSON", false));
dbTypeMap.put(DbType.UUID, new DbPlatformType("UUID", false));
dbTypeMap.put(DbType.INET, new DbPlatformType("String", false));
dbTypeMap.put(DbType.CIDR, new DbPlatformType("String", false));