package liquibase.change.ext;

import liquibase.change.ChangeMetaData;
import liquibase.change.DatabaseChange;
import liquibase.change.core.DropNotNullConstraintChange;
import liquibase.database.Database;
import liquibase.database.ext.HanaDBDatabase;
import liquibase.statement.SqlStatement;
import liquibase.statement.core.SetNullableStatement;

@DatabaseChange(name="dropNotNullConstraint", description = "Makes a column nullable", priority = ChangeMetaData.PRIORITY_DATABASE, appliesTo = "column", since = "3.0")
public class DropNotNullConstraintChangeHana extends
		DropNotNullConstraintChange {

	@Override
	public boolean supports(Database database) {
		return database instanceof HanaDBDatabase;
	}

	@Override
	public SqlStatement[] generateStatements(Database database) {
    	if (getSchemaName() == null) {
    		setSchemaName(database.getDefaultSchemaName());
    	}
    	String columnDataTypeName = getColumnDataType();
    	if (columnDataTypeName == null && getSchemaName() != null && database instanceof HanaDBDatabase) {
    		columnDataTypeName = ((HanaDBDatabase) database).getColumnDataTypeName(getCatalogName(), getSchemaName(), getTableName(), getColumnName());
		}
    	
    	return new SqlStatement[] { new SetNullableStatement(
                getCatalogName(),
    			getSchemaName(),
    			getTableName(), getColumnName(), columnDataTypeName, true) 
    	};

	}

}

package liquibase.change.ext;

import liquibase.change.ChangeMetaData;
import liquibase.change.DatabaseChange;
import liquibase.change.core.DropNotNullConstraintChange;
import liquibase.database.Database;
import liquibase.database.ext.HanaDBDatabase;
import liquibase.statement.SqlStatement;
import liquibase.statement.core.SetNullableStatement;

@DatabaseChange(name="dropNotNullConstraint", description = "Makes a column nullable", priority = ChangeMetaData.PRIORITY_DATABASE, appliesTo = "column", since = "3.0")
public class DropNotNullConstraintChangeHana extends
		DropNotNullConstraintChange {

	@Override
	public boolean supports(Database database) {
		return database instanceof HanaDBDatabase;
	}

	@Override
	public SqlStatement[] generateStatements(Database database) {
		// local variable introduced as superclass's schemaName is used for checksum calculation
		// TODO: is this logic also needed for the inverse?
		String schemaToUse = getSchemaName();
    	if (schemaToUse == null) {
    		schemaToUse = database.getDefaultSchemaName();
    	}
    	String columnDataTypeName = getColumnDataType();
    	if (columnDataTypeName == null && schemaToUse != null && database instanceof HanaDBDatabase) {
    		columnDataTypeName = ((HanaDBDatabase) database).getColumnDataTypeName(getCatalogName(), schemaToUse, getTableName(), getColumnName());
		}
    	
    	return new SqlStatement[] { new SetNullableStatement(
                getCatalogName(),
    			schemaToUse,
    			getTableName(), getColumnName(), columnDataTypeName, true) 
    	};

	}

}

Fix checksum failure when reexecuting changesets with dropNotNullConstraint
Fix checksum failure when reexecuting changesets with
dropNotNullConstraint

The checksum validation failed when a changeset containing a
<dropNotNullConstraint> change was processed for the second time.
The reason is that the statement generation (which only occurs when the
change
is really executed, i.e. the first time only) changes the value of the
schemaName field. The schemaName, however, is used for checksum
calculation.
