github.com/aacfactory/fns-contrib/databases/sql@v1.2.84/rows.go (about)

     1  package sql
     2  
     3  import (
     4  	"database/sql"
     5  	stdJson "encoding/json"
     6  	"fmt"
     7  	"github.com/aacfactory/avro"
     8  	"github.com/aacfactory/errors"
     9  	"github.com/aacfactory/fns-contrib/databases/sql/databases"
    10  	"github.com/aacfactory/fns/commons/times"
    11  	"github.com/aacfactory/json"
    12  	"reflect"
    13  	"strings"
    14  	"time"
    15  )
    16  
    17  type Row []Column
    18  
    19  func NewRows(rows databases.Rows) (v Rows, err error) {
    20  	names, namesErr := rows.Columns()
    21  	if namesErr != nil {
    22  		_ = rows.Close()
    23  		err = errors.Warning("sql: new rows failed").WithCause(namesErr)
    24  		return
    25  	}
    26  	cts, ctsErr := rows.ColumnTypes()
    27  	if ctsErr != nil {
    28  		_ = rows.Close()
    29  		err = errors.Warning("sql: new rows failed").WithCause(ctsErr)
    30  		return
    31  	}
    32  	columnLen := len(cts)
    33  	columnTypes := make([]ColumnType, 0, columnLen)
    34  	for i, ct := range cts {
    35  		columnTypes = append(columnTypes, NewColumnType(names[i], strings.ToUpper(ct.DatabaseType), ct.ScanType))
    36  	}
    37  	v = Rows{
    38  		idx:         0,
    39  		rows:        rows,
    40  		columnTypes: columnTypes,
    41  		columnLen:   columnLen,
    42  		values:      nil,
    43  		size:        0,
    44  	}
    45  	return
    46  }
    47  
    48  type Rows struct {
    49  	idx         int
    50  	rows        databases.Rows
    51  	columnTypes []ColumnType
    52  	columnLen   int
    53  	values      []Row
    54  	size        int
    55  }
    56  
    57  func (rows *Rows) Columns() []ColumnType {
    58  	return rows.columnTypes
    59  }
    60  
    61  func (rows *Rows) Close() error {
    62  	if rows.rows == nil {
    63  		return nil
    64  	}
    65  	return rows.rows.Close()
    66  }
    67  
    68  func (rows *Rows) Next() (ok bool) {
    69  	if rows.rows != nil {
    70  		ok = rows.rows.Next()
    71  		return
    72  	}
    73  	ok = rows.idx < rows.size
    74  	if ok {
    75  		rows.idx++
    76  	}
    77  	return
    78  }
    79  
    80  // Scan
    81  // element of dst must be scanned.
    82  // in dac case, when field is json kind and type does not implement sql.NullJson,
    83  // then wrap field value by sql.NullJson
    84  func (rows *Rows) Scan(dst ...any) (err error) {
    85  	if rows.rows != nil {
    86  		err = rows.rows.Scan(dst...)
    87  		return
    88  	}
    89  	if rows.idx > rows.size {
    90  		err = sql.ErrNoRows
    91  		return
    92  	}
    93  	dstLen := len(dst)
    94  	if dstLen == 0 {
    95  		return
    96  	}
    97  	if dstLen != rows.columnLen {
    98  		err = errors.Warning("sql: scan failed").WithCause(fmt.Errorf("size is not matched"))
    99  		return
   100  	}
   101  	row := rows.values[rows.idx-1]
   102  	for i := 0; i < rows.columnLen; i++ {
   103  		item := dst[i]
   104  		if item == nil {
   105  			err = errors.Warning("sql: scan failed").WithCause(fmt.Errorf("some of dst is nil"))
   106  			return
   107  		}
   108  		column := row[i]
   109  		if !column.Valid {
   110  			continue
   111  		}
   112  		ct := rows.columnTypes[i]
   113  		switch d := item.(type) {
   114  		case *string:
   115  			cv, cvErr := column.String()
   116  			if cvErr != nil {
   117  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   118  				return
   119  			}
   120  			*d = cv
   121  			break
   122  		case *NullString:
   123  			cv, cvErr := column.String()
   124  			if cvErr != nil {
   125  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   126  				return
   127  			}
   128  			d.Valid = len(cv) > 0
   129  			d.String = cv
   130  			break
   131  		case *sql.NullString:
   132  			cv, cvErr := column.String()
   133  			if cvErr != nil {
   134  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   135  				return
   136  			}
   137  			d.Valid = len(cv) > 0
   138  			d.String = cv
   139  			break
   140  		case *bool:
   141  			cv, cvErr := column.Bool()
   142  			if cvErr != nil {
   143  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   144  				return
   145  			}
   146  			*d = cv
   147  			break
   148  		case *NullBool:
   149  			cv, cvErr := column.Bool()
   150  			if cvErr != nil {
   151  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   152  				return
   153  			}
   154  			d.Valid = true
   155  			d.Bool = cv
   156  			break
   157  		case *sql.NullBool:
   158  			cv, cvErr := column.Bool()
   159  			if cvErr != nil {
   160  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   161  				return
   162  			}
   163  			d.Valid = true
   164  			d.Bool = cv
   165  			break
   166  		case *int64:
   167  			cv, cvErr := column.Int()
   168  			if cvErr != nil {
   169  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   170  				return
   171  			}
   172  			*d = cv
   173  			break
   174  		case *int32:
   175  			cv, cvErr := column.Int()
   176  			if cvErr != nil {
   177  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   178  				return
   179  			}
   180  			*d = int32(cv)
   181  			break
   182  		case *int16:
   183  			cv, cvErr := column.Int()
   184  			if cvErr != nil {
   185  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   186  				return
   187  			}
   188  			*d = int16(cv)
   189  			break
   190  		case NullInt64:
   191  			cv, cvErr := column.Int()
   192  			if cvErr != nil {
   193  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   194  				return
   195  			}
   196  			d.Valid = true
   197  			d.Int64 = cv
   198  			break
   199  		case *sql.NullInt64:
   200  			cv, cvErr := column.Int()
   201  			if cvErr != nil {
   202  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   203  				return
   204  			}
   205  			d.Valid = true
   206  			d.Int64 = cv
   207  			break
   208  		case NullInt32:
   209  			cv, cvErr := column.Int()
   210  			if cvErr != nil {
   211  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   212  				return
   213  			}
   214  			d.Valid = true
   215  			d.Int32 = int32(cv)
   216  			break
   217  		case *sql.NullInt32:
   218  			cv, cvErr := column.Int()
   219  			if cvErr != nil {
   220  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   221  				return
   222  			}
   223  			d.Valid = true
   224  			d.Int32 = int32(cv)
   225  			break
   226  		case NullInt16:
   227  			cv, cvErr := column.Int()
   228  			if cvErr != nil {
   229  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   230  				return
   231  			}
   232  			d.Valid = true
   233  			d.Int16 = int16(cv)
   234  			break
   235  		case *sql.NullInt16:
   236  			cv, cvErr := column.Int()
   237  			if cvErr != nil {
   238  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   239  				return
   240  			}
   241  			d.Valid = true
   242  			d.Int16 = int16(cv)
   243  			break
   244  		case *float64:
   245  			cv, cvErr := column.Float()
   246  			if cvErr != nil {
   247  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   248  				return
   249  			}
   250  			*d = cv
   251  			break
   252  		case *float32:
   253  			cv, cvErr := column.Float()
   254  			if cvErr != nil {
   255  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   256  				return
   257  			}
   258  			*d = float32(cv)
   259  			break
   260  		case sql.NullFloat64:
   261  			cv, cvErr := column.Float()
   262  			if cvErr != nil {
   263  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   264  				return
   265  			}
   266  			d.Valid = true
   267  			d.Float64 = cv
   268  			break
   269  		case *sql.NullFloat64:
   270  			cv, cvErr := column.Float()
   271  			if cvErr != nil {
   272  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   273  				return
   274  			}
   275  			d.Valid = true
   276  			d.Float64 = cv
   277  			break
   278  		case *time.Time:
   279  			cv, cvErr := column.Datetime()
   280  			if cvErr != nil {
   281  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   282  				return
   283  			}
   284  			*d = cv
   285  			break
   286  		case *NullDatetime:
   287  			cv, cvErr := column.Datetime()
   288  			if cvErr != nil {
   289  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   290  				return
   291  			}
   292  			d.Valid = true
   293  			d.Time = cv
   294  			break
   295  		case *sql.NullTime:
   296  			cv, cvErr := column.Datetime()
   297  			if cvErr != nil {
   298  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   299  				return
   300  			}
   301  			d.Valid = !cv.IsZero()
   302  			d.Time = cv
   303  			break
   304  		case *times.Date:
   305  			cv, cvErr := column.Date()
   306  			if cvErr != nil {
   307  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   308  				return
   309  			}
   310  			*d = cv
   311  			break
   312  		case *NullDate:
   313  			cv, cvErr := column.Date()
   314  			if cvErr != nil {
   315  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   316  				return
   317  			}
   318  			d.Valid = !cv.IsZero()
   319  			d.Date = cv
   320  			break
   321  		case *times.Time:
   322  			cv, cvErr := column.Time()
   323  			if cvErr != nil {
   324  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   325  				return
   326  			}
   327  			*d = cv
   328  			break
   329  		case *NullTime:
   330  			cv, cvErr := column.Time()
   331  			if cvErr != nil {
   332  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   333  				return
   334  			}
   335  			d.Valid = !cv.IsZero()
   336  			d.Time = cv
   337  			break
   338  		case *[]byte:
   339  			cv, cvErr := column.Bytes()
   340  			if cvErr != nil {
   341  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   342  				return
   343  			}
   344  			*d = cv
   345  			break
   346  		case *NullBytes:
   347  			cv, cvErr := column.Bytes()
   348  			if cvErr != nil {
   349  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   350  				return
   351  			}
   352  			d.Valid = true
   353  			d.Bytes = cv
   354  			break
   355  		case *json.RawMessage:
   356  			cv, cvErr := column.Bytes()
   357  			if cvErr != nil {
   358  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   359  				return
   360  			}
   361  			*d = cv
   362  			break
   363  		case *stdJson.RawMessage:
   364  			cv, cvErr := column.Bytes()
   365  			if cvErr != nil {
   366  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   367  				return
   368  			}
   369  			*d = cv
   370  			break
   371  		case *sql.RawBytes:
   372  			cv, cvErr := column.Bytes()
   373  			if cvErr != nil {
   374  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   375  				return
   376  			}
   377  			*d = cv
   378  			break
   379  		case *byte:
   380  			cv, cvErr := column.Byte()
   381  			if cvErr != nil {
   382  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   383  				return
   384  			}
   385  			*d = cv
   386  			break
   387  		case *sql.NullByte:
   388  			cv, cvErr := column.Byte()
   389  			if cvErr != nil {
   390  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   391  				return
   392  			}
   393  			d.Valid = true
   394  			d.Byte = cv
   395  			break
   396  		case *json.Date:
   397  			cv, cvErr := column.Date()
   398  			if cvErr != nil {
   399  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   400  				return
   401  			}
   402  			*d = json.NewDate(cv.Year, cv.Month, cv.Day)
   403  			break
   404  		case *json.Time:
   405  			cv, cvErr := column.Time()
   406  			if cvErr != nil {
   407  				err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   408  				return
   409  			}
   410  			*d = json.NewTime(cv.Hour, cv.Minutes, cv.Second)
   411  			break
   412  		default:
   413  			scanner, isScanner := item.(sql.Scanner)
   414  			if isScanner {
   415  				var scanErr error
   416  				switch ct.Type {
   417  				case "string":
   418  					cv, cvErr := column.String()
   419  					if cvErr != nil {
   420  						err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   421  						return
   422  					}
   423  					scanErr = scanner.Scan(cv)
   424  					break
   425  				case "bool":
   426  					cv, cvErr := column.Bool()
   427  					if cvErr != nil {
   428  						err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   429  						return
   430  					}
   431  					scanErr = scanner.Scan(cv)
   432  					break
   433  				case "int":
   434  					cv, cvErr := column.Int()
   435  					if cvErr != nil {
   436  						err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   437  						return
   438  					}
   439  					scanErr = scanner.Scan(cv)
   440  					break
   441  				case "float":
   442  					cv, cvErr := column.Float()
   443  					if cvErr != nil {
   444  						err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   445  						return
   446  					}
   447  					scanErr = scanner.Scan(cv)
   448  					break
   449  				case "datetime":
   450  					cv, cvErr := column.Datetime()
   451  					if cvErr != nil {
   452  						err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   453  						return
   454  					}
   455  					scanErr = scanner.Scan(cv)
   456  					break
   457  				case "date":
   458  					cv, cvErr := column.Datetime()
   459  					if cvErr != nil {
   460  						err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   461  						return
   462  					}
   463  					scanErr = scanner.Scan(cv)
   464  					break
   465  				case "time":
   466  					cv, cvErr := column.Datetime()
   467  					if cvErr != nil {
   468  						err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   469  						return
   470  					}
   471  					scanErr = scanner.Scan(cv)
   472  					break
   473  				case "bytes":
   474  					cv, cvErr := column.Bytes()
   475  					if cvErr != nil {
   476  						err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   477  						return
   478  					}
   479  					scanErr = scanner.Scan(cv)
   480  					break
   481  				case "byte":
   482  					cv, cvErr := column.Byte()
   483  					if cvErr != nil {
   484  						err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   485  						return
   486  					}
   487  					scanErr = scanner.Scan(cv)
   488  					break
   489  				default:
   490  					err = errors.Warning("sql: scan failed").WithCause(fmt.Errorf("type is unsupported")).WithMeta("column", ct.Name)
   491  					return
   492  				}
   493  				if scanErr != nil {
   494  					err = errors.Warning("sql: scan failed").WithCause(scanErr).WithMeta("column", ct.Name)
   495  					return
   496  				}
   497  				return
   498  			}
   499  			if ct.Type == "json" {
   500  				decodeErr := json.Unmarshal(column.Value, item)
   501  				if decodeErr != nil {
   502  					err = errors.Warning("sql: scan failed").WithCause(decodeErr).WithMeta("column", ct.Name)
   503  					return
   504  				}
   505  				return
   506  			}
   507  			rv := reflect.ValueOf(item).Elem()
   508  			switch rv.Type().Kind() {
   509  			case reflect.String:
   510  				cv, cvErr := column.String()
   511  				if cvErr != nil {
   512  					err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   513  					return
   514  				}
   515  				rv.SetString(cv)
   516  				break
   517  			case reflect.Bool:
   518  				cv, cvErr := column.Bool()
   519  				if cvErr != nil {
   520  					err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   521  					return
   522  				}
   523  				rv.SetBool(cv)
   524  				break
   525  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   526  				cv, cvErr := column.Int()
   527  				if cvErr != nil {
   528  					err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   529  					return
   530  				}
   531  				rv.SetInt(cv)
   532  				break
   533  			case reflect.Float32, reflect.Float64:
   534  				cv, cvErr := column.Float()
   535  				if cvErr != nil {
   536  					err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   537  					return
   538  				}
   539  				rv.SetFloat(cv)
   540  				break
   541  			case reflect.Uint8:
   542  				cv, cvErr := column.Byte()
   543  				if cvErr != nil {
   544  					err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   545  					return
   546  				}
   547  				rv.SetUint(uint64(cv))
   548  				break
   549  			default:
   550  				rt := rv.Type()
   551  				if rt.ConvertibleTo(datetimeType) {
   552  					cv, cvErr := column.Datetime()
   553  					if cvErr != nil {
   554  						err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   555  						return
   556  					}
   557  					rv.Set(reflect.ValueOf(cv).Convert(rt))
   558  				} else if rt.ConvertibleTo(dateType) {
   559  					cv, cvErr := column.Date()
   560  					if cvErr != nil {
   561  						err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   562  						return
   563  					}
   564  					rv.Set(reflect.ValueOf(cv).Convert(rt))
   565  				} else if rt.ConvertibleTo(timeType) {
   566  					cv, cvErr := column.Time()
   567  					if cvErr != nil {
   568  						err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   569  						return
   570  					}
   571  					rv.Set(reflect.ValueOf(cv).Convert(rt))
   572  				} else if rt.ConvertibleTo(rawType) {
   573  					cv, cvErr := column.Bytes()
   574  					if cvErr != nil {
   575  						err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   576  						return
   577  					}
   578  					rv.Set(reflect.ValueOf(cv).Convert(rt))
   579  				} else if rt.ConvertibleTo(bytesType) {
   580  					cv, cvErr := column.Bytes()
   581  					if cvErr != nil {
   582  						err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   583  						return
   584  					}
   585  					rv.Set(reflect.ValueOf(cv).Convert(rt))
   586  				} else if rt.ConvertibleTo(jsonDateType) {
   587  					cv, cvErr := column.Date()
   588  					if cvErr != nil {
   589  						err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   590  						return
   591  					}
   592  					rv.Set(reflect.ValueOf(cv).Convert(rt))
   593  				} else if rt.ConvertibleTo(jsonTimeType) {
   594  					cv, cvErr := column.Time()
   595  					if cvErr != nil {
   596  						err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   597  						return
   598  					}
   599  					rv.Set(reflect.ValueOf(cv).Convert(rt))
   600  				} else {
   601  					unmarshaler, isUnmarshaler := item.(json.Unmarshaler)
   602  					if isUnmarshaler {
   603  						cv, cvErr := column.Bytes()
   604  						if cvErr != nil {
   605  							err = errors.Warning("sql: scan failed").WithCause(cvErr).WithMeta("column", ct.Name)
   606  							return
   607  						}
   608  						decodeErr := unmarshaler.UnmarshalJSON(cv)
   609  						if decodeErr != nil {
   610  							err = errors.Warning("sql: scan failed").WithCause(decodeErr).WithMeta("column", ct.Name)
   611  							return
   612  						}
   613  						return
   614  					}
   615  					cv, cvErr := column.Bytes()
   616  					if cvErr != nil {
   617  						err = errors.Warning("sql: scan failed").WithCause(fmt.Errorf("unsupported type")).WithMeta("column", ct.Name)
   618  						return
   619  					}
   620  					decodeErr := json.Unmarshal(cv, item)
   621  					if decodeErr != nil {
   622  						err = errors.Warning("sql: scan failed").WithCause(decodeErr).WithMeta("column", ct.Name)
   623  						return
   624  					}
   625  					return
   626  				}
   627  			}
   628  			break
   629  		}
   630  	}
   631  	return
   632  }
   633  
   634  func (rows Rows) MarshalAvro() (p []byte, err error) {
   635  	if len(rows.values) > 0 {
   636  		tr := transferRows{
   637  			ColumnTypes: rows.columnTypes,
   638  			Values:      rows.values,
   639  		}
   640  		p, err = avro.Marshal(tr)
   641  		return
   642  	}
   643  	if rows.idx != 0 {
   644  		err = errors.Warning("sql: encode rows failed").WithCause(fmt.Errorf("rows has been used"))
   645  		return
   646  	}
   647  	mc := newMultiColumns(rows.columnLen)
   648  	for rows.rows.Next() {
   649  		scanners := mc.Next()
   650  		scanErr := rows.rows.Scan(scanners...)
   651  		if scanErr != nil {
   652  			_ = rows.rows.Close()
   653  			mc.Release()
   654  			err = errors.Warning("sql: encode rows failed").WithCause(scanErr)
   655  			return
   656  		}
   657  	}
   658  	_ = rows.rows.Close()
   659  	rows.values = mc.Rows()
   660  	rows.size = len(rows.values)
   661  	tr := transferRows{
   662  		ColumnTypes: rows.columnTypes,
   663  		Values:      rows.values,
   664  	}
   665  	p, err = avro.Marshal(tr)
   666  	mc.Release()
   667  	return
   668  }
   669  
   670  func (rows *Rows) UnmarshalAvro(p []byte) (err error) {
   671  	if len(p) == 0 {
   672  		return
   673  	}
   674  	tr := transferRows{}
   675  	err = avro.Unmarshal(p, &tr)
   676  	if err != nil {
   677  		return
   678  	}
   679  	rows.idx = 0
   680  	rows.columnTypes = tr.ColumnTypes
   681  	rows.columnLen = len(rows.columnTypes)
   682  	rows.values = tr.Values
   683  	rows.size = len(rows.values)
   684  	return
   685  }
   686  
   687  func (rows Rows) MarshalJSON() (p []byte, err error) {
   688  	if len(rows.values) > 0 {
   689  		tr := transferRows{
   690  			ColumnTypes: rows.columnTypes,
   691  			Values:      rows.values,
   692  		}
   693  		p, err = json.Marshal(tr)
   694  		return
   695  	}
   696  	if rows.idx != 0 {
   697  		err = errors.Warning("sql: encode rows failed").WithCause(fmt.Errorf("rows has been used"))
   698  		return
   699  	}
   700  	mc := newMultiColumns(rows.columnLen)
   701  	for rows.rows.Next() {
   702  		scanners := mc.Next()
   703  		scanErr := rows.rows.Scan(scanners...)
   704  		if scanErr != nil {
   705  			_ = rows.rows.Close()
   706  			mc.Release()
   707  			err = errors.Warning("sql: encode rows failed").WithCause(scanErr)
   708  			return
   709  		}
   710  	}
   711  	_ = rows.rows.Close()
   712  	rows.values = mc.Rows()
   713  	rows.size = len(rows.values)
   714  	tr := transferRows{
   715  		ColumnTypes: rows.columnTypes,
   716  		Values:      rows.values,
   717  	}
   718  	p, err = json.Marshal(tr)
   719  	mc.Release()
   720  	return
   721  }
   722  
   723  func (rows *Rows) UnmarshalJSON(p []byte) (err error) {
   724  	tr := transferRows{}
   725  	err = json.Unmarshal(p, &tr)
   726  	if err != nil {
   727  		return
   728  	}
   729  	rows.idx = 0
   730  	rows.columnTypes = tr.ColumnTypes
   731  	rows.columnLen = len(rows.columnTypes)
   732  	rows.values = tr.Values
   733  	rows.size = len(rows.values)
   734  	return
   735  }
   736  
   737  type transferRows struct {
   738  	ColumnTypes []ColumnType `json:"columnTypes" avro:"columnTypes"`
   739  	Values      []Row        `json:"values" avro:"values"`
   740  }