HHH-7797 Block "unique" syntax on a column if a constraint can/will be
used
This commit is contained in:
parent
c64b8bc4ae
commit
2ae841db66
|
@ -1977,6 +1977,11 @@ public abstract class Dialect implements ConversionContext {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does this dialect support columns that are both unique and not null.
|
||||||
|
*
|
||||||
|
* @return True if supported, false otherwise.
|
||||||
|
*/
|
||||||
public boolean supportsNotNullUnique() {
|
public boolean supportsNotNullUnique() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -423,10 +423,13 @@ public class Table implements RelationalModel, Serializable {
|
||||||
alter.append( " not null" );
|
alter.append( " not null" );
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean useUniqueConstraint = column.isUnique() &&
|
// If the column is 1.) unique, 2.) the dialect supports the
|
||||||
dialect.supportsUnique() &&
|
// unique syntax, 3.) the column is nullable or supports
|
||||||
( column.isNullable() || dialect.supportsNotNullUnique() );
|
// "not null unique", and 4.) a constraint will not be created
|
||||||
if ( useUniqueConstraint ) {
|
if ( column.isUnique() && dialect.supportsUnique()
|
||||||
|
&& ( column.isNullable()
|
||||||
|
|| dialect.supportsNotNullUnique() )
|
||||||
|
&& !dialect.supportsUniqueConstraintInCreateAlterTable() ) {
|
||||||
alter.append( " unique" );
|
alter.append( " unique" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -524,17 +527,21 @@ public class Table implements RelationalModel, Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean useUniqueConstraint = col.isUnique() &&
|
// If the column is 1.) unique and nullable or 2.) unique,
|
||||||
( col.isNullable() || dialect.supportsNotNullUnique() );
|
// not null, and the dialect supports unique not null
|
||||||
if ( useUniqueConstraint ) {
|
if ( col.isUnique()
|
||||||
if ( dialect.supportsUnique() ) {
|
&& ( col.isNullable()
|
||||||
buf.append( " unique" );
|
|| dialect.supportsNotNullUnique() ) ) {
|
||||||
}
|
if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) {
|
||||||
else {
|
// If the constraint is supported, do not add to the column syntax.
|
||||||
UniqueKey uk = getOrCreateUniqueKey( col.getQuotedName( dialect ) + '_' );
|
UniqueKey uk = getOrCreateUniqueKey( col.getQuotedName( dialect ) + '_' );
|
||||||
uk.addColumn( col );
|
uk.addColumn( col );
|
||||||
}
|
}
|
||||||
|
else if ( dialect.supportsUnique() ) {
|
||||||
|
// Otherwise, add to the column syntax if supported.
|
||||||
|
buf.append( " unique" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( col.hasCheckConstraint() && dialect.supportsColumnCheck() ) {
|
if ( col.hasCheckConstraint() && dialect.supportsColumnCheck() ) {
|
||||||
|
|
|
@ -35,23 +35,21 @@ import org.hibernate.engine.spi.Mapping;
|
||||||
public class UniqueKey extends Constraint {
|
public class UniqueKey extends Constraint {
|
||||||
|
|
||||||
public String sqlConstraintString(Dialect dialect) {
|
public String sqlConstraintString(Dialect dialect) {
|
||||||
|
// TODO: This may not be necessary, but not all callers currently
|
||||||
|
// check it on their own. Go through their logic.
|
||||||
|
if ( !isGenerated( dialect ) ) return null;
|
||||||
|
|
||||||
StringBuilder buf = new StringBuilder( "unique (" );
|
StringBuilder buf = new StringBuilder( "unique (" );
|
||||||
boolean hadNullableColumn = false;
|
|
||||||
Iterator iter = getColumnIterator();
|
Iterator iter = getColumnIterator();
|
||||||
while ( iter.hasNext() ) {
|
while ( iter.hasNext() ) {
|
||||||
Column column = (Column) iter.next();
|
Column column = (Column) iter.next();
|
||||||
if ( !hadNullableColumn && column.isNullable() ) {
|
|
||||||
hadNullableColumn = true;
|
|
||||||
}
|
|
||||||
buf.append( column.getQuotedName( dialect ) );
|
buf.append( column.getQuotedName( dialect ) );
|
||||||
if ( iter.hasNext() ) {
|
if ( iter.hasNext() ) {
|
||||||
buf.append( ", " );
|
buf.append( ", " );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//do not add unique constraint on DB not supporting unique and nullable columns
|
|
||||||
return !hadNullableColumn || dialect.supportsNotNullUnique() ?
|
return buf.append( ')' ).toString();
|
||||||
buf.append( ')' ).toString() :
|
|
||||||
null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -60,18 +58,19 @@ public class UniqueKey extends Constraint {
|
||||||
String constraintName,
|
String constraintName,
|
||||||
String defaultCatalog,
|
String defaultCatalog,
|
||||||
String defaultSchema) {
|
String defaultSchema) {
|
||||||
|
// TODO: This may not be necessary, but not all callers currently
|
||||||
|
// check it on their own. Go through their logic.
|
||||||
|
if ( !isGenerated( dialect ) ) return null;
|
||||||
|
|
||||||
StringBuilder buf = new StringBuilder(
|
StringBuilder buf = new StringBuilder(
|
||||||
dialect.getAddUniqueConstraintString( constraintName )
|
dialect.getAddUniqueConstraintString( constraintName ) ).append( '(' );
|
||||||
).append( '(' );
|
|
||||||
Iterator iter = getColumnIterator();
|
Iterator iter = getColumnIterator();
|
||||||
boolean nullable = false;
|
|
||||||
while ( iter.hasNext() ) {
|
while ( iter.hasNext() ) {
|
||||||
Column column = (Column) iter.next();
|
Column column = (Column) iter.next();
|
||||||
if ( !nullable && column.isNullable() ) nullable = true;
|
|
||||||
buf.append( column.getQuotedName( dialect ) );
|
buf.append( column.getQuotedName( dialect ) );
|
||||||
if ( iter.hasNext() ) buf.append( ", " );
|
if ( iter.hasNext() ) buf.append( ", " );
|
||||||
}
|
}
|
||||||
return !nullable || dialect.supportsNotNullUnique() ? buf.append( ')' ).toString() : null;
|
return buf.append( ')' ).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -97,12 +96,13 @@ public class UniqueKey extends Constraint {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isGenerated(Dialect dialect) {
|
public boolean isGenerated(Dialect dialect) {
|
||||||
|
if ( !dialect.supportsUniqueConstraintInCreateAlterTable() ) return false;
|
||||||
if ( dialect.supportsNotNullUnique() ) return true;
|
if ( dialect.supportsNotNullUnique() ) return true;
|
||||||
|
|
||||||
Iterator iter = getColumnIterator();
|
Iterator iter = getColumnIterator();
|
||||||
while ( iter.hasNext() ) {
|
while ( iter.hasNext() ) {
|
||||||
if ( ( (Column) iter.next() ).isNullable() ) {
|
// Dialect does not support "not null unique" and this column is not null.
|
||||||
return false;
|
if ( ! ( (Column) iter.next() ).isNullable() ) return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,16 +199,20 @@ public class Table extends AbstractTableSpecification implements Exportable {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean useUniqueConstraint = col.isUnique() &&
|
// If the column is 1.) unique and nullable or 2.) unique,
|
||||||
( col.isNullable() || dialect.supportsNotNullUnique() );
|
// not null, and the dialect supports unique not null
|
||||||
if ( useUniqueConstraint ) {
|
if ( col.isUnique()
|
||||||
if ( dialect.supportsUnique() ) {
|
&& ( col.isNullable()
|
||||||
buf.append( " unique" );
|
|| dialect.supportsNotNullUnique() ) ) {
|
||||||
}
|
if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) {
|
||||||
else {
|
// If the constraint is supported, do not add to the column syntax.
|
||||||
UniqueKey uk = getOrCreateUniqueKey( col.getColumnName().encloseInQuotesIfQuoted( dialect ) + '_' );
|
UniqueKey uk = getOrCreateUniqueKey( col.getColumnName().encloseInQuotesIfQuoted( dialect ) + '_' );
|
||||||
uk.addColumn( col );
|
uk.addColumn( col );
|
||||||
}
|
}
|
||||||
|
else if ( dialect.supportsUnique() ) {
|
||||||
|
// Otherwise, add to the column syntax if supported.
|
||||||
|
buf.append( " unique" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( col.getCheckCondition() != null && dialect.supportsColumnCheck() ) {
|
if ( col.getCheckCondition() != null && dialect.supportsColumnCheck() ) {
|
||||||
|
|
|
@ -48,21 +48,22 @@ public class UniqueKey extends AbstractConstraint implements Constraint {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCreationVetoed(Dialect dialect) {
|
public boolean isCreationVetoed(Dialect dialect) {
|
||||||
if ( dialect.supportsNotNullUnique() ) {
|
if ( !dialect.supportsUniqueConstraintInCreateAlterTable() ) return true;
|
||||||
return false;
|
if ( dialect.supportsNotNullUnique() ) return false;
|
||||||
}
|
|
||||||
|
|
||||||
for ( Column column : getColumns() ) {
|
for ( Column column : getColumns() ) {
|
||||||
if ( column.isNullable() ) {
|
// Dialect does not support "not null unique" and this column is not null.
|
||||||
return true;
|
if ( ! column.isNullable() ) return true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String sqlConstraintStringInCreateTable(Dialect dialect) {
|
public String sqlConstraintStringInCreateTable(Dialect dialect) {
|
||||||
|
// TODO: This may not be necessary, but not all callers currently
|
||||||
|
// check it on their own. Go through their logic.
|
||||||
|
if ( isCreationVetoed( dialect ) ) return null;
|
||||||
|
|
||||||
StringBuilder buf = new StringBuilder( "unique (" );
|
StringBuilder buf = new StringBuilder( "unique (" );
|
||||||
boolean hadNullableColumn = false;
|
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for ( Column column : getColumns() ) {
|
for ( Column column : getColumns() ) {
|
||||||
if ( first ) {
|
if ( first ) {
|
||||||
|
@ -71,23 +72,19 @@ public class UniqueKey extends AbstractConstraint implements Constraint {
|
||||||
else {
|
else {
|
||||||
buf.append( ", " );
|
buf.append( ", " );
|
||||||
}
|
}
|
||||||
if ( !hadNullableColumn && column.isNullable() ) {
|
|
||||||
hadNullableColumn = true;
|
|
||||||
}
|
|
||||||
buf.append( column.getColumnName().encloseInQuotesIfQuoted( dialect ) );
|
buf.append( column.getColumnName().encloseInQuotesIfQuoted( dialect ) );
|
||||||
}
|
}
|
||||||
//do not add unique constraint on DB not supporting unique and nullable columns
|
return buf.append( ')' ).toString();
|
||||||
return !hadNullableColumn || dialect.supportsNotNullUnique() ?
|
|
||||||
buf.append( ')' ).toString() :
|
|
||||||
null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String sqlConstraintStringInAlterTable(Dialect dialect) {
|
public String sqlConstraintStringInAlterTable(Dialect dialect) {
|
||||||
|
// TODO: This may not be necessary, but not all callers currently
|
||||||
|
// check it on their own. Go through their logic.
|
||||||
|
if ( isCreationVetoed( dialect ) ) return null;
|
||||||
|
|
||||||
StringBuilder buf = new StringBuilder(
|
StringBuilder buf = new StringBuilder(
|
||||||
dialect.getAddUniqueConstraintString( getName() )
|
dialect.getAddUniqueConstraintString( getName() ) ).append( '(' );
|
||||||
).append( '(' );
|
|
||||||
boolean nullable = false;
|
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for ( Column column : getColumns() ) {
|
for ( Column column : getColumns() ) {
|
||||||
if ( first ) {
|
if ( first ) {
|
||||||
|
@ -96,11 +93,8 @@ public class UniqueKey extends AbstractConstraint implements Constraint {
|
||||||
else {
|
else {
|
||||||
buf.append( ", " );
|
buf.append( ", " );
|
||||||
}
|
}
|
||||||
if ( !nullable && column.isNullable() ) {
|
|
||||||
nullable = true;
|
|
||||||
}
|
|
||||||
buf.append( column.getColumnName().encloseInQuotesIfQuoted( dialect ) );
|
buf.append( column.getColumnName().encloseInQuotesIfQuoted( dialect ) );
|
||||||
}
|
}
|
||||||
return !nullable || dialect.supportsNotNullUnique() ? buf.append( ')' ).toString() : null;
|
return buf.append( ')' ).toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue