github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/colexec/vec_elem_to_datum.go (about) 1 // Copyright 2019 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package colexec 12 13 import ( 14 "math/big" 15 16 "github.com/cockroachdb/cockroach/pkg/col/coldata" 17 "github.com/cockroachdb/cockroach/pkg/col/coldataext" 18 "github.com/cockroachdb/cockroach/pkg/sql/colexecbase/colexecerror" 19 "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" 20 "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" 21 "github.com/cockroachdb/cockroach/pkg/sql/types" 22 "github.com/cockroachdb/cockroach/pkg/util/timeutil/pgdate" 23 "github.com/cockroachdb/cockroach/pkg/util/uuid" 24 "github.com/lib/pq/oid" 25 ) 26 27 // PhysicalTypeColElemToDatum converts an element in a colvec to a datum of 28 // type ct. The returned Datum is a deep copy of the colvec element. Note 29 // that this function handles nulls as well, so there is no need for a separate 30 // null check. 31 func PhysicalTypeColElemToDatum( 32 col coldata.Vec, rowIdx int, da *sqlbase.DatumAlloc, ct *types.T, 33 ) tree.Datum { 34 if col.MaybeHasNulls() { 35 if col.Nulls().NullAt(rowIdx) { 36 return tree.DNull 37 } 38 } 39 switch ct.Family() { 40 case types.BoolFamily: 41 if col.Bool()[rowIdx] { 42 return tree.DBoolTrue 43 } 44 return tree.DBoolFalse 45 case types.IntFamily: 46 switch ct.Width() { 47 case 16: 48 return da.NewDInt(tree.DInt(col.Int16()[rowIdx])) 49 case 32: 50 return da.NewDInt(tree.DInt(col.Int32()[rowIdx])) 51 default: 52 return da.NewDInt(tree.DInt(col.Int64()[rowIdx])) 53 } 54 case types.FloatFamily: 55 return da.NewDFloat(tree.DFloat(col.Float64()[rowIdx])) 56 case types.DecimalFamily: 57 d := da.NewDDecimal(tree.DDecimal{Decimal: col.Decimal()[rowIdx]}) 58 // Clear the Coeff so that the Set below allocates a new slice for the 59 // Coeff.abs field. 60 d.Coeff = big.Int{} 61 d.Coeff.Set(&col.Decimal()[rowIdx].Coeff) 62 return d 63 case types.DateFamily: 64 return tree.NewDDate(pgdate.MakeCompatibleDateFromDisk(col.Int64()[rowIdx])) 65 case types.StringFamily: 66 // Note that there is no need for a copy since casting to a string will do 67 // that. 68 b := col.Bytes().Get(rowIdx) 69 if ct.Oid() == oid.T_name { 70 return da.NewDName(tree.DString(string(b))) 71 } 72 return da.NewDString(tree.DString(string(b))) 73 case types.BytesFamily: 74 // Note that there is no need for a copy since DBytes uses a string as 75 // underlying storage, which will perform the copy for us. 76 return da.NewDBytes(tree.DBytes(col.Bytes().Get(rowIdx))) 77 case types.OidFamily: 78 return da.NewDOid(tree.MakeDOid(tree.DInt(col.Int64()[rowIdx]))) 79 case types.UuidFamily: 80 // Note that there is no need for a copy because uuid.FromBytes will perform 81 // a copy. 82 id, err := uuid.FromBytes(col.Bytes().Get(rowIdx)) 83 if err != nil { 84 colexecerror.InternalError(err) 85 } 86 return da.NewDUuid(tree.DUuid{UUID: id}) 87 case types.TimestampFamily: 88 return da.NewDTimestamp(tree.DTimestamp{Time: col.Timestamp()[rowIdx]}) 89 case types.TimestampTZFamily: 90 return da.NewDTimestampTZ(tree.DTimestampTZ{Time: col.Timestamp()[rowIdx]}) 91 case types.IntervalFamily: 92 return da.NewDInterval(tree.DInterval{Duration: col.Interval()[rowIdx]}) 93 default: 94 return col.Datum().Get(rowIdx).(*coldataext.Datum).Datum 95 } 96 }