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  }