github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/colexec/materializer_test.go (about)

     1  // Copyright 2018 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  	"context"
    15  	"testing"
    16  	"unsafe"
    17  
    18  	"github.com/cockroachdb/apd"
    19  	"github.com/cockroachdb/cockroach/pkg/settings/cluster"
    20  	"github.com/cockroachdb/cockroach/pkg/sql/execinfra"
    21  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    22  	"github.com/cockroachdb/cockroach/pkg/sql/sqlbase"
    23  	"github.com/cockroachdb/cockroach/pkg/sql/types"
    24  	"github.com/cockroachdb/cockroach/pkg/util/leaktest"
    25  	"github.com/cockroachdb/cockroach/pkg/util/timeutil/pgdate"
    26  )
    27  
    28  func TestColumnarizeMaterialize(t *testing.T) {
    29  	defer leaktest.AfterTest(t)()
    30  
    31  	// TODO(jordan,asubiotto): add randomness to this test as more types are supported.
    32  	typs := []*types.T{types.Int, types.Int}
    33  	nRows := 10000
    34  	nCols := 2
    35  	rows := sqlbase.MakeIntRows(nRows, nCols)
    36  	input := execinfra.NewRepeatableRowSource(typs, rows)
    37  
    38  	ctx := context.Background()
    39  	st := cluster.MakeTestingClusterSettings()
    40  	evalCtx := tree.MakeTestingEvalContext(st)
    41  	defer evalCtx.Stop(ctx)
    42  	flowCtx := &execinfra.FlowCtx{
    43  		Cfg:     &execinfra.ServerConfig{Settings: st},
    44  		EvalCtx: &evalCtx,
    45  	}
    46  	c, err := NewColumnarizer(ctx, testAllocator, flowCtx, 0, input)
    47  	if err != nil {
    48  		t.Fatal(err)
    49  	}
    50  
    51  	m, err := NewMaterializer(
    52  		flowCtx,
    53  		1, /* processorID */
    54  		c,
    55  		typs,
    56  		nil, /* output */
    57  		nil, /* metadataSourcesQueue */
    58  		nil, /* toClose */
    59  		nil, /* outputStatsToTrace */
    60  		nil, /* cancelFlow */
    61  	)
    62  	if err != nil {
    63  		t.Fatal(err)
    64  	}
    65  	m.Start(ctx)
    66  
    67  	for i := 0; i < nRows; i++ {
    68  		row, meta := m.Next()
    69  		if meta != nil {
    70  			t.Fatalf("unexpected meta %+v", meta)
    71  		}
    72  		if row == nil {
    73  			t.Fatal("unexpected nil row")
    74  		}
    75  		for j := 0; j < nCols; j++ {
    76  			if row[j].Datum.Compare(&evalCtx, rows[i][j].Datum) != 0 {
    77  				t.Fatal("unequal rows", row, rows[i])
    78  			}
    79  		}
    80  	}
    81  	row, meta := m.Next()
    82  	if meta != nil {
    83  		t.Fatalf("unexpected meta %+v", meta)
    84  	}
    85  	if row != nil {
    86  		t.Fatal("unexpected not nil row", row)
    87  	}
    88  }
    89  
    90  func TestMaterializeTypes(t *testing.T) {
    91  	defer leaktest.AfterTest(t)()
    92  
    93  	// TODO(andyk): Make sure to add more types here. Consider iterating over
    94  	// types.OidToTypes list and also using randomly generated EncDatums.
    95  	typs := []*types.T{
    96  		types.Bool,
    97  		types.Int,
    98  		types.Float,
    99  		types.Decimal,
   100  		types.Date,
   101  		types.String,
   102  		types.Bytes,
   103  		types.Name,
   104  		types.Oid,
   105  	}
   106  	inputRow := sqlbase.EncDatumRow{
   107  		sqlbase.EncDatum{Datum: tree.DBoolTrue},
   108  		sqlbase.EncDatum{Datum: tree.NewDInt(tree.DInt(31))},
   109  		sqlbase.EncDatum{Datum: tree.NewDFloat(37.41)},
   110  		sqlbase.EncDatum{Datum: &tree.DDecimal{Decimal: *apd.New(43, 47)}},
   111  		sqlbase.EncDatum{Datum: tree.NewDDate(pgdate.MakeCompatibleDateFromDisk(53))},
   112  		sqlbase.EncDatum{Datum: tree.NewDString("hello")},
   113  		sqlbase.EncDatum{Datum: tree.NewDBytes("ciao")},
   114  		sqlbase.EncDatum{Datum: tree.NewDName("aloha")},
   115  		sqlbase.EncDatum{Datum: tree.NewDOid(59)},
   116  	}
   117  	input := execinfra.NewRepeatableRowSource(typs, sqlbase.EncDatumRows{inputRow})
   118  
   119  	ctx := context.Background()
   120  	st := cluster.MakeTestingClusterSettings()
   121  	evalCtx := tree.MakeTestingEvalContext(st)
   122  	defer evalCtx.Stop(ctx)
   123  	flowCtx := &execinfra.FlowCtx{
   124  		Cfg:     &execinfra.ServerConfig{Settings: st},
   125  		EvalCtx: &evalCtx,
   126  	}
   127  	c, err := NewColumnarizer(ctx, testAllocator, flowCtx, 0, input)
   128  	if err != nil {
   129  		t.Fatal(err)
   130  	}
   131  
   132  	outputToInputColIdx := make([]int, len(typs))
   133  	for i := range outputToInputColIdx {
   134  		outputToInputColIdx[i] = i
   135  	}
   136  	m, err := NewMaterializer(
   137  		flowCtx,
   138  		1, /* processorID */
   139  		c,
   140  		typs,
   141  		nil, /* output */
   142  		nil, /* metadataSourcesQueue */
   143  		nil, /* toClose */
   144  		nil, /* outputStatsToTrace */
   145  		nil, /* cancelFlow */
   146  	)
   147  	if err != nil {
   148  		t.Fatal(err)
   149  	}
   150  	m.Start(ctx)
   151  
   152  	row, meta := m.Next()
   153  	if meta != nil {
   154  		t.Fatalf("unexpected meta %+v", meta)
   155  	}
   156  	if row == nil {
   157  		t.Fatal("unexpected nil row")
   158  	}
   159  	for i := range inputRow {
   160  		inDatum := inputRow[i].Datum
   161  		outDatum := row[i].Datum
   162  		if inDatum.Compare(&evalCtx, outDatum) != 0 {
   163  			t.Fatal("unequal datums", inDatum, outDatum)
   164  		}
   165  	}
   166  }
   167  
   168  func BenchmarkColumnarizeMaterialize(b *testing.B) {
   169  	types := []*types.T{types.Int, types.Int}
   170  	nRows := 10000
   171  	nCols := 2
   172  	rows := sqlbase.MakeIntRows(nRows, nCols)
   173  	input := execinfra.NewRepeatableRowSource(types, rows)
   174  
   175  	ctx := context.Background()
   176  	st := cluster.MakeTestingClusterSettings()
   177  	evalCtx := tree.MakeTestingEvalContext(st)
   178  	defer evalCtx.Stop(ctx)
   179  	flowCtx := &execinfra.FlowCtx{
   180  		Cfg:     &execinfra.ServerConfig{Settings: st},
   181  		EvalCtx: &evalCtx,
   182  	}
   183  	c, err := NewColumnarizer(ctx, testAllocator, flowCtx, 0, input)
   184  	if err != nil {
   185  		b.Fatal(err)
   186  	}
   187  
   188  	b.SetBytes(int64(nRows * nCols * int(unsafe.Sizeof(int64(0)))))
   189  	for i := 0; i < b.N; i++ {
   190  		m, err := NewMaterializer(
   191  			flowCtx,
   192  			1, /* processorID */
   193  			c,
   194  			types,
   195  			nil, /* output */
   196  			nil, /* metadataSourcesQueue */
   197  			nil, /* toClose */
   198  			nil, /* outputStatsToTrace */
   199  			nil, /* cancelFlow */
   200  		)
   201  		if err != nil {
   202  			b.Fatal(err)
   203  		}
   204  		m.Start(ctx)
   205  
   206  		foundRows := 0
   207  		for {
   208  			row, meta := m.Next()
   209  			if meta != nil {
   210  				b.Fatalf("unexpected metadata %v", meta)
   211  			}
   212  			if row == nil {
   213  				break
   214  			}
   215  			foundRows++
   216  		}
   217  		if foundRows != nRows {
   218  			b.Fatalf("expected %d rows, found %d", nRows, foundRows)
   219  		}
   220  		input.Reset()
   221  	}
   222  }