github.com/matrixorigin/matrixone@v1.2.0/pkg/container/vector/tools.go (about)

     1  // Copyright 2021 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package vector
    16  
    17  import (
    18  	"fmt"
    19  	"unsafe"
    20  
    21  	"github.com/matrixorigin/matrixone/pkg/common/mpool"
    22  	"github.com/matrixorigin/matrixone/pkg/container/types"
    23  	"github.com/matrixorigin/matrixone/pkg/pb/api"
    24  	"github.com/matrixorigin/matrixone/pkg/pb/plan"
    25  )
    26  
    27  func ToFixedCol[T any](v *Vector, ret *[]T) {
    28  	// XXX hack.   Sometimes we generate an t_any, for untyped const null.
    29  	// This should be handled more carefully and gracefully.
    30  	if v.GetType().Oid == types.T_any || len(v.data) == 0 {
    31  		return
    32  	}
    33  	ToSlice(v, ret)
    34  	if v.class == CONSTANT {
    35  		*ret = (*ret)[:1]
    36  	} else {
    37  		*ret = (*ret)[:v.length]
    38  	}
    39  }
    40  
    41  func MustFixedCol[T any](v *Vector) (ret []T) {
    42  	ToFixedCol(v, &ret)
    43  	return
    44  }
    45  
    46  func MustBytesCol(v *Vector) [][]byte {
    47  	if v.GetType().Oid == types.T_any || len(v.data) == 0 {
    48  		return nil
    49  	}
    50  	varcol := MustFixedCol[types.Varlena](v)
    51  	if v.class == CONSTANT {
    52  		return [][]byte{(&varcol[0]).GetByteSlice(v.area)}
    53  	} else {
    54  		ret := make([][]byte, v.length)
    55  		for i := range varcol {
    56  			ret[i] = (&varcol[i]).GetByteSlice(v.area)
    57  		}
    58  		return ret
    59  	}
    60  }
    61  
    62  func MustStrCol(v *Vector) []string {
    63  	if v.GetType().Oid == types.T_any || len(v.data) == 0 {
    64  		return nil
    65  	}
    66  	varcol := MustFixedCol[types.Varlena](v)
    67  	if v.class == CONSTANT {
    68  		return []string{(&varcol[0]).GetString(v.area)}
    69  	} else {
    70  		ret := make([]string, v.length)
    71  		for i := range varcol {
    72  			ret[i] = (&varcol[i]).GetString(v.area)
    73  		}
    74  		return ret
    75  	}
    76  }
    77  
    78  // MustArrayCol  Converts Vector<[]T> to [][]T
    79  func MustArrayCol[T types.RealNumbers](v *Vector) [][]T {
    80  	if v.GetType().Oid == types.T_any || len(v.data) == 0 {
    81  		return nil
    82  	}
    83  	varcol := MustFixedCol[types.Varlena](v)
    84  	if v.class == CONSTANT {
    85  		return [][]T{types.GetArray[T](&varcol[0], v.area)}
    86  	} else {
    87  		ret := make([][]T, v.length)
    88  		for i := range varcol {
    89  			ret[i] = types.GetArray[T](&varcol[i], v.area)
    90  		}
    91  		return ret
    92  	}
    93  }
    94  
    95  // ExpandFixedCol decode data and return decoded []T.
    96  // For const/scalar vector we expand and return newly allocated slice.
    97  func ExpandFixedCol[T any](v *Vector) []T {
    98  	if v.IsConst() {
    99  		vs := make([]T, v.Length())
   100  		if len(v.data) > 0 {
   101  			var cols []T
   102  			ToSlice(v, &cols)
   103  			for i := range vs {
   104  				vs[i] = cols[0]
   105  			}
   106  		}
   107  		return vs
   108  	}
   109  	return MustFixedCol[T](v)
   110  }
   111  
   112  func ExpandStrCol(v *Vector) []string {
   113  	if v.IsConst() {
   114  		vs := make([]string, v.Length())
   115  		if len(v.data) > 0 {
   116  			var cols []types.Varlena
   117  			ToSlice(v, &cols)
   118  			ss := cols[0].GetString(v.area)
   119  			for i := range vs {
   120  				vs[i] = ss
   121  			}
   122  		}
   123  		return vs
   124  	}
   125  	return MustStrCol(v)
   126  }
   127  
   128  func ExpandBytesCol(v *Vector) [][]byte {
   129  	if v.IsConst() {
   130  		vs := make([][]byte, v.Length())
   131  		if len(v.data) > 0 {
   132  			var cols []types.Varlena
   133  			ToSlice(v, &cols)
   134  			ss := cols[0].GetByteSlice(v.area)
   135  			for i := range vs {
   136  				vs[i] = ss
   137  			}
   138  		}
   139  		return vs
   140  	}
   141  	return MustBytesCol(v)
   142  }
   143  
   144  func MustVarlenaToInt64Slice(v *Vector) [][3]int64 {
   145  	data := MustFixedCol[types.Varlena](v)
   146  	pointer := (*[3]int64)(data[0].UnsafePtr())
   147  	return unsafe.Slice(pointer, len(data))
   148  }
   149  
   150  func MustVarlenaRawData(v *Vector) (data []types.Varlena, area []byte) {
   151  	data = MustFixedCol[types.Varlena](v)
   152  	area = v.area
   153  	return
   154  }
   155  
   156  // XXX extend will extend the vector's Data to accommodate rows more entry.
   157  func extend(v *Vector, rows int, m *mpool.MPool) error {
   158  	if tgtCap := v.length + rows; tgtCap > v.capacity {
   159  		sz := v.typ.TypeSize()
   160  		ndata, err := m.Grow(v.data, tgtCap*sz)
   161  		if err != nil {
   162  			return err
   163  		}
   164  		v.data = ndata[:cap(ndata)]
   165  		v.setupColFromData()
   166  	}
   167  	return nil
   168  }
   169  
   170  func (v *Vector) setupColFromData() {
   171  	if v.GetType().IsVarlen() {
   172  		v.col.setFromVector(v)
   173  	} else {
   174  		// The followng switch attach the correct type to v.col
   175  		// even though v.col is only an interface.
   176  		switch v.typ.Oid {
   177  		case types.T_bool:
   178  			v.col.setFromVector(v)
   179  		case types.T_bit:
   180  			v.col.setFromVector(v)
   181  		case types.T_int8:
   182  			v.col.setFromVector(v)
   183  		case types.T_int16:
   184  			v.col.setFromVector(v)
   185  		case types.T_int32:
   186  			v.col.setFromVector(v)
   187  		case types.T_int64:
   188  			v.col.setFromVector(v)
   189  		case types.T_uint8:
   190  			v.col.setFromVector(v)
   191  		case types.T_uint16:
   192  			v.col.setFromVector(v)
   193  		case types.T_uint32:
   194  			v.col.setFromVector(v)
   195  		case types.T_uint64:
   196  			v.col.setFromVector(v)
   197  		case types.T_float32:
   198  			v.col.setFromVector(v)
   199  		case types.T_float64:
   200  			v.col.setFromVector(v)
   201  		case types.T_decimal64:
   202  			v.col.setFromVector(v)
   203  		case types.T_decimal128:
   204  			v.col.setFromVector(v)
   205  		case types.T_uuid:
   206  			v.col.setFromVector(v)
   207  		case types.T_date:
   208  			v.col.setFromVector(v)
   209  		case types.T_time:
   210  			v.col.setFromVector(v)
   211  		case types.T_datetime:
   212  			v.col.setFromVector(v)
   213  		case types.T_timestamp:
   214  			v.col.setFromVector(v)
   215  		case types.T_TS:
   216  			v.col.setFromVector(v)
   217  		case types.T_Rowid:
   218  			v.col.setFromVector(v)
   219  		case types.T_Blockid:
   220  			v.col.setFromVector(v)
   221  		case types.T_enum:
   222  			v.col.setFromVector(v)
   223  		default:
   224  			panic(fmt.Sprintf("unknown type %s", v.typ.Oid))
   225  		}
   226  	}
   227  	tlen := v.GetType().TypeSize()
   228  	v.capacity = cap(v.data) / tlen
   229  }
   230  
   231  func VectorToProtoVector(vec *Vector) (ret api.Vector, err error) {
   232  	nsp, err := vec.nsp.Show()
   233  	if err != nil {
   234  		return
   235  	}
   236  	sz := vec.typ.TypeSize()
   237  	return api.Vector{
   238  		Nsp:      nsp,
   239  		Nullable: true,
   240  		Area:     vec.area,
   241  		IsConst:  vec.IsConst(),
   242  		Len:      uint32(vec.length),
   243  		Type:     TypeToProtoType(vec.typ),
   244  		Data:     vec.data[:vec.length*sz],
   245  	}, nil
   246  }
   247  
   248  func ProtoVectorToVector(vec api.Vector) (*Vector, error) {
   249  	rvec := &Vector{
   250  		area:         vec.Area,
   251  		length:       int(vec.Len),
   252  		typ:          ProtoTypeToType(vec.Type),
   253  		cantFreeData: true,
   254  		cantFreeArea: true,
   255  	}
   256  	if vec.IsConst {
   257  		rvec.class = CONSTANT
   258  	} else {
   259  		rvec.class = FLAT
   260  	}
   261  	if err := rvec.nsp.Read(vec.Nsp); err != nil {
   262  		return nil, err
   263  	}
   264  	if rvec.IsConst() && rvec.nsp.Contains(0) {
   265  		return rvec, nil
   266  	}
   267  	rvec.data = vec.Data
   268  	rvec.setupColFromData()
   269  	return rvec, nil
   270  }
   271  
   272  func TypeToProtoType(typ types.Type) *plan.Type {
   273  	return &plan.Type{
   274  		Id:    int32(typ.Oid),
   275  		Width: typ.Width,
   276  		Scale: typ.Scale,
   277  	}
   278  }
   279  
   280  func ProtoTypeToType(typ *plan.Type) types.Type {
   281  	return types.New(types.T(typ.Id), typ.Width, typ.Scale)
   282  }
   283  
   284  func appendBytesToFixSized[T types.FixedSizeT](vec *Vector) func([]byte, bool, *mpool.MPool) error {
   285  	return func(buf []byte, isNull bool, mp *mpool.MPool) (err error) {
   286  		v := types.DecodeFixed[T](buf)
   287  		return AppendFixed(vec, v, isNull, mp)
   288  	}
   289  }
   290  
   291  func MakeAppendBytesFunc(vec *Vector) func([]byte, bool, *mpool.MPool) error {
   292  	t := vec.GetType()
   293  	if t.IsVarlen() {
   294  		return func(v []byte, isNull bool, mp *mpool.MPool) (err error) {
   295  			return AppendBytes(vec, v, isNull, mp)
   296  		}
   297  	}
   298  	switch t.Oid {
   299  	case types.T_bool:
   300  		return appendBytesToFixSized[bool](vec)
   301  	case types.T_bit:
   302  		return appendBytesToFixSized[uint64](vec)
   303  	case types.T_int8:
   304  		return appendBytesToFixSized[int8](vec)
   305  	case types.T_int16:
   306  		return appendBytesToFixSized[int16](vec)
   307  	case types.T_int32:
   308  		return appendBytesToFixSized[int32](vec)
   309  	case types.T_int64:
   310  		return appendBytesToFixSized[int64](vec)
   311  	case types.T_uint8:
   312  		return appendBytesToFixSized[uint8](vec)
   313  	case types.T_uint16:
   314  		return appendBytesToFixSized[uint16](vec)
   315  	case types.T_uint32:
   316  		return appendBytesToFixSized[uint32](vec)
   317  	case types.T_uint64:
   318  		return appendBytesToFixSized[uint64](vec)
   319  	case types.T_float32:
   320  		return appendBytesToFixSized[float32](vec)
   321  	case types.T_float64:
   322  		return appendBytesToFixSized[float64](vec)
   323  	case types.T_date:
   324  		return appendBytesToFixSized[types.Date](vec)
   325  	case types.T_datetime:
   326  		return appendBytesToFixSized[types.Datetime](vec)
   327  	case types.T_time:
   328  		return appendBytesToFixSized[types.Time](vec)
   329  	case types.T_timestamp:
   330  		return appendBytesToFixSized[types.Timestamp](vec)
   331  	case types.T_enum:
   332  		return appendBytesToFixSized[types.Enum](vec)
   333  	case types.T_decimal64:
   334  		return appendBytesToFixSized[types.Decimal64](vec)
   335  	case types.T_decimal128:
   336  		return appendBytesToFixSized[types.Decimal128](vec)
   337  	case types.T_uuid:
   338  		return appendBytesToFixSized[types.Uuid](vec)
   339  	case types.T_TS:
   340  		return appendBytesToFixSized[types.TS](vec)
   341  	case types.T_Rowid:
   342  		return appendBytesToFixSized[types.Rowid](vec)
   343  	case types.T_Blockid:
   344  		return appendBytesToFixSized[types.Blockid](vec)
   345  	}
   346  	panic(fmt.Sprintf("unexpected type: %s", vec.GetType().String()))
   347  }