github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/rowexec/values_test.go (about) 1 // Copyright 2017 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 rowexec 12 13 import ( 14 "context" 15 "fmt" 16 "testing" 17 18 "github.com/cockroachdb/cockroach/pkg/settings/cluster" 19 "github.com/cockroachdb/cockroach/pkg/sql/execinfra" 20 "github.com/cockroachdb/cockroach/pkg/sql/execinfrapb" 21 "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" 22 "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" 23 "github.com/cockroachdb/cockroach/pkg/testutils/distsqlutils" 24 "github.com/cockroachdb/cockroach/pkg/util/leaktest" 25 "github.com/cockroachdb/cockroach/pkg/util/randutil" 26 ) 27 28 func TestValuesProcessor(t *testing.T) { 29 defer leaktest.AfterTest(t)() 30 rng, _ := randutil.NewPseudoRand() 31 for _, numRows := range []int{0, 1, 10, 13, 15} { 32 for _, numCols := range []int{1, 3} { 33 for _, rowsPerChunk := range []int{1, 2, 5} { 34 t.Run(fmt.Sprintf("%d-%d-%d", numRows, numCols, rowsPerChunk), func(t *testing.T) { 35 inRows, colTypes := sqlbase.RandEncDatumRows(rng, numRows, numCols) 36 37 spec, err := execinfra.GenerateValuesSpec(colTypes, inRows, rowsPerChunk) 38 if err != nil { 39 t.Fatal(err) 40 } 41 42 out := &distsqlutils.RowBuffer{} 43 st := cluster.MakeTestingClusterSettings() 44 evalCtx := tree.NewTestingEvalContext(st) 45 defer evalCtx.Stop(context.Background()) 46 flowCtx := execinfra.FlowCtx{ 47 Cfg: &execinfra.ServerConfig{Settings: st}, 48 EvalCtx: evalCtx, 49 } 50 51 v, err := newValuesProcessor(&flowCtx, 0 /* processorID */, &spec, &execinfrapb.PostProcessSpec{}, out) 52 if err != nil { 53 t.Fatal(err) 54 } 55 v.Run(context.Background()) 56 if !out.ProducerClosed() { 57 t.Fatalf("output RowReceiver not closed") 58 } 59 60 var res sqlbase.EncDatumRows 61 for { 62 row := out.NextNoMeta(t) 63 if row == nil { 64 break 65 } 66 res = append(res, row) 67 } 68 69 if len(res) != numRows { 70 t.Fatalf("incorrect number of rows %d, expected %d", len(res), numRows) 71 } 72 73 var a sqlbase.DatumAlloc 74 for i := 0; i < numRows; i++ { 75 if len(res[i]) != numCols { 76 t.Fatalf("row %d incorrect length %d, expected %d", i, len(res[i]), numCols) 77 } 78 for j, val := range res[i] { 79 cmp, err := val.Compare(colTypes[j], &a, evalCtx, &inRows[i][j]) 80 if err != nil { 81 t.Fatal(err) 82 } 83 if cmp != 0 { 84 t.Errorf( 85 "row %d, column %d: received %s, expected %s", 86 i, j, val.String(colTypes[j]), inRows[i][j].String(colTypes[j]), 87 ) 88 } 89 } 90 } 91 }) 92 } 93 } 94 } 95 } 96 97 func BenchmarkValuesProcessor(b *testing.B) { 98 const numCols = 2 99 100 ctx := context.Background() 101 st := cluster.MakeTestingClusterSettings() 102 evalCtx := tree.MakeTestingEvalContext(st) 103 defer evalCtx.Stop(ctx) 104 105 flowCtx := execinfra.FlowCtx{ 106 Cfg: &execinfra.ServerConfig{Settings: st}, 107 EvalCtx: &evalCtx, 108 } 109 post := execinfrapb.PostProcessSpec{} 110 output := rowDisposer{} 111 for _, numRows := range []int{1 << 4, 1 << 8, 1 << 12, 1 << 16} { 112 for _, rowsPerChunk := range []int{1, 4, 16} { 113 b.Run(fmt.Sprintf("rows=%d,chunkSize=%d", numRows, rowsPerChunk), func(b *testing.B) { 114 rows := sqlbase.MakeIntRows(numRows, numCols) 115 spec, err := execinfra.GenerateValuesSpec(sqlbase.TwoIntCols, rows, rowsPerChunk) 116 if err != nil { 117 b.Fatal(err) 118 } 119 120 b.SetBytes(int64(8 * numRows * numCols)) 121 b.ResetTimer() 122 for i := 0; i < b.N; i++ { 123 v, err := newValuesProcessor(&flowCtx, 0 /* processorID */, &spec, &post, &output) 124 if err != nil { 125 b.Fatal(err) 126 } 127 v.Run(context.Background()) 128 } 129 }) 130 } 131 } 132 }