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  }