nakagami / firebirdsql

Firebird RDBMS sql driver for Go (golang)
MIT License
224 stars 60 forks source link

Decimal cannot be converted to type float32 #81

Closed iv-menshenin closed 3 years ago

iv-menshenin commented 5 years ago

Scan error on column index 9, name "DISCOUNT": reflect.Value. Convert: value of type decimal. Decimal cannot be converted to type float32 on column DISCOUNT"

scanner:


func (f *refScanner) Scan (src interface{}) (err error) {

    defer func(){
        if r := recover(); r != nil {
            if s, ok := r.(string); ok {
                err = errors.New(s + " on column `" + f.ColumnName + "`")
            } else {
                err = errors.New(fmt.Sprintf("<%T>: %s on column `%s`", r, r, f.ColumnName))
            }
        }
    }()

    sv := reflect.ValueOf(src)
    if sv.IsValid() {

        k := sv.Kind()
        if k == reflect.Ptr || k == reflect.Interface {

            if sv.IsNil() {
                return
            }
            sv = sv.Elem()

        }

        if f.Destination.Kind() == reflect.Slice && f.Destination.Type().Elem().Kind() != reflect.Struct {

            f.Destination.Set(sv.Convert(f.Destination.Type()))

        } else
        if f.Destination.Kind() == reflect.Slice {

            // the slice must extends in each iteration
            currCap := f.Destination.Cap()
            currLen := f.RowsCount          // needed len

            // extends if needed
            if currLen > currCap {
                newCap := (currLen + currCap / 2) + 4
                newSlice := reflect.MakeSlice(f.Destination.Type(), currLen, newCap)
                reflect.Copy(newSlice, *f.Destination)
                f.Destination.Set(newSlice)
            }
            // each iteration, remember
            f.Destination.SetLen(currLen)
            field := f.Destination.Index(f.RowsCount - 1).Field(f.Index)
            if field.Kind() == reflect.ValueOf(&(time.Time{})).Kind() && field.IsNil() {
                field.Set(reflect.New(field.Type().Elem()))
                field = field.Elem()
            }
            field.Set(sv.Convert(field.Type()))

        } else {

            if f.Destination.Kind() == reflect.ValueOf(&(time.Time{})).Kind() && f.Destination.IsNil() {
                f.Destination.Set(reflect.New(f.Destination.Type().Elem()))
                f.Destination.Elem().Set(sv.Convert(f.Destination.Elem().Type()))

            } else {
                f.Destination.Set(sv.Convert(f.Destination.Type()))

            }

        }
        return

    }

    return

}

sql procedure signature:


procedure get_list(
    session char(16) character set octets,
    fltid varchar(64),
    fskip integer,
    fcount integer,
    sorted varchar(10),
    approved boolean
    )returns(   
    created timestamp,
    client_uuid char(16) character set octets,  
    group_uuid char(16) character set octets,
    fullname varchar(64),
    ctype varchar(64),
    pic varchar(64),
    ncountry varchar(64),
    country_code varchar(64),
    ncity varchar(64),   
    city_uuid char(16) character set octets,
    discount numeric(4,2),  
    like_rate numeric(4,2),
    balance numeric(18,4),
    likes int,
    gift int,
    toptags varchar(2048),
    errcode integer,
    err varchar(250)
    );

Struct:


    TApiClientListV100 struct {
        UUID []uint8                    `json:"uuid" sql:"CLIENT_UUID"`
        GroupUUID []uint8               `json:"group_uuid" sql:"GROUP_UUID"`
        FullName string                 `json:"clientname" sql:"FULLNAME"`
        Type string                     `json:"type" sql:"CTYPE"`
        Picture string                  `json:"picture" sql:"PIC"`
        Country string                  `json:"country" sql:"NCOUNTRY"`
        CountryCode string              `json:"country_code" sql:"COUNTRY_CODE"`
        City string                     `json:"city" sql:"NCITY"`
        CityUUID []uint8                `json:"city_uuid" sql:"CITY_UUID"`
        Discount float32                `json:"discount" sql:"DISCOUNT"`
        Balance float32                 `json:"balance" sql:"BALANCE"`
        Likes int                       `json:"likes" sql:"LIKES"`
        StrTags string                  `json:"-" sql:"TOPTAGS"`
        Hashtags []TApiTag100           `json:"tags"`
    }
iv-menshenin commented 5 years ago

It worked well a few months ago (six to seven months) And brokes after 'git pull'

here is woked fine = bf347607b06449643f4f943c06bf241abf889bf9

iv-menshenin commented 5 years ago

and same error with float64 in this commit it works fine = bf347607b06449643f4f943c06bf241abf889bf9

nakagami commented 5 years ago

Please use shopspring/decimal now.

I hope to support decimal in Go2.