github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/rowexec/indexjoiner_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  // This file doesn't live next to execinfra/indexjoiner.go in order to use
    12  // unexported method runProcessorsTest.
    13  // TODO(yuzefovich): move this test file next to indexjoiner.go.
    14  
    15  package rowexec
    16  
    17  import (
    18  	"context"
    19  	"testing"
    20  
    21  	"github.com/cockroachdb/cockroach/pkg/base"
    22  	"github.com/cockroachdb/cockroach/pkg/keys"
    23  	"github.com/cockroachdb/cockroach/pkg/kv"
    24  	"github.com/cockroachdb/cockroach/pkg/sql/execinfrapb"
    25  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    26  	"github.com/cockroachdb/cockroach/pkg/sql/sqlbase"
    27  	"github.com/cockroachdb/cockroach/pkg/sql/types"
    28  	"github.com/cockroachdb/cockroach/pkg/testutils/serverutils"
    29  	"github.com/cockroachdb/cockroach/pkg/testutils/sqlutils"
    30  	"github.com/cockroachdb/cockroach/pkg/util/leaktest"
    31  )
    32  
    33  func TestIndexJoiner(t *testing.T) {
    34  	defer leaktest.AfterTest(t)()
    35  
    36  	s, sqlDB, kvDB := serverutils.StartServer(t, base.TestServerArgs{})
    37  	defer s.Stopper().Stop(context.Background())
    38  
    39  	// Create a table where each row is:
    40  	//
    41  	//  |     a    |     b    |         sum         |         s           |
    42  	//  |-----------------------------------------------------------------|
    43  	//  | rowId/10 | rowId%10 | rowId/10 + rowId%10 | IntToEnglish(rowId) |
    44  
    45  	aFn := func(row int) tree.Datum {
    46  		return tree.NewDInt(tree.DInt(row / 10))
    47  	}
    48  	bFn := func(row int) tree.Datum {
    49  		return tree.NewDInt(tree.DInt(row % 10))
    50  	}
    51  	sumFn := func(row int) tree.Datum {
    52  		return tree.NewDInt(tree.DInt(row/10 + row%10))
    53  	}
    54  
    55  	sqlutils.CreateTable(t, sqlDB, "t",
    56  		"a INT, b INT, sum INT, s STRING, PRIMARY KEY (a,b), INDEX bs (b,s)",
    57  		99,
    58  		sqlutils.ToRowFn(aFn, bFn, sumFn, sqlutils.RowEnglishFn))
    59  
    60  	sqlutils.CreateTable(t, sqlDB, "t2",
    61  		"a INT, b INT, sum INT, s STRING, PRIMARY KEY (a,b), FAMILY f1 (a, b), FAMILY f2 (s), FAMILY f3 (sum), INDEX bs (b,s)",
    62  		99,
    63  		sqlutils.ToRowFn(aFn, bFn, sumFn, sqlutils.RowEnglishFn))
    64  
    65  	td := sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "test", "t")
    66  	tdf := sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "test", "t2")
    67  
    68  	v := [10]sqlbase.EncDatum{}
    69  	for i := range v {
    70  		v[i] = sqlbase.IntEncDatum(i)
    71  	}
    72  
    73  	testCases := []struct {
    74  		description string
    75  		desc        *sqlbase.TableDescriptor
    76  		post        execinfrapb.PostProcessSpec
    77  		input       sqlbase.EncDatumRows
    78  		outputTypes []*types.T
    79  		expected    sqlbase.EncDatumRows
    80  	}{
    81  		{
    82  			description: "Test selecting rows using the primary index",
    83  			desc:        td,
    84  			post: execinfrapb.PostProcessSpec{
    85  				Projection:    true,
    86  				OutputColumns: []uint32{0, 1, 2},
    87  			},
    88  			input: sqlbase.EncDatumRows{
    89  				{v[0], v[2]},
    90  				{v[0], v[5]},
    91  				{v[1], v[0]},
    92  				{v[1], v[5]},
    93  			},
    94  			outputTypes: sqlbase.ThreeIntCols,
    95  			expected: sqlbase.EncDatumRows{
    96  				{v[0], v[2], v[2]},
    97  				{v[0], v[5], v[5]},
    98  				{v[1], v[0], v[1]},
    99  				{v[1], v[5], v[6]},
   100  			},
   101  		},
   102  		{
   103  			description: "Test a filter in the post process spec and using a secondary index",
   104  			desc:        td,
   105  			post: execinfrapb.PostProcessSpec{
   106  				Filter:        execinfrapb.Expression{Expr: "@3 <= 5"}, // sum <= 5
   107  				Projection:    true,
   108  				OutputColumns: []uint32{3},
   109  			},
   110  			input: sqlbase.EncDatumRows{
   111  				{v[0], v[1]},
   112  				{v[2], v[5]},
   113  				{v[0], v[5]},
   114  				{v[2], v[1]},
   115  				{v[3], v[4]},
   116  				{v[1], v[3]},
   117  				{v[5], v[1]},
   118  				{v[5], v[0]},
   119  			},
   120  			outputTypes: []*types.T{types.String},
   121  			expected: sqlbase.EncDatumRows{
   122  				{sqlbase.StrEncDatum("one")},
   123  				{sqlbase.StrEncDatum("five")},
   124  				{sqlbase.StrEncDatum("two-one")},
   125  				{sqlbase.StrEncDatum("one-three")},
   126  				{sqlbase.StrEncDatum("five-zero")},
   127  			},
   128  		},
   129  		{
   130  			description: "Test selecting rows using the primary index with multiple family spans",
   131  			desc:        tdf,
   132  			post: execinfrapb.PostProcessSpec{
   133  				Projection:    true,
   134  				OutputColumns: []uint32{0, 1, 2},
   135  			},
   136  			input: sqlbase.EncDatumRows{
   137  				{v[0], v[2]},
   138  				{v[0], v[5]},
   139  				{v[1], v[0]},
   140  				{v[1], v[5]},
   141  			},
   142  			outputTypes: sqlbase.ThreeIntCols,
   143  			expected: sqlbase.EncDatumRows{
   144  				{v[0], v[2], v[2]},
   145  				{v[0], v[5], v[5]},
   146  				{v[1], v[0], v[1]},
   147  				{v[1], v[5], v[6]},
   148  			},
   149  		},
   150  	}
   151  
   152  	for _, c := range testCases {
   153  		t.Run(c.description, func(t *testing.T) {
   154  			spec := execinfrapb.JoinReaderSpec{
   155  				Table:    *c.desc,
   156  				IndexIdx: 0,
   157  			}
   158  			txn := kv.NewTxn(context.Background(), s.DB(), s.NodeID())
   159  			runProcessorTest(
   160  				t,
   161  				execinfrapb.ProcessorCoreUnion{JoinReader: &spec},
   162  				c.post,
   163  				sqlbase.TwoIntCols,
   164  				c.input,
   165  				c.outputTypes,
   166  				c.expected,
   167  				txn,
   168  			)
   169  		})
   170  	}
   171  }