github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/colexec/selection_ops_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 "fmt" 16 "math/rand" 17 "reflect" 18 "testing" 19 20 "github.com/cockroachdb/cockroach/pkg/col/coldata" 21 "github.com/cockroachdb/cockroach/pkg/sql/colexecbase" 22 "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" 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 const ( 29 selectivity = .5 30 nullProbability = .1 31 ) 32 33 func TestSelLTInt64Int64ConstOp(t *testing.T) { 34 defer leaktest.AfterTest(t)() 35 tups := tuples{{0}, {1}, {2}, {nil}} 36 runTests(t, []tuples{tups}, tuples{{0}, {1}}, orderedVerifier, func(input []colexecbase.Operator) (colexecbase.Operator, error) { 37 return &selLTInt64Int64ConstOp{ 38 selConstOpBase: selConstOpBase{ 39 OneInputNode: NewOneInputNode(input[0]), 40 colIdx: 0, 41 }, 42 constArg: 2, 43 }, nil 44 }) 45 } 46 47 func TestSelLTInt64Int64(t *testing.T) { 48 defer leaktest.AfterTest(t)() 49 tups := tuples{ 50 {0, 0}, 51 {0, 1}, 52 {1, 0}, 53 {1, 1}, 54 {nil, 1}, 55 {-1, nil}, 56 {nil, nil}, 57 } 58 runTests(t, []tuples{tups}, tuples{{0, 1}}, orderedVerifier, func(input []colexecbase.Operator) (colexecbase.Operator, error) { 59 return &selLTInt64Int64Op{ 60 selOpBase: selOpBase{ 61 OneInputNode: NewOneInputNode(input[0]), 62 col1Idx: 0, 63 col2Idx: 1, 64 }, 65 }, nil 66 }) 67 } 68 69 func TestGetSelectionConstOperator(t *testing.T) { 70 defer leaktest.AfterTest(t)() 71 cmpOp := tree.LT 72 var input colexecbase.Operator 73 colIdx := 3 74 constVal := int64(31) 75 constArg := tree.NewDDate(pgdate.MakeCompatibleDateFromDisk(constVal)) 76 op, err := GetSelectionConstOperator(types.Date, types.Date, cmpOp, input, colIdx, constArg, overloadHelper{}) 77 if err != nil { 78 t.Error(err) 79 } 80 expected := &selLTInt64Int64ConstOp{ 81 selConstOpBase: selConstOpBase{ 82 OneInputNode: NewOneInputNode(input), 83 colIdx: colIdx, 84 }, 85 constArg: constVal, 86 } 87 if !reflect.DeepEqual(op, expected) { 88 t.Errorf("got %+v, expected %+v", op, expected) 89 } 90 } 91 92 func TestGetSelectionConstMixedTypeOperator(t *testing.T) { 93 defer leaktest.AfterTest(t)() 94 cmpOp := tree.LT 95 var input colexecbase.Operator 96 colIdx := 3 97 constVal := int16(31) 98 constArg := tree.NewDInt(tree.DInt(constVal)) 99 op, err := GetSelectionConstOperator(types.Int, types.Int2, cmpOp, input, colIdx, constArg, overloadHelper{}) 100 if err != nil { 101 t.Error(err) 102 } 103 expected := &selLTInt64Int16ConstOp{ 104 selConstOpBase: selConstOpBase{ 105 OneInputNode: NewOneInputNode(input), 106 colIdx: colIdx, 107 }, 108 constArg: constVal, 109 } 110 if !reflect.DeepEqual(op, expected) { 111 t.Errorf("got %+v, expected %+v", op, expected) 112 } 113 } 114 115 func TestGetSelectionOperator(t *testing.T) { 116 defer leaktest.AfterTest(t)() 117 ct := types.Int2 118 cmpOp := tree.GE 119 var input colexecbase.Operator 120 col1Idx := 5 121 col2Idx := 7 122 op, err := GetSelectionOperator(ct, ct, cmpOp, input, col1Idx, col2Idx, overloadHelper{}) 123 if err != nil { 124 t.Error(err) 125 } 126 expected := &selGEInt16Int16Op{ 127 selOpBase: selOpBase{ 128 OneInputNode: NewOneInputNode(input), 129 col1Idx: col1Idx, 130 col2Idx: col2Idx, 131 }, 132 } 133 if !reflect.DeepEqual(op, expected) { 134 t.Errorf("got %+v, expected %+v", op, expected) 135 } 136 } 137 138 func benchmarkSelLTInt64Int64ConstOp(b *testing.B, useSelectionVector bool, hasNulls bool) { 139 ctx := context.Background() 140 141 typs := []*types.T{types.Int} 142 batch := testAllocator.NewMemBatch(typs) 143 col := batch.ColVec(0).Int64() 144 for i := 0; i < coldata.BatchSize(); i++ { 145 if float64(i) < float64(coldata.BatchSize())*selectivity { 146 col[i] = -1 147 } else { 148 col[i] = 1 149 } 150 } 151 if hasNulls { 152 for i := 0; i < coldata.BatchSize(); i++ { 153 if rand.Float64() < nullProbability { 154 batch.ColVec(0).Nulls().SetNull(i) 155 } 156 } 157 } 158 batch.SetLength(coldata.BatchSize()) 159 if useSelectionVector { 160 batch.SetSelection(true) 161 sel := batch.Selection() 162 for i := 0; i < coldata.BatchSize(); i++ { 163 sel[i] = i 164 } 165 } 166 source := colexecbase.NewRepeatableBatchSource(testAllocator, batch, typs) 167 source.Init() 168 169 plusOp := &selLTInt64Int64ConstOp{ 170 selConstOpBase: selConstOpBase{ 171 OneInputNode: NewOneInputNode(source), 172 colIdx: 0, 173 }, 174 constArg: 0, 175 } 176 plusOp.Init() 177 178 b.SetBytes(int64(8 * coldata.BatchSize())) 179 b.ResetTimer() 180 for i := 0; i < b.N; i++ { 181 plusOp.Next(ctx) 182 } 183 } 184 185 func BenchmarkSelLTInt64Int64ConstOp(b *testing.B) { 186 for _, useSel := range []bool{true, false} { 187 for _, hasNulls := range []bool{true, false} { 188 b.Run(fmt.Sprintf("useSel=%t,hasNulls=%t", useSel, hasNulls), func(b *testing.B) { 189 benchmarkSelLTInt64Int64ConstOp(b, useSel, hasNulls) 190 }) 191 } 192 } 193 } 194 195 func benchmarkSelLTInt64Int64Op(b *testing.B, useSelectionVector bool, hasNulls bool) { 196 ctx := context.Background() 197 198 typs := []*types.T{types.Int, types.Int} 199 batch := testAllocator.NewMemBatch(typs) 200 col1 := batch.ColVec(0).Int64() 201 col2 := batch.ColVec(1).Int64() 202 for i := 0; i < coldata.BatchSize(); i++ { 203 if float64(i) < float64(coldata.BatchSize())*selectivity { 204 col1[i], col2[i] = -1, 1 205 } else { 206 col1[i], col2[i] = 1, -1 207 } 208 } 209 if hasNulls { 210 for i := 0; i < coldata.BatchSize(); i++ { 211 if rand.Float64() < nullProbability { 212 batch.ColVec(0).Nulls().SetNull(i) 213 } 214 if rand.Float64() < nullProbability { 215 batch.ColVec(1).Nulls().SetNull(i) 216 } 217 } 218 } 219 batch.SetLength(coldata.BatchSize()) 220 if useSelectionVector { 221 batch.SetSelection(true) 222 sel := batch.Selection() 223 for i := 0; i < coldata.BatchSize(); i++ { 224 sel[i] = i 225 } 226 } 227 source := colexecbase.NewRepeatableBatchSource(testAllocator, batch, typs) 228 source.Init() 229 230 plusOp := &selLTInt64Int64Op{ 231 selOpBase: selOpBase{ 232 OneInputNode: NewOneInputNode(source), 233 col1Idx: 0, 234 col2Idx: 1, 235 }, 236 } 237 plusOp.Init() 238 239 b.SetBytes(int64(8 * coldata.BatchSize() * 2)) 240 b.ResetTimer() 241 for i := 0; i < b.N; i++ { 242 plusOp.Next(ctx) 243 } 244 } 245 246 func BenchmarkSelLTInt64Int64Op(b *testing.B) { 247 for _, useSel := range []bool{true, false} { 248 for _, hasNulls := range []bool{true, false} { 249 b.Run(fmt.Sprintf("useSel=%t,hasNulls=%t", useSel, hasNulls), func(b *testing.B) { 250 benchmarkSelLTInt64Int64Op(b, useSel, hasNulls) 251 }) 252 } 253 } 254 }