From 9d5d1c57b9c384df401cd7d7b9baf68aa011e687 Mon Sep 17 00:00:00 2001 From: Jordan Lewis Date: Tue, 27 Aug 2019 13:11:04 -0400 Subject: [PATCH] colexec,coldata: support timestamp type This commit adds support for the TIMESTAMP type to the coldata and colexec packages. Release note: None --- pkg/col/coldata/vec.go | 9 +++++ pkg/col/coldata/vec_tmpl.go | 4 +++ pkg/col/colserde/arrowbatchconverter_test.go | 6 ++-- pkg/col/colserde/record_batch_test.go | 4 +-- pkg/col/coltypes/t_string.go | 7 ++-- pkg/col/coltypes/types.go | 8 +++++ pkg/sql/colencoding/key_encoding.go | 10 ++++++ pkg/sql/colencoding/value_encoding.go | 6 ++++ pkg/sql/colexec/any_not_null_agg_tmpl.go | 5 +++ pkg/sql/colexec/const_tmpl.go | 4 +++ pkg/sql/colexec/distinct_tmpl.go | 4 +++ .../colexec/execgen/cmd/execgen/overloads.go | 35 +++++++++++++++++++ .../cmd/execgen/overloads_test_utils_gen.go | 1 + pkg/sql/colexec/mem_estimation.go | 3 ++ pkg/sql/colexec/mergejoinbase_tmpl.go | 4 +++ pkg/sql/colexec/mergejoiner_tmpl.go | 4 +++ pkg/sql/colexec/min_max_agg_tmpl.go | 4 +++ pkg/sql/colexec/proj_const_ops_tmpl.go | 4 +++ pkg/sql/colexec/random_testutils.go | 6 ++++ pkg/sql/colexec/rowstovec_tmpl.go | 4 +++ pkg/sql/colexec/select_in_tmpl.go | 4 +++ pkg/sql/colexec/selection_ops_tmpl.go | 4 +++ pkg/sql/colexec/sort_tmpl.go | 4 +++ pkg/sql/colexec/supported_sql_types.go | 1 + pkg/sql/colexec/typeconv/typeconv.go | 10 ++++++ pkg/sql/colexec/types_integration_test.go | 4 +-- pkg/sql/colexec/vec_comparators_tmpl.go | 4 +++ pkg/sql/colexec/vec_elem_to_datum.go | 2 ++ pkg/sql/colexec/zerocolumns_tmpl.go | 5 +++ pkg/sql/opt/exec/execbuilder/testdata/explain | 2 +- pkg/sql/sqlbase/testutils.go | 2 +- 31 files changed, 162 insertions(+), 12 deletions(-) diff --git a/pkg/col/coldata/vec.go b/pkg/col/coldata/vec.go index 7405631d51a5..824eae30cb10 100644 --- a/pkg/col/coldata/vec.go +++ b/pkg/col/coldata/vec.go @@ -12,6 +12,7 @@ package coldata import ( "fmt" + "time" "github.com/cockroachdb/apd" "github.com/cockroachdb/cockroach/pkg/col/coltypes" @@ -76,6 +77,8 @@ type Vec interface { // TODO(jordan): should this be [][]byte? // Decimal returns an apd.Decimal slice. Decimal() []apd.Decimal + // Timestamp returns a time.Time slice. + Timestamp() []time.Time // Col returns the raw, typeless backing storage for this Vec. Col() interface{} @@ -151,6 +154,8 @@ func NewMemColumn(t coltypes.T, n int) Vec { return &memColumn{t: t, col: make([]float64, n), nulls: nulls} case coltypes.Decimal: return &memColumn{t: t, col: make([]apd.Decimal, n), nulls: nulls} + case coltypes.Timestamp: + return &memColumn{t: t, col: make([]time.Time, n), nulls: nulls} default: panic(fmt.Sprintf("unhandled type %s", t)) } @@ -192,6 +197,10 @@ func (m *memColumn) Decimal() []apd.Decimal { return m.col.([]apd.Decimal) } +func (m *memColumn) Timestamp() []time.Time { + return m.col.([]time.Time) +} + func (m *memColumn) Col() interface{} { return m.col } diff --git a/pkg/col/coldata/vec_tmpl.go b/pkg/col/coldata/vec_tmpl.go index 141dcd7d535c..d81ce6482b99 100644 --- a/pkg/col/coldata/vec_tmpl.go +++ b/pkg/col/coldata/vec_tmpl.go @@ -21,6 +21,7 @@ package coldata import ( "fmt" + "time" "github.com/cockroachdb/apd" "github.com/cockroachdb/cockroach/pkg/col/coltypes" @@ -45,6 +46,9 @@ type _GOTYPESLICE interface{} // Dummy import to pull in "apd" package. var _ apd.Decimal +// Dummy import to pull in "time" package. +var _ time.Time + // */}} func (m *memColumn) Append(args SliceArgs) { diff --git a/pkg/col/colserde/arrowbatchconverter_test.go b/pkg/col/colserde/arrowbatchconverter_test.go index 3fed44ca10d7..b9c69ecabbff 100644 --- a/pkg/col/colserde/arrowbatchconverter_test.go +++ b/pkg/col/colserde/arrowbatchconverter_test.go @@ -30,8 +30,8 @@ func randomBatch() ([]coltypes.T, coldata.Batch) { availableTyps := make([]coltypes.T, 0, len(coltypes.AllTypes)) for _, typ := range coltypes.AllTypes { - // TODO(asubiotto): We do not support decimal conversion yet. - if typ == coltypes.Decimal { + // TODO(asubiotto,jordan): We do not support decimal, timestamp conversion yet. + if typ == coltypes.Decimal || typ == coltypes.Timestamp { continue } availableTyps = append(availableTyps, typ) @@ -119,7 +119,7 @@ func assertEqualBatches(t *testing.T, expected, actual coldata.Batch) { func TestArrowBatchConverterRejectsUnsupportedTypes(t *testing.T) { defer leaktest.AfterTest(t)() - typs := []coltypes.T{coltypes.Decimal} + typs := []coltypes.T{coltypes.Decimal, coltypes.Timestamp} _, err := NewArrowBatchConverter(typs) require.Error(t, err) } diff --git a/pkg/col/colserde/record_batch_test.go b/pkg/col/colserde/record_batch_test.go index dfd61635e672..c9f0aaafb16b 100644 --- a/pkg/col/colserde/record_batch_test.go +++ b/pkg/col/colserde/record_batch_test.go @@ -180,9 +180,9 @@ func TestRecordBatchSerializerSerializeDeserializeRandom(t *testing.T) { buf = bytes.Buffer{} ) - // We do not support decimals yet. + // We do not support decimals or timestamps yet. for _, t := range coltypes.AllTypes { - if t == coltypes.Decimal { + if t == coltypes.Decimal || t == coltypes.Timestamp { continue } supportedTypes = append(supportedTypes, t) diff --git a/pkg/col/coltypes/t_string.go b/pkg/col/coltypes/t_string.go index ed520b42be55..641a18a99df7 100644 --- a/pkg/col/coltypes/t_string.go +++ b/pkg/col/coltypes/t_string.go @@ -15,12 +15,13 @@ func _() { _ = x[Int32-4] _ = x[Int64-5] _ = x[Float64-6] - _ = x[Unhandled-7] + _ = x[Timestamp-7] + _ = x[Unhandled-8] } -const _T_name = "BoolBytesDecimalInt16Int32Int64Float64Unhandled" +const _T_name = "BoolBytesDecimalInt16Int32Int64Float64TimestampUnhandled" -var _T_index = [...]uint8{0, 4, 9, 16, 21, 26, 31, 38, 47} +var _T_index = [...]uint8{0, 4, 9, 16, 21, 26, 31, 38, 47, 56} func (i T) String() string { if i < 0 || i >= T(len(_T_index)-1) { diff --git a/pkg/col/coltypes/types.go b/pkg/col/coltypes/types.go index ca0feaa4ac96..d7dab0713cfe 100644 --- a/pkg/col/coltypes/types.go +++ b/pkg/col/coltypes/types.go @@ -14,6 +14,7 @@ import ( "fmt" "strings" "text/template" + "time" "github.com/cockroachdb/apd" ) @@ -38,6 +39,8 @@ const ( Int64 // Float64 is a column of type float64 Float64 + // Timestamp is a column of type time.Time + Timestamp // Unhandled is a temporary value that represents an unhandled type. // TODO(jordan): this should be replaced by a panic once all types are @@ -74,6 +77,7 @@ func init() { CompatibleTypes[Int32] = append(CompatibleTypes[Int32], NumberTypes...) CompatibleTypes[Int64] = append(CompatibleTypes[Int64], NumberTypes...) CompatibleTypes[Float64] = append(CompatibleTypes[Float64], NumberTypes...) + CompatibleTypes[Timestamp] = append(CompatibleTypes[Timestamp], Timestamp) } // FromGoType returns the type for a Go value, if applicable. Shouldn't be used at @@ -96,6 +100,8 @@ func FromGoType(v interface{}) T { return Bytes case apd.Decimal: return Decimal + case time.Time: + return Timestamp default: panic(fmt.Sprintf("type %T not supported yet", t)) } @@ -118,6 +124,8 @@ func (t T) GoTypeName() string { return "int64" case Float64: return "float64" + case Timestamp: + return "time.Time" default: panic(fmt.Sprintf("unhandled type %d", t)) } diff --git a/pkg/sql/colencoding/key_encoding.go b/pkg/sql/colencoding/key_encoding.go index bfa6f8c49358..f859c932d839 100644 --- a/pkg/sql/colencoding/key_encoding.go +++ b/pkg/sql/colencoding/key_encoding.go @@ -11,6 +11,8 @@ package colencoding import ( + "time" + "github.com/cockroachdb/apd" "github.com/cockroachdb/cockroach/pkg/col/coldata" "github.com/cockroachdb/cockroach/pkg/roachpb" @@ -225,6 +227,14 @@ func decodeTableKeyToCol( rkey, t, err = encoding.DecodeVarintDescending(key) } vec.Int64()[idx] = t + case types.TimestampFamily: + var t time.Time + if dir == sqlbase.IndexDescriptor_ASC { + rkey, t, err = encoding.DecodeTimeAscending(key) + } else { + rkey, t, err = encoding.DecodeTimeDescending(key) + } + vec.Timestamp()[idx] = t default: return rkey, errors.AssertionFailedf("unsupported type %+v", log.Safe(valType)) } diff --git a/pkg/sql/colencoding/value_encoding.go b/pkg/sql/colencoding/value_encoding.go index b3d743734e83..a425f93aed64 100644 --- a/pkg/sql/colencoding/value_encoding.go +++ b/pkg/sql/colencoding/value_encoding.go @@ -11,6 +11,8 @@ package colencoding import ( + "time" + "github.com/cockroachdb/cockroach/pkg/col/coldata" "github.com/cockroachdb/cockroach/pkg/sql/types" "github.com/cockroachdb/cockroach/pkg/util/encoding" @@ -91,6 +93,10 @@ func decodeUntaggedDatumToCol(vec coldata.Vec, idx uint16, t *types.T, buf []byt if err == nil { vec.Bytes().Set(int(idx), data.GetBytes()) } + case types.TimestampFamily: + var t time.Time + buf, t, err = encoding.DecodeUntaggedTimeValue(buf) + vec.Timestamp()[idx] = t default: return buf, errors.AssertionFailedf( "couldn't decode type: %s", log.Safe(t)) diff --git a/pkg/sql/colexec/any_not_null_agg_tmpl.go b/pkg/sql/colexec/any_not_null_agg_tmpl.go index 33a1c9024f12..edad3b7d3932 100644 --- a/pkg/sql/colexec/any_not_null_agg_tmpl.go +++ b/pkg/sql/colexec/any_not_null_agg_tmpl.go @@ -20,6 +20,8 @@ package colexec import ( + "time" + "github.com/cockroachdb/apd" "github.com/cockroachdb/cockroach/pkg/col/coldata" "github.com/cockroachdb/cockroach/pkg/col/coltypes" @@ -45,6 +47,9 @@ func newAnyNotNullAgg(t coltypes.T) (aggregateFunc, error) { // Dummy import to pull in "apd" package. var _ apd.Decimal +// Dummy import to pull in "time" package. +var _ time.Time + // _GOTYPESLICE is the template Go type slice variable for this operator. It // will be replaced by the Go slice representation for each type in coltypes.T, for // example []int64 for coltypes.Int64. diff --git a/pkg/sql/colexec/const_tmpl.go b/pkg/sql/colexec/const_tmpl.go index 9150086c008b..38c80241a931 100644 --- a/pkg/sql/colexec/const_tmpl.go +++ b/pkg/sql/colexec/const_tmpl.go @@ -21,6 +21,7 @@ package colexec import ( "context" + "time" "github.com/cockroachdb/apd" "github.com/cockroachdb/cockroach/pkg/col/coldata" @@ -36,6 +37,9 @@ import ( // Dummy import to pull in "apd" package. var _ apd.Decimal +// Dummy import to pull in "time" package. +var _ time.Time + // _TYPES_T is the template type variable for coltypes.T. It will be replaced by // coltypes.Foo for each type Foo in the coltypes.T type. const _TYPES_T = coltypes.Unhandled diff --git a/pkg/sql/colexec/distinct_tmpl.go b/pkg/sql/colexec/distinct_tmpl.go index 6b42d4006d60..9e9f36fb83ea 100644 --- a/pkg/sql/colexec/distinct_tmpl.go +++ b/pkg/sql/colexec/distinct_tmpl.go @@ -23,6 +23,7 @@ import ( "bytes" "context" "math" + "time" "github.com/cockroachdb/apd" "github.com/cockroachdb/cockroach/pkg/col/coldata" @@ -104,6 +105,9 @@ var _ bytes.Buffer // Dummy import to pull in "apd" package. var _ apd.Decimal +// Dummy import to pull in "time" package. +var _ time.Time + // Dummy import to pull in "tree" package. var _ tree.Datum diff --git a/pkg/sql/colexec/execgen/cmd/execgen/overloads.go b/pkg/sql/colexec/execgen/cmd/execgen/overloads.go index 2c5e9d877453..e92e68933aae 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/overloads.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/overloads.go @@ -537,6 +537,9 @@ type floatIntCustomizer struct{} // side and a float right-hand side. type intFloatCustomizer struct{} +// timestampCustomizer is necessary since time.Time doesn't have infix operators. +type timestampCustomizer struct{} + func (boolCustomizer) getCmpOpCompareFunc() compareFunc { return func(target, l, r string) string { args := map[string]string{"Target": target, "Left": l, "Right": r} @@ -997,11 +1000,43 @@ func (c intFloatCustomizer) getCmpOpCompareFunc() compareFunc { return getFloatCmpOpCompareFunc(false /* checkLeftNan */, true /* checkRightNan */) } +func (c timestampCustomizer) getCmpOpCompareFunc() compareFunc { + return func(target, l, r string) string { + args := map[string]string{"Target": target, "Left": l, "Right": r} + buf := strings.Builder{} + // Inline the code from tree.compareTimestamps. + t := template.Must(template.New("").Parse(` + if {{.Left}}.Before({{.Right}}) { + {{.Target}} = -1 + } else if {{.Right}}.Before({{.Left}}) { + {{.Target}} = 1 + } else { + {{.Target}} = 0 + }`)) + + if err := t.Execute(&buf, args); err != nil { + execerror.VectorizedInternalPanic(err) + } + return buf.String() + } +} + +func (timestampCustomizer) getHashAssignFunc() assignFunc { + return func(op overload, target, v, _ string) string { + return fmt.Sprintf(` + s, ns := %[2]s.Second(), %[2]s.Nanosecond() + %[1]s = memhash64(noescape(unsafe.Pointer(&s)), %[1]s) + %[1]s = memhash64(noescape(unsafe.Pointer(&ns)), %[1]s) + `, target, v) + } +} + func registerTypeCustomizers() { typeCustomizers = make(map[coltypePair]typeCustomizer) registerTypeCustomizer(coltypePair{coltypes.Bool, coltypes.Bool}, boolCustomizer{}) registerTypeCustomizer(coltypePair{coltypes.Bytes, coltypes.Bytes}, bytesCustomizer{}) registerTypeCustomizer(coltypePair{coltypes.Decimal, coltypes.Decimal}, decimalCustomizer{}) + registerTypeCustomizer(coltypePair{coltypes.Timestamp, coltypes.Timestamp}, timestampCustomizer{}) for _, leftFloatType := range coltypes.FloatTypes { for _, rightFloatType := range coltypes.FloatTypes { registerTypeCustomizer(coltypePair{leftFloatType, rightFloatType}, floatCustomizer{width: 64}) diff --git a/pkg/sql/colexec/execgen/cmd/execgen/overloads_test_utils_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/overloads_test_utils_gen.go index f700b7435eea..b6038b74d0b3 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/overloads_test_utils_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/overloads_test_utils_gen.go @@ -21,6 +21,7 @@ package colexec import ( "bytes" "math" + "time" "github.com/cockroachdb/apd" "github.com/cockroachdb/cockroach/pkg/sql/colexec/execerror" diff --git a/pkg/sql/colexec/mem_estimation.go b/pkg/sql/colexec/mem_estimation.go index 501f9ba88b94..59dd150c91f4 100644 --- a/pkg/sql/colexec/mem_estimation.go +++ b/pkg/sql/colexec/mem_estimation.go @@ -55,6 +55,9 @@ func EstimateBatchSizeBytes(vecTypes []coltypes.T, batchLength int) int { // Similar to byte arrays, we can't tell how much space is used // to hold the arbitrary precision decimal objects. acc += 50 + case coltypes.Timestamp: + // time.Time has 2 int64s and a pointer. + acc += sizeOfInt64 * 3 default: execerror.VectorizedInternalPanic(fmt.Sprintf("unhandled type %s", t)) } diff --git a/pkg/sql/colexec/mergejoinbase_tmpl.go b/pkg/sql/colexec/mergejoinbase_tmpl.go index 0fdb10ac21df..1d00007846f4 100644 --- a/pkg/sql/colexec/mergejoinbase_tmpl.go +++ b/pkg/sql/colexec/mergejoinbase_tmpl.go @@ -23,6 +23,7 @@ import ( "bytes" "fmt" "math" + "time" "github.com/cockroachdb/apd" "github.com/cockroachdb/cockroach/pkg/col/coldata" @@ -44,6 +45,9 @@ var _ tree.Datum // Dummy import to pull in "apd" package. var _ apd.Decimal +// Dummy import to pull in "time" package. +var _ time.Time + // Dummy import to pull in "math" package. var _ = math.MaxInt64 diff --git a/pkg/sql/colexec/mergejoiner_tmpl.go b/pkg/sql/colexec/mergejoiner_tmpl.go index bc3754d08032..3570469ad094 100644 --- a/pkg/sql/colexec/mergejoiner_tmpl.go +++ b/pkg/sql/colexec/mergejoiner_tmpl.go @@ -24,6 +24,7 @@ import ( "context" "fmt" "math" + "time" "github.com/cockroachdb/apd" "github.com/cockroachdb/cockroach/pkg/col/coldata" @@ -46,6 +47,9 @@ var _ tree.Datum // Dummy import to pull in "apd" package. var _ apd.Decimal +// Dummy import to pull in "time" package. +var _ time.Time + // Dummy import to pull in "math" package. var _ = math.MaxInt64 diff --git a/pkg/sql/colexec/min_max_agg_tmpl.go b/pkg/sql/colexec/min_max_agg_tmpl.go index bb5ee3007d1c..47e7300dff03 100644 --- a/pkg/sql/colexec/min_max_agg_tmpl.go +++ b/pkg/sql/colexec/min_max_agg_tmpl.go @@ -22,6 +22,7 @@ package colexec import ( "bytes" "math" + "time" "github.com/cockroachdb/apd" "github.com/cockroachdb/cockroach/pkg/col/coldata" @@ -43,6 +44,9 @@ var _ bytes.Buffer // Dummy import to pull in "apd" package. var _ apd.Decimal +// Dummy import to pull in "time" package. +var _ time.Time + // Dummy import to pull in "tree" package. var _ tree.Datum diff --git a/pkg/sql/colexec/proj_const_ops_tmpl.go b/pkg/sql/colexec/proj_const_ops_tmpl.go index 46e6cd6798b1..4b09a61ca163 100644 --- a/pkg/sql/colexec/proj_const_ops_tmpl.go +++ b/pkg/sql/colexec/proj_const_ops_tmpl.go @@ -23,6 +23,7 @@ import ( "bytes" "context" "math" + "time" "github.com/cockroachdb/apd" "github.com/cockroachdb/cockroach/pkg/col/coldata" @@ -52,6 +53,9 @@ var _ tree.Datum // Dummy import to pull in "math" package. var _ = math.MaxInt64 +// Dummy import to pull in "time" package. +var _ = time.Day + // _ASSIGN is the template function for assigning the first input to the result // of computation an operation on the second and the third inputs. func _ASSIGN(_, _, _ interface{}) { diff --git a/pkg/sql/colexec/random_testutils.go b/pkg/sql/colexec/random_testutils.go index 9e1432c4ead7..4f5158767e88 100644 --- a/pkg/sql/colexec/random_testutils.go +++ b/pkg/sql/colexec/random_testutils.go @@ -18,6 +18,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/col/coldata" "github.com/cockroachdb/cockroach/pkg/col/coltypes" "github.com/cockroachdb/cockroach/pkg/sql/colexec/execerror" + "github.com/cockroachdb/cockroach/pkg/util/timeutil" ) // maxVarLen specifies a length limit for variable length types (e.g. byte slices). @@ -84,6 +85,11 @@ func RandomVec(rng *rand.Rand, typ coltypes.T, vec coldata.Vec, n int, nullProba for i := 0; i < n; i++ { floats[i] = rng.Float64() } + case coltypes.Timestamp: + timestamps := vec.Timestamp() + for i := 0; i < n; i++ { + timestamps[i] = timeutil.Unix(rng.Int63n(1000000), rng.Int63n(1000000)) + } default: execerror.VectorizedInternalPanic(fmt.Sprintf("unhandled type %s", typ)) } diff --git a/pkg/sql/colexec/rowstovec_tmpl.go b/pkg/sql/colexec/rowstovec_tmpl.go index e4f82e6dc97b..28f7383baffc 100644 --- a/pkg/sql/colexec/rowstovec_tmpl.go +++ b/pkg/sql/colexec/rowstovec_tmpl.go @@ -21,6 +21,7 @@ package colexec import ( "fmt" + "time" "github.com/cockroachdb/apd" "github.com/cockroachdb/cockroach/pkg/col/coldata" @@ -37,6 +38,9 @@ import ( // Dummy import to pull in "apd" package. var _ apd.Decimal +// Dummy import to pull in "time" package. +var _ time.Time + const ( _FAMILY = types.Family(0) _WIDTH = int32(0) diff --git a/pkg/sql/colexec/select_in_tmpl.go b/pkg/sql/colexec/select_in_tmpl.go index 8848260a38fb..4b5379ef2a2e 100644 --- a/pkg/sql/colexec/select_in_tmpl.go +++ b/pkg/sql/colexec/select_in_tmpl.go @@ -23,6 +23,7 @@ import ( "bytes" "context" "math" + "time" "github.com/cockroachdb/apd" "github.com/cockroachdb/cockroach/pkg/col/coldata" @@ -45,6 +46,9 @@ type _TYPE interface{} // Dummy import to pull in "apd" package. var _ apd.Decimal +// Dummy import to pull in "time" package. +var _ time.Time + // Dummy import to pull in "coltypes" package var _ coltypes.T diff --git a/pkg/sql/colexec/selection_ops_tmpl.go b/pkg/sql/colexec/selection_ops_tmpl.go index 2014a7cb6282..20cdfbac7bd7 100644 --- a/pkg/sql/colexec/selection_ops_tmpl.go +++ b/pkg/sql/colexec/selection_ops_tmpl.go @@ -23,6 +23,7 @@ import ( "bytes" "context" "math" + "time" "github.com/cockroachdb/apd" "github.com/cockroachdb/cockroach/pkg/col/coldata" @@ -52,6 +53,9 @@ var _ tree.Datum // Dummy import to pull in "math" package. var _ = math.MaxInt64 +// Dummy import to pull in "time" package. +var _ = time.Day + // Dummy import to pull in "coltypes" package. var _ = coltypes.Bool diff --git a/pkg/sql/colexec/sort_tmpl.go b/pkg/sql/colexec/sort_tmpl.go index 34998092fa26..b2ef9e1a4e2f 100644 --- a/pkg/sql/colexec/sort_tmpl.go +++ b/pkg/sql/colexec/sort_tmpl.go @@ -24,6 +24,7 @@ import ( "context" "fmt" "math" + "time" "github.com/cockroachdb/apd" "github.com/cockroachdb/cockroach/pkg/col/coldata" @@ -44,6 +45,9 @@ var _ bytes.Buffer // Dummy import to pull in "apd" package. var _ apd.Decimal +// Dummy import to pull in "time" package. +var _ time.Time + // Dummy import to pull in "tree" package. var _ tree.Datum diff --git a/pkg/sql/colexec/supported_sql_types.go b/pkg/sql/colexec/supported_sql_types.go index 3f6dcf9aea1f..6c84b85c212d 100644 --- a/pkg/sql/colexec/supported_sql_types.go +++ b/pkg/sql/colexec/supported_sql_types.go @@ -27,4 +27,5 @@ var allSupportedSQLTypes = []types.T{ *types.Float4, *types.String, *types.Uuid, + *types.Timestamp, } diff --git a/pkg/sql/colexec/typeconv/typeconv.go b/pkg/sql/colexec/typeconv/typeconv.go index e6c24aadc07c..64df0c392b9a 100644 --- a/pkg/sql/colexec/typeconv/typeconv.go +++ b/pkg/sql/colexec/typeconv/typeconv.go @@ -47,6 +47,8 @@ func FromColumnType(ct *types.T) coltypes.T { execerror.VectorizedInternalPanic(fmt.Sprintf("integer with unknown width %d", ct.Width())) case types.FloatFamily: return coltypes.Float64 + case types.TimestampFamily: + return coltypes.Timestamp } return coltypes.Unhandled } @@ -210,6 +212,14 @@ func GetDatumToPhysicalFn(ct *types.T) func(tree.Datum) (interface{}, error) { } return d.UUID.GetBytesMut(), nil } + case types.TimestampFamily: + return func(datum tree.Datum) (interface{}, error) { + d, ok := datum.(*tree.DTimestamp) + if !ok { + return nil, errors.Errorf("expected *tree.DTimestamp, found %s", reflect.TypeOf(datum)) + } + return d.Time, nil + } } // It would probably be more correct to return an error here, rather than a // function which always returns an error. But since the function tends to be diff --git a/pkg/sql/colexec/types_integration_test.go b/pkg/sql/colexec/types_integration_test.go index c543d3fc829f..585668c2d967 100644 --- a/pkg/sql/colexec/types_integration_test.go +++ b/pkg/sql/colexec/types_integration_test.go @@ -59,8 +59,8 @@ func TestSupportedSQLTypesIntegration(t *testing.T) { rng, _ := randutil.NewPseudoRand() for _, typ := range allSupportedSQLTypes { - if typ.Equal(*types.Decimal) { - // Serialization of Decimals is currently not supported. + if typ.Equal(*types.Decimal) || typ.Equal(*types.Timestamp) { + // Serialization of Decimals and Timestamps is currently not supported. // TODO(yuzefovich): remove this once it is supported. continue } diff --git a/pkg/sql/colexec/vec_comparators_tmpl.go b/pkg/sql/colexec/vec_comparators_tmpl.go index 5b02564eca73..713948a25fd5 100644 --- a/pkg/sql/colexec/vec_comparators_tmpl.go +++ b/pkg/sql/colexec/vec_comparators_tmpl.go @@ -23,6 +23,7 @@ import ( "bytes" "fmt" "math" + "time" "github.com/cockroachdb/apd" "github.com/cockroachdb/cockroach/pkg/col/coldata" @@ -44,6 +45,9 @@ var _ bytes.Buffer // Dummy import to pull in "apd" package. var _ apd.Decimal +// Dummy import to pull in "time" package. +var _ time.Time + // Dummy import to pull in "tree" package. var _ tree.Datum diff --git a/pkg/sql/colexec/vec_elem_to_datum.go b/pkg/sql/colexec/vec_elem_to_datum.go index c84932e4c912..d0ffb4c946a4 100644 --- a/pkg/sql/colexec/vec_elem_to_datum.go +++ b/pkg/sql/colexec/vec_elem_to_datum.go @@ -72,6 +72,8 @@ func PhysicalTypeColElemToDatum( execerror.VectorizedInternalPanic(err) } return da.NewDUuid(tree.DUuid{UUID: id}) + case types.TimestampFamily: + return da.NewDTimestamp(tree.DTimestamp{Time: col.Timestamp()[rowIdx]}) default: execerror.VectorizedInternalPanic(fmt.Sprintf("Unsupported column type %s", ct.String())) // This code is unreachable, but the compiler cannot infer that. diff --git a/pkg/sql/colexec/zerocolumns_tmpl.go b/pkg/sql/colexec/zerocolumns_tmpl.go index 71c1c9310c72..d2de183cd474 100644 --- a/pkg/sql/colexec/zerocolumns_tmpl.go +++ b/pkg/sql/colexec/zerocolumns_tmpl.go @@ -20,6 +20,8 @@ package colexec import ( + "time" + "github.com/cockroachdb/apd" "github.com/cockroachdb/cockroach/pkg/col/coldata" ) @@ -30,6 +32,9 @@ import ( // Dummy import to pull in "apd" package. var _ apd.Decimal +// Dummy import to pull in "time" package. +var _ time.Time + // */}} // {{range .}} diff --git a/pkg/sql/opt/exec/execbuilder/testdata/explain b/pkg/sql/opt/exec/execbuilder/testdata/explain index 87f1b1e5b380..58cb767d5a00 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/explain +++ b/pkg/sql/opt/exec/execbuilder/testdata/explain @@ -21,7 +21,7 @@ EXPLAIN (PLAN) SELECT 1 FROM system.jobs WHERE TRUE ---- tree field description · distributed false -· vectorized false +· vectorized true render · · └── scan · · · table jobs@jobs_status_created_idx diff --git a/pkg/sql/sqlbase/testutils.go b/pkg/sql/sqlbase/testutils.go index 63e559f920d5..afb08b23acf4 100644 --- a/pkg/sql/sqlbase/testutils.go +++ b/pkg/sql/sqlbase/testutils.go @@ -159,7 +159,7 @@ func RandDatumWithNullChance(rng *rand.Rand, typ *types.T, nullChance int) tree. case types.TimeFamily: return tree.MakeDTime(timeofday.Random(rng)) case types.TimestampFamily: - return &tree.DTimestamp{Time: timeutil.Unix(rng.Int63n(1000000), rng.Int63n(1000000))} + return tree.MakeDTimestamp(timeutil.Unix(rng.Int63n(1000000), rng.Int63n(1000000)), time.Microsecond) case types.IntervalFamily: sign := 1 - rng.Int63n(2)*2 return &tree.DInterval{Duration: duration.MakeDuration(