-
Notifications
You must be signed in to change notification settings - Fork 1.8k
/
SetNullableGenerator.java
executable file
·143 lines (122 loc) · 9.27 KB
/
SetNullableGenerator.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package liquibase.sqlgenerator.core;
import liquibase.database.Database;
import liquibase.database.core.*;
import liquibase.datatype.DataTypeFactory;
import liquibase.exception.DatabaseException;
import liquibase.exception.ValidationErrors;
import liquibase.exception.Warnings;
import liquibase.sql.Sql;
import liquibase.sql.UnparsedSql;
import liquibase.sqlgenerator.SqlGeneratorChain;
import liquibase.sqlgenerator.SqlGeneratorFactory;
import liquibase.statement.core.AddDefaultValueStatement;
import liquibase.statement.core.ReorganizeTableStatement;
import liquibase.statement.core.SetNullableStatement;
import liquibase.structure.core.Column;
import liquibase.structure.core.Table;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class SetNullableGenerator extends AbstractSqlGenerator<SetNullableStatement> {
@Override
public boolean supports(SetNullableStatement statement, Database database) {
try {
if (database instanceof Db2zDatabase || (database instanceof DB2Database) && (database.getDatabaseMajorVersion() > 0 && database.getDatabaseMajorVersion() < 9)) {
//"DB2 versions less than 9 or z/OS do not support modifying null constraints";
return false;
}
} catch (DatabaseException ignore) {
//cannot check
}
return !(database instanceof SQLiteDatabase);
}
@Override
public ValidationErrors validate(SetNullableStatement setNullableStatement, Database database, SqlGeneratorChain sqlGeneratorChain) {
ValidationErrors validationErrors = new ValidationErrors();
validationErrors.checkRequiredField("tableName", setNullableStatement.getTableName());
if (setNullableStatement.isNullable()) {
if (database instanceof OracleDatabase) {
if (setNullableStatement.getConstraintName() == null && setNullableStatement.getColumnName() == null) {
validationErrors.addError("Oracle requires either constraintName or columnName to be set");
}
} else {
validationErrors.checkRequiredField("columnName", setNullableStatement.getColumnName());
}
} else {
validationErrors.checkRequiredField("columnName", setNullableStatement.getColumnName());
}
if ((database instanceof MSSQLDatabase) || (database instanceof MySQLDatabase) || (database instanceof InformixDatabase)) {
validationErrors.checkRequiredField("columnDataType", setNullableStatement.getColumnDataType());
}
return validationErrors;
}
@Override
public Warnings warn(SetNullableStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) {
Warnings warnings = super.warn(statement, database, sqlGeneratorChain);
if (database instanceof MySQLDatabase) {
((MySQLDatabase) database).warnAboutAlterColumn("setNullable", warnings);
}
return warnings;
}
@Override
public Sql[] generateSql(SetNullableStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) {
String sql;
String nullableString = statement.isNullable()?" NULL":" NOT NULL";
if ((database instanceof OracleDatabase) && (statement.getConstraintName() != null)) {
if (!statement.isNullable()) {
nullableString += !statement.isValidate() ? " ENABLE NOVALIDATE " : "";
sql = "ALTER TABLE " + database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName()) + " MODIFY " + database.escapeColumnName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName(), statement.getColumnName()) + " CONSTRAINT " + statement.getConstraintName() + nullableString;
} else {
sql = "ALTER TABLE " + database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName()) + " DROP CONSTRAINT " + statement.getConstraintName();
}
} else if ((database instanceof OracleDatabase) || (database instanceof SybaseDatabase) || (database
instanceof SybaseASADatabase)) {
nullableString += (database instanceof OracleDatabase)&&(!statement.isValidate()) ? " ENABLE NOVALIDATE " : "";
sql = "ALTER TABLE " + database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName()) + " MODIFY " + database.escapeColumnName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName(), statement.getColumnName()) + nullableString;
} else if (database instanceof MSSQLDatabase) {
sql = "ALTER TABLE " + database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName()) + " ALTER COLUMN " + database.escapeColumnName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName(), statement.getColumnName()) + " " + DataTypeFactory.getInstance().fromDescription(statement.getColumnDataType(), database).toDatabaseDataType(database) + nullableString;
} else if (database instanceof MySQLDatabase) {
sql = "ALTER TABLE " + database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName()) + " MODIFY " + database.escapeColumnName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName(), statement.getColumnName()) + " " + DataTypeFactory.getInstance().fromDescription(statement.getColumnDataType(), database).toDatabaseDataType(database) + nullableString;
} else if (database instanceof DerbyDatabase) {
sql = "ALTER TABLE " + database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName()) + " ALTER COLUMN " + database.escapeColumnName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName(), statement.getColumnName()) + nullableString;
} else if ((database instanceof HsqlDatabase) || (database instanceof H2Database)) {
sql = "ALTER TABLE " + database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName()) + " ALTER COLUMN " + database.escapeColumnName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName(), statement.getColumnName()) + " SET"+nullableString;
} else if (database instanceof InformixDatabase) {
// Informix simply omits the null for nullables
if (statement.isNullable()) {
nullableString = "";
}
sql = "ALTER TABLE " + database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName()) + " MODIFY (" + database.escapeColumnName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName(), statement.getColumnName()) + " " + DataTypeFactory.getInstance().fromDescription(statement.getColumnDataType(), database).toDatabaseDataType(database) + nullableString + ")";
} else {
final String standardSqlStatement = "ALTER TABLE " + database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName()) + " ALTER COLUMN " + database.escapeColumnName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName(), statement.getColumnName()) + (statement.isNullable() ? " DROP NOT NULL" : " SET NOT NULL");
if (database instanceof FirebirdDatabase) {
try {
if (database.getDatabaseMajorVersion() <= 2) {
// For Firebird database prior to Firebird 3 the ALTER TABLE syntax is not working
// As a workaround we can modify the system table entry directly (see http://www.firebirdfaq.org/faq103/)
sql = "UPDATE RDB$RELATION_FIELDS SET RDB$NULL_FLAG = " + (statement.isNullable() ? "NULL" : "1") + " WHERE RDB$RELATION_NAME = '" + database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName()) + "' AND RDB$FIELD_NAME = '" + database.escapeColumnName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName(), statement.getColumnName()) + "'";
} else {
sql = standardSqlStatement;
}
} catch (DatabaseException ignored) {
//assume it's firebird 3+
sql = standardSqlStatement;
}
} else {
sql = standardSqlStatement;
}
}
List<Sql> returnList = new ArrayList<>();
returnList.add(new UnparsedSql(sql, getAffectedColumn(statement)));
if (database instanceof DB2Database) {
Sql[] a = SqlGeneratorFactory.getInstance().generateSql(new ReorganizeTableStatement(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName()), database);
if (a != null) {
returnList.addAll(Arrays.asList(a));
}
}
return returnList.toArray(new Sql[returnList.size()]);
}
protected Column getAffectedColumn(SetNullableStatement statement) {
return new Column().setName(statement.getColumnName()).setRelation(new Table().setName(statement.getTableName()).setSchema(statement.getCatalogName(), statement.getSchemaName()));
}
}