Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: support scan float32 to float32 #1088

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

j2gg0s
Copy link
Collaborator

@j2gg0s j2gg0s commented Dec 18, 2024

Close #1087

@j2gg0s
Copy link
Collaborator Author

j2gg0s commented Dec 18, 2024

@vmihailenco

Do we have any specific reason not to do this? I suspect this might be a bug.

@j2gg0s j2gg0s requested a review from vmihailenco December 18, 2024 02:57
@Re3os
Copy link

Re3os commented Dec 18, 2024

@j2gg0s
Why duplicate the code when we can just use:

case float32:
    dest.SetFloat(float64(src))
    return nil
Or bring the function to common values:

func scanFloat(dest reflect.Value, src interface{}) error

It's wrong to duplicate code, I may be wrong?

@j2gg0s
Copy link
Collaborator Author

j2gg0s commented Dec 18, 2024

@j2gg0s Why duplicate the code when we can just use:

case float32:
    dest.SetFloat(float64(src))
    return nil
Or bring the function to common values:

func scanFloat(dest reflect.Value, src interface{}) error

It's wrong to duplicate code, I may be wrong?

@Re3os
Currently, we dont support scan float32 to float64.
I dont want to break this.

To me, there is no difference in merit between adding an if condition and duplicating code.

schema/scan.go Outdated Show resolved Hide resolved
@vmihailenco
Copy link
Member

vmihailenco commented Dec 18, 2024

Currently, we dont support scan float32 to float64.

But why? You allow to scan float64 into float32 which results in precision loss, but want to forbid scanning float32 to float64 which is fine.

I agree with @Re3os that this could be refactored into a more general function:

func scanFloat32(dest reflect.Value, src interface{}) error {
    return scanFloat(dest, src, 32)
}

func scanFloat64(dest reflect.Value, src interface{}) error {
    return scanFloat(dest, src, 64)
}

func scanFloat(dest reflect.Value, src interface{}, bits int) error {
}

Do we have any specific reason not to do this? I suspect this might be a bug.

AFAIR no I think I assumed that database/sql never returns float32.

@j2gg0s j2gg0s force-pushed the fix-support-scan-float32-to-float32 branch from 281274e to a52e733 Compare December 18, 2024 11:15
@Re3os
Copy link

Re3os commented Dec 18, 2024

@j2gg0s

func scanFloat(dest reflect.Value, src interface{}, bits int) error {
    var parsedFloat float64 

    switch src := src.(type) {
    case nil:
        parsedFloat = 0
    case float32:
        parsedFloat = float64(src)
    case float64:
        parsedFloat = src
    case []byte:
        f, err := strconv.ParseFloat(string(src), bits)
        if err != nil {
            return err
        }
        parsedFloat = f
    case string:
        f, err := strconv.ParseFloat(src, bits)
        if err != nil {
            return err
        }
        parsedFloat = f
    default:
        return scanError(dest.Type(), src)
    }

    if bits == 32 && dest.Kind() == reflect.Float32 {
        dest.SetFloat(float64(float32(parsedFloat))) 
    } else if bits == 64 && dest.Kind() == reflect.Float64 {
        dest.SetFloat(parsedFloat)
    } else {
        return scanError(dest.Type(), src)
    }

    return nil
}

float32 = 32bits
float64 = 64bits

Didn't test it, no time

func scanFloat32(dest reflect.Value, src interface{}) error {
    return scanFloat(dest, src, 32)
}

func scanFloat64(dest reflect.Value, src interface{}) error {
    return scanFloat(dest, src, 64)
}

@j2gg0s
Copy link
Collaborator Author

j2gg0s commented Dec 18, 2024

Current logic in master:

  1. support scan float64 to float64
  2. support scan float64 to float32
  3. dont support scan float32 to float64
  4. dont support scan float32 to float32

I think:
1 must be correct.
2 might be incorrect because it could lose precision
3 might be supported, but it is not mandatory.
4 must be incorrect

Due to personal habits, I am unwilling to modify any existing logic unless I have confirmed how everyone uses it, or it is obviously incorrect.

However, I think it is also acceptable to directly support 3 & 4 now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Bun cannot scan float32 into float32 for MySQL FLOAT columns
3 participants