func()

in pkg/datasource/sql/util/sql.go [277:317]


func (rs *ScanRows) Scan(dest ...interface{}) error {
	rs.closemu.RLock()

	if rs.lasterr != nil && rs.lasterr != io.EOF {
		rs.closemu.RUnlock()
		return rs.lasterr
	}
	if rs.closed {
		err := rs.lasterrOrErrLocked(errRowsClosed)
		rs.closemu.RUnlock()
		return err
	}
	rs.closemu.RUnlock()

	if rs.lastcols == nil {
		return errors.New("sql: Scan called without calling Next")
	}
	if len(dest) != len(rs.lastcols) {
		return fmt.Errorf("sql: expected %d destination arguments in Scan, not %d", len(rs.lastcols), len(dest))
	}
	for i, sv := range rs.lastcols {
		if sv == nil {
			continue
		}
		// the type of dest may be NullString, NullInt64, int64, etc, we should call its Scan()
		ty := reflect.TypeOf(dest[i])
		fn, ok := ty.MethodByName("Scan")
		if !ok {
			err := convertAssignRows(dest[i], sv, rs)
			if err != nil {
				return fmt.Errorf(`sql: Scan error on column index %d, name %q: %w`, i, rs.rowsi.Columns()[i], err)
			}
		} else {
			res := fn.Func.Call([]reflect.Value{reflect.ValueOf(dest[i]), reflect.ValueOf(sv)})
			if len(res) > 0 && !res[0].IsNil() {
				return fmt.Errorf(`sql: Scan error on column index %d, name %q: %v`, i, rs.rowsi.Columns()[i], res[0].Elem().String())
			}
		}
	}
	return nil
}