package liquibase.database.typeconversion.core;

import liquibase.database.Database;
import liquibase.database.core.MSSQLDatabase;
import liquibase.database.structure.type.*;

import java.math.BigInteger;
import java.text.ParseException;

public class MSSQLTypeConverter extends AbstractTypeConverter {

    public int getPriority() {
        return PRIORITY_DATABASE;
    }

    public boolean supports(Database database) {
        return database instanceof MSSQLDatabase;
    }


    @Override
    public Object convertDatabaseValueToObject(Object defaultValue, int dataType, int columnSize, int decimalDigits, Database database) throws ParseException {
        if (defaultValue == null) {
            return null;
        }

        if (defaultValue instanceof String) {
            if (((String) defaultValue).startsWith("('")) {
                defaultValue = ((String) defaultValue).replaceFirst("^\\('", "").replaceFirst("'\\)$", "");
            } else if (((String) defaultValue).startsWith("((")) {
                defaultValue = ((String) defaultValue).replaceFirst("^\\(\\(", "").replaceFirst("\\)\\)$", "");
            }
        }

        defaultValue = super.convertDatabaseValueToObject(defaultValue, dataType, columnSize, decimalDigits, database);

        return defaultValue;
    }


    @Override
    public DataType getDataType(String columnTypeString, Boolean autoIncrement) {
        if (columnTypeString.endsWith(" identity")) {
            columnTypeString = columnTypeString.replaceFirst(" identity$", "");
            autoIncrement = true;
        }
        if (columnTypeString.equalsIgnoreCase("varbinary(2147483647)")){
            columnTypeString = "varbinary(max)";
        }
        return super.getDataType(columnTypeString, autoIncrement);
    }

    @Override
    protected DataType getDataType(String columnTypeString, Boolean autoIncrement, String dataTypeName, String precision) {
        if (columnTypeString.endsWith(" identity")) {
            columnTypeString = columnTypeString.replaceFirst(" identity$", "");
            autoIncrement = true;
        }
        if (columnTypeString.equalsIgnoreCase("varbinary") && (precision==null || Long.valueOf(precision) > 8000)) {
            precision = "max";
        }

        // Try to define data type by searching of common standard types
        DataType returnTypeName = super.getDataType(columnTypeString, autoIncrement, dataTypeName, precision);
        // If we found CustomType (it means - nothing compatible) then search for oracle types
        if (returnTypeName instanceof CustomType) {
            boolean returnTypeChanged=false;
            if (columnTypeString.toUpperCase().startsWith("NVARCHAR")) {
                returnTypeName = new NVarcharType();
                returnTypeChanged=true;
            } else if(columnTypeString.toUpperCase().startsWith("NCHAR")) {
                returnTypeName= new CharType("NCHAR");
                returnTypeChanged=true;
            }

            if(returnTypeChanged)
                addPrecisionToType(precision, returnTypeName);
        }
        
        return returnTypeName;
    }

    @Override
    public DateType getDateType() {
        return new DateType("SMALLDATETIME");
    }

    @Override
    public TimeType getTimeType() {
        return new TimeType("DATETIME");
    }

    @Override
    public BooleanType getBooleanType() {
        return new BooleanType.NumericBooleanType("BIT");
    }

    @Override
    public CurrencyType getCurrencyType() {
        return new CurrencyType("MONEY");
    }

    @Override
    public UUIDType getUUIDType() {
        return new UUIDType("UNIQUEIDENTIFIER");
    }

    @Override
    public ClobType getClobType() {
        return new ClobType("NVARCHAR(MAX)");
    }

    @Override
    public BlobType getBlobType() {
        return new BlobType("VARBINARY(MAX)");
    }

    @Override
    public NumberType getNumberType() {
      return new NumberType("NUMERIC");
    }
    
}

@@ -4098,17 +4098,117 @@
 %0A    %7D%0D%0A
+%0D%0A
     
+@Override%0D%0A    public DoubleType getDoubleType() %7B%0D%0A        return new DoubleType(%22FLOAT%22);%0D%0A    %7D
 %0D%0A%7D%0D%0A

Use correct data type for double on sqlserver. From forum post http://liquibase.org/forum/index.php?topic=823.msg3103#msg3103