HHH-8796 corrected MySQL index create/drop, corrected qualifyIndexName()

use
This commit is contained in:
Brett Meyer 2014-03-21 14:35:55 -04:00
parent 62704e4daa
commit 9504c102cf
8 changed files with 176 additions and 19 deletions

View File

@ -436,4 +436,9 @@ public class H2Dialect extends Dialect {
public String getCurrentSchemaCommand() {
return "call schema()";
}
@Override
public boolean qualifyIndexName() {
return false;
}
}

View File

@ -688,4 +688,9 @@ public class HSQLDialect extends Dialect {
public String getCascadeConstraintsString() {
return " CASCADE ";
}
@Override
public boolean qualifyIndexName() {
return false;
}
}

View File

@ -31,6 +31,8 @@ import java.sql.Types;
import org.hibernate.JDBCException;
import org.hibernate.NullPrecedence;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.constraint.MySQLIndexExporter;
import org.hibernate.dialect.constraint.MySQLUniqueKeyExporter;
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.pagination.AbstractLimitHandler;
@ -42,6 +44,9 @@ import org.hibernate.exception.LockTimeoutException;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.spi.relational.Constraint;
import org.hibernate.metamodel.spi.relational.Index;
import org.hibernate.tool.schema.spi.Exporter;
import org.hibernate.type.StandardBasicTypes;
/**
@ -51,6 +56,9 @@ import org.hibernate.type.StandardBasicTypes;
*/
public class MySQLDialect extends Dialect {
private final MySQLUniqueKeyExporter uniqueKeyExporter = new MySQLUniqueKeyExporter( this );
private final MySQLIndexExporter indexExporter = new MySQLIndexExporter( this );
/**
* Constructs a MySQLDialect
*/
@ -469,4 +477,14 @@ public class MySQLDialect extends Dialect {
public String getNotExpression(String expression) {
return "not (" + expression + ")";
}
@Override
public Exporter<Constraint> getUniqueKeyExporter() {
return uniqueKeyExporter;
}
@Override
public Exporter<Index> getIndexExporter() {
return indexExporter;
}
}

View File

@ -27,16 +27,12 @@ import java.util.List;
import javax.persistence.Column;
import javax.persistence.UniqueConstraint;
import org.hibernate.boot.registry.internal.BootstrapServiceRegistryImpl;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.metamodel.spi.relational.AbstractConstraint;
import org.hibernate.metamodel.spi.relational.Constraint;
import org.hibernate.metamodel.spi.relational.Index;
import org.hibernate.metamodel.spi.relational.Table;
import org.hibernate.metamodel.spi.relational.UniqueKey;
import org.hibernate.tool.schema.spi.Exporter;
import org.jboss.logging.Logger;
/**
@ -64,13 +60,9 @@ public class ConstraintDelegate {
private static final Logger LOG = Logger.getLogger( ConstraintDelegate.class );
final protected Dialect dialect;
final protected Exporter<Index> indexExporter;
final protected Exporter<Constraint> uniqueExporter;
public ConstraintDelegate(Dialect dialect) {
this.dialect = dialect;
this.indexExporter = dialect.getIndexExporter();
this.uniqueExporter = dialect.getUniqueKeyExporter();
}
/**
@ -128,7 +120,7 @@ public class ConstraintDelegate {
+ " sequence of columns: %s", index.getColumnNames());
}
else {
sqlStrings.addAll(Arrays.asList( indexExporter.getSqlCreateStrings( index, jdbcEnvironment ) ) );
sqlStrings.addAll(Arrays.asList( dialect.getIndexExporter().getSqlCreateStrings( index, jdbcEnvironment ) ) );
}
indexColumnListIds.add( index.columnListId() );
}
@ -152,7 +144,7 @@ public class ConstraintDelegate {
+ " for a unique index. %s", constraint.getColumnNames());
}
else {
sqlStrings.addAll(Arrays.asList( uniqueExporter.getSqlCreateStrings(
sqlStrings.addAll(Arrays.asList( dialect.getUniqueKeyExporter().getSqlCreateStrings(
constraint, jdbcEnvironment ) ) );
}
uniqueColumnListIds.add( constraint.columnListAlphabeticalId() );
@ -209,7 +201,7 @@ public class ConstraintDelegate {
}
else {
if (! indexColumnListIds.contains( index.columnListId() )) {
sqlStrings.addAll(Arrays.asList( indexExporter.getSqlDropStrings( index, jdbcEnvironment ) ) );
sqlStrings.addAll(Arrays.asList( dialect.getIndexExporter().getSqlDropStrings( index, jdbcEnvironment ) ) );
}
indexColumnListIds.add( index.columnListId() );
}
@ -229,7 +221,7 @@ public class ConstraintDelegate {
List<Integer> uniqueColumnListIds, JdbcEnvironment jdbcEnvironment) {
// A unique Index may have already exported the constraint.
if (! uniqueColumnListIds.contains( constraint.columnListAlphabeticalId() )) {
sqlStrings.addAll(Arrays.asList( uniqueExporter.getSqlDropStrings(
sqlStrings.addAll(Arrays.asList( dialect.getUniqueKeyExporter().getSqlDropStrings(
constraint, jdbcEnvironment ) ) );
}
uniqueColumnListIds.add( constraint.columnListAlphabeticalId() );

View File

@ -0,0 +1,67 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.dialect.constraint;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.spi.relational.Index;
import org.hibernate.metamodel.spi.relational.Table;
import org.hibernate.tool.schema.internal.StandardIndexExporter;
/**
* MySQL requires "ON table" at the end of a "DROP INDEX".
*
* TODO: If other Dialects need that as well, consider adding a "requiresOnTable" type of method on Dialect and
* work it into StandardIndexExporter itself.
*
* @author Brett Meyer
*/
public class MySQLIndexExporter extends StandardIndexExporter {
private final Dialect dialect;
public MySQLIndexExporter(Dialect dialect) {
super(dialect);
this.dialect = dialect;
}
@Override
public String[] getSqlDropStrings(Index index, JdbcEnvironment jdbcEnvironment) {
if ( ! dialect.dropConstraints() ) {
return NO_COMMANDS;
}
final String tableName = jdbcEnvironment.getQualifiedObjectNameSupport().formatName(
( (Table) index.getTable() ).getTableName()
);
StringBuilder sb = new StringBuilder();
sb.append( "drop index " );
sb.append( ( dialect.qualifyIndexName()
? StringHelper.qualify( tableName, index.getName() ) : index.getName() ) );
sb.append( " on " + tableName );
return new String[] { sb.toString() };
}
}

View File

@ -0,0 +1,66 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.dialect.constraint;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.metamodel.spi.relational.Constraint;
import org.hibernate.metamodel.spi.relational.Table;
import org.hibernate.tool.schema.internal.StandardUniqueKeyExporter;
/**
* MySQL does not support "DROP CONSTRAINT". Must use "DROP INDEX" instead.
*
* @author Brett Meyer
*/
public class MySQLUniqueKeyExporter extends StandardUniqueKeyExporter {
private final Dialect dialect;
public MySQLUniqueKeyExporter(Dialect dialect) {
super( dialect );
this.dialect = dialect;
}
@Override
public String[] getSqlDropStrings(Constraint constraint, JdbcEnvironment jdbcEnvironment) {
if ( ! dialect.dropConstraints() ) {
return NO_COMMANDS;
}
final String tableName = jdbcEnvironment.getQualifiedObjectNameSupport().formatName(
( (Table) constraint.getTable() ).getTableName()
);
final StringBuilder sb = new StringBuilder( "alter table " );
sb.append( tableName );
sb.append(" drop index " );
if ( dialect.supportsIfExistsBeforeConstraintName() ) {
sb.append( "if exists " );
}
sb.append( dialect.quote( constraint.getName() ) );
if ( dialect.supportsIfExistsAfterConstraintName() ) {
sb.append( " if exists" );
}
return new String[] { sb.toString() };
}
}

View File

@ -77,17 +77,14 @@ public class SchemaDropperImpl implements SchemaDropper {
}
for ( Schema schema : database.getSchemas() ) {
// we need to drop constraints prior to dropping table
applySqlStrings( targets, dialect.dropConstraints( schema.getTables(), jdbcEnvironment ) );
// we need to drop all constraints/indexes prior to dropping the tables
applySqlStrings( targets, dialect.dropConstraints( schema.getTables(), jdbcEnvironment ) );
for ( Table table : schema.getTables() ) {
if( !table.isPhysicalTable() ){
continue;
}
if ( dialect.dropConstraints() ) {
// we need to drop constraints prior to dropping table
for ( ForeignKey foreignKey : table.getForeignKeys() ) {
// only add the foreign key if its source and target are both physical tables
// and if the target table does not have any denormalized tables.
@ -107,7 +104,13 @@ public class SchemaDropperImpl implements SchemaDropper {
}
}
}
}
// now it's safe to drop the tables
for ( Table table : schema.getTables() ) {
if( !table.isPhysicalTable() ){
continue;
}
checkExportIdentifier( table, exportIdentifiers );
applySqlStrings( targets, dialect.getTableExporter().getSqlDropStrings( table, jdbcEnvironment ) );
}

View File

@ -77,7 +77,8 @@ public class StandardIndexExporter implements Exporter<Index> {
( (Table) index.getTable() ).getTableName()
);
return new String[] {
"drop index " + StringHelper.qualify( tableName, index.getName() )
"drop index " + ( dialect.qualifyIndexName()
? StringHelper.qualify( tableName, index.getName() ) : index.getName() )
};
}
}