Skip to content

DatabaseTypeRequest.Equals should ignore Width/Unicode for decimal types #19

@jas88

Description

@jas88

Issue

DatabaseTypeRequest.Equals() is too strict when comparing decimal types, causing round-trip tests to fail even when the semantically important properties (CSharpType, DecimalSize) match.

Current Behavior

private bool Equals(DatabaseTypeRequest other)
{
    return CSharpType == other.CSharpType && 
           Width == other.Width && 
           Equals(Size, other.Size) && 
           Unicode == other.Unicode;
}

Problem

When comparing decimal types:

  • Guesser-created: Has Width from string analysis, Size = DecimalSize(4,1)
  • Reverse-engineered from SQL: Has Width = null, Size = DecimalSize(4,1)

Even though both have identical CSharpType (decimal) and DecimalSize, Equals() returns false because Width differs!

Example

var guesser = new Guesser();
guesser.AdjustToCompensateForValue("200");
guesser.AdjustToCompensateForValue("29.9");
var orig = guesser.Guess; // CSharpType=decimal, Size=DecimalSize(4,1), Width=?

var sql = orig.GetSQLDbType(translater); // "decimal(5,1)"
var reverseEngineered = translater.GetDataTypeRequestForSQLDBType(sql);
// CSharpType=decimal, Size=DecimalSize(4,1), Width=null

Assert.That(reverseEngineered, Is.EqualTo(orig)); // FAILS!

Proposed Solution

Make Equals() more pragmatic for decimal types - ignore Width and Unicode since they're irrelevant for numeric types:

private bool Equals(DatabaseTypeRequest other)
{
    if (CSharpType != other.CSharpType) return false;
    
    // For decimal/numeric types, only compare Size (DecimalSize)
    // Width and Unicode are irrelevant for numeric types
    if (CSharpType == typeof(decimal) || CSharpType == typeof(decimal?) ||
        CSharpType == typeof(float) || CSharpType == typeof(double))
    {
        return Equals(Size, other.Size);
    }
    
    // For other types, compare all properties
    return Width == other.Width && Equals(Size, other.Size) && Unicode == other.Unicode;
}

Impact

This would make round-trip tests pass when comparing semantically equivalent DatabaseTypeRequest objects, even if Width/Unicode differ due to different creation paths.

Workaround

Currently working around this in FAnsiSql by comparing properties individually instead of using .Equals():

Assert.That(reverseEngineered.CSharpType, Is.EqualTo(orig.CSharpType));
Assert.That(reverseEngineered.Size, Is.EqualTo(orig.Size));

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions