github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/colexec/is_null_ops_test.go (about) 1 // Copyright 2019 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 "testing" 17 18 "github.com/cockroachdb/cockroach/pkg/settings/cluster" 19 "github.com/cockroachdb/cockroach/pkg/sql/colexecbase" 20 "github.com/cockroachdb/cockroach/pkg/sql/execinfra" 21 "github.com/cockroachdb/cockroach/pkg/sql/execinfrapb" 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 ) 26 27 func TestIsNullProjOp(t *testing.T) { 28 defer leaktest.AfterTest(t)() 29 ctx := context.Background() 30 st := cluster.MakeTestingClusterSettings() 31 evalCtx := tree.MakeTestingEvalContext(st) 32 defer evalCtx.Stop(ctx) 33 flowCtx := &execinfra.FlowCtx{ 34 EvalCtx: &evalCtx, 35 Cfg: &execinfra.ServerConfig{ 36 Settings: st, 37 }, 38 } 39 40 testCases := []struct { 41 desc string 42 inputTuples tuples 43 outputTuples tuples 44 projExpr string 45 }{ 46 { 47 desc: "SELECT c, c IS NULL FROM t -- both", 48 inputTuples: tuples{{0}, {nil}, {1}, {2}, {nil}}, 49 outputTuples: tuples{{0, false}, {nil, true}, {1, false}, {2, false}, {nil, true}}, 50 projExpr: "IS NULL", 51 }, 52 { 53 desc: "SELECT c, c IS NULL FROM t -- no NULLs", 54 inputTuples: tuples{{0}, {1}, {2}}, 55 outputTuples: tuples{{0, false}, {1, false}, {2, false}}, 56 projExpr: "IS NULL", 57 }, 58 { 59 desc: "SELECT c, c IS NULL FROM t -- only NULLs", 60 inputTuples: tuples{{nil}, {nil}}, 61 outputTuples: tuples{{nil, true}, {nil, true}}, 62 projExpr: "IS NULL", 63 }, 64 { 65 desc: "SELECT c, c IS NOT NULL FROM t -- both", 66 inputTuples: tuples{{0}, {nil}, {1}, {2}, {nil}}, 67 outputTuples: tuples{{0, true}, {nil, false}, {1, true}, {2, true}, {nil, false}}, 68 projExpr: "IS NOT NULL", 69 }, 70 { 71 desc: "SELECT c, c IS NOT NULL FROM t -- no NULLs", 72 inputTuples: tuples{{0}, {1}, {2}}, 73 outputTuples: tuples{{0, true}, {1, true}, {2, true}}, 74 projExpr: "IS NOT NULL", 75 }, 76 { 77 desc: "SELECT c, c IS NOT NULL FROM t -- only NULLs", 78 inputTuples: tuples{{nil}, {nil}}, 79 outputTuples: tuples{{nil, false}, {nil, false}}, 80 projExpr: "IS NOT NULL", 81 }, 82 { 83 desc: "SELECT c, c IS NOT DISTINCT FROM NULL FROM t -- both", 84 inputTuples: tuples{{0}, {nil}, {1}, {2}, {nil}}, 85 outputTuples: tuples{{0, false}, {nil, true}, {1, false}, {2, false}, {nil, true}}, 86 projExpr: "IS NOT DISTINCT FROM NULL", 87 }, 88 { 89 desc: "SELECT c, c IS NOT DISTINCT FROM NULL FROM t -- no NULLs", 90 inputTuples: tuples{{0}, {1}, {2}}, 91 outputTuples: tuples{{0, false}, {1, false}, {2, false}}, 92 projExpr: "IS NOT DISTINCT FROM NULL", 93 }, 94 { 95 desc: "SELECT c, c IS NOT DISTINCT FROM NULL FROM t -- only NULLs", 96 inputTuples: tuples{{nil}, {nil}}, 97 outputTuples: tuples{{nil, true}, {nil, true}}, 98 projExpr: "IS NOT DISTINCT FROM NULL", 99 }, 100 { 101 desc: "SELECT c, c IS DISTINCT FROM NULL FROM t -- both", 102 inputTuples: tuples{{0}, {nil}, {1}, {2}, {nil}}, 103 outputTuples: tuples{{0, true}, {nil, false}, {1, true}, {2, true}, {nil, false}}, 104 projExpr: "IS DISTINCT FROM NULL", 105 }, 106 { 107 desc: "SELECT c, c IS DISTINCT FROM NULL FROM t -- no NULLs", 108 inputTuples: tuples{{0}, {1}, {2}}, 109 outputTuples: tuples{{0, true}, {1, true}, {2, true}}, 110 projExpr: "IS DISTINCT FROM NULL", 111 }, 112 { 113 desc: "SELECT c, c IS DISTINCT FROM NULL FROM t -- only NULLs", 114 inputTuples: tuples{{nil}, {nil}}, 115 outputTuples: tuples{{nil, false}, {nil, false}}, 116 projExpr: "IS DISTINCT FROM NULL", 117 }, 118 } 119 120 for _, c := range testCases { 121 t.Run(c.desc, func(t *testing.T) { 122 opConstructor := func(input []colexecbase.Operator) (colexecbase.Operator, error) { 123 return createTestProjectingOperator( 124 ctx, flowCtx, input[0], []*types.T{types.Int}, 125 fmt.Sprintf("@1 %s", c.projExpr), false, /* canFallbackToRowexec */ 126 ) 127 } 128 runTests(t, []tuples{c.inputTuples}, c.outputTuples, orderedVerifier, opConstructor) 129 }) 130 } 131 } 132 133 func TestIsNullSelOp(t *testing.T) { 134 defer leaktest.AfterTest(t)() 135 ctx := context.Background() 136 st := cluster.MakeTestingClusterSettings() 137 evalCtx := tree.MakeTestingEvalContext(st) 138 defer evalCtx.Stop(ctx) 139 flowCtx := &execinfra.FlowCtx{ 140 EvalCtx: &evalCtx, 141 Cfg: &execinfra.ServerConfig{ 142 Settings: st, 143 }, 144 } 145 146 testCases := []struct { 147 desc string 148 inputTuples tuples 149 outputTuples tuples 150 selExpr string 151 }{ 152 { 153 desc: "SELECT c FROM t WHERE c IS NULL -- both", 154 inputTuples: tuples{{0}, {nil}, {1}, {2}, {nil}}, 155 outputTuples: tuples{{nil}, {nil}}, 156 selExpr: "IS NULL", 157 }, 158 { 159 desc: "SELECT c FROM t WHERE c IS NULL -- no NULLs", 160 inputTuples: tuples{{0}, {1}, {2}}, 161 outputTuples: tuples{}, 162 selExpr: "IS NULL", 163 }, 164 { 165 desc: "SELECT c FROM t WHERE c IS NULL -- only NULLs", 166 inputTuples: tuples{{nil}, {nil}}, 167 outputTuples: tuples{{nil}, {nil}}, 168 selExpr: "IS NULL", 169 }, 170 { 171 desc: "SELECT c FROM t WHERE c IS NOT NULL -- both", 172 inputTuples: tuples{{0}, {nil}, {1}, {2}, {nil}}, 173 outputTuples: tuples{{0}, {1}, {2}}, 174 selExpr: "IS NOT NULL", 175 }, 176 { 177 desc: "SELECT c FROM t WHERE c IS NOT NULL -- no NULLs", 178 inputTuples: tuples{{0}, {1}, {2}}, 179 outputTuples: tuples{{0}, {1}, {2}}, 180 selExpr: "IS NOT NULL", 181 }, 182 { 183 desc: "SELECT c FROM t WHERE c IS NOT NULL -- only NULLs", 184 inputTuples: tuples{{nil}, {nil}}, 185 outputTuples: tuples{}, 186 selExpr: "IS NOT NULL", 187 }, 188 { 189 desc: "SELECT c FROM t WHERE c IS NOT DISTINCT FROM NULL -- both", 190 inputTuples: tuples{{0}, {nil}, {1}, {2}, {nil}}, 191 outputTuples: tuples{{nil}, {nil}}, 192 selExpr: "IS NOT DISTINCT FROM NULL", 193 }, 194 { 195 desc: "SELECT c FROM t WHERE c IS NOT DISTINCT FROM NULL -- no NULLs", 196 inputTuples: tuples{{0}, {1}, {2}}, 197 outputTuples: tuples{}, 198 selExpr: "IS NOT DISTINCT FROM NULL", 199 }, 200 { 201 desc: "SELECT c FROM t WHERE c IS NOT DISTINCT FROM NULL -- only NULLs", 202 inputTuples: tuples{{nil}, {nil}}, 203 outputTuples: tuples{{nil}, {nil}}, 204 selExpr: "IS NOT DISTINCT FROM NULL", 205 }, 206 { 207 desc: "SELECT c FROM t WHERE c IS DISTINCT FROM NULL -- both", 208 inputTuples: tuples{{0}, {nil}, {1}, {2}, {nil}}, 209 outputTuples: tuples{{0}, {1}, {2}}, 210 selExpr: "IS DISTINCT FROM NULL", 211 }, 212 { 213 desc: "SELECT c FROM t WHERE c IS DISTINCT FROM NULL -- no NULLs", 214 inputTuples: tuples{{0}, {1}, {2}}, 215 outputTuples: tuples{{0}, {1}, {2}}, 216 selExpr: "IS DISTINCT FROM NULL", 217 }, 218 { 219 desc: "SELECT c FROM t WHERE c IS DISTINCT FROM NULL -- only NULLs", 220 inputTuples: tuples{{nil}, {nil}}, 221 outputTuples: tuples{}, 222 selExpr: "IS DISTINCT FROM NULL", 223 }, 224 } 225 226 for _, c := range testCases { 227 t.Run(c.desc, func(t *testing.T) { 228 opConstructor := func(input []colexecbase.Operator) (colexecbase.Operator, error) { 229 spec := &execinfrapb.ProcessorSpec{ 230 Input: []execinfrapb.InputSyncSpec{{ColumnTypes: []*types.T{types.Int}}}, 231 Core: execinfrapb.ProcessorCoreUnion{ 232 Noop: &execinfrapb.NoopCoreSpec{}, 233 }, 234 Post: execinfrapb.PostProcessSpec{ 235 Filter: execinfrapb.Expression{Expr: fmt.Sprintf("@1 %s", c.selExpr)}, 236 }, 237 } 238 args := NewColOperatorArgs{ 239 Spec: spec, 240 Inputs: input, 241 StreamingMemAccount: testMemAcc, 242 } 243 args.TestingKnobs.UseStreamingMemAccountForBuffering = true 244 result, err := NewColOperator(ctx, flowCtx, args) 245 if err != nil { 246 return nil, err 247 } 248 return result.Op, nil 249 } 250 runTests(t, []tuples{c.inputTuples}, c.outputTuples, orderedVerifier, opConstructor) 251 }) 252 } 253 }