github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/colexec/case_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  	"testing"
    16  
    17  	"github.com/cockroachdb/cockroach/pkg/settings/cluster"
    18  	"github.com/cockroachdb/cockroach/pkg/sql/colexecbase"
    19  	"github.com/cockroachdb/cockroach/pkg/sql/execinfra"
    20  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    21  	"github.com/cockroachdb/cockroach/pkg/sql/types"
    22  	"github.com/cockroachdb/cockroach/pkg/util/leaktest"
    23  )
    24  
    25  func TestCaseOp(t *testing.T) {
    26  	defer leaktest.AfterTest(t)()
    27  	ctx := context.Background()
    28  	st := cluster.MakeTestingClusterSettings()
    29  	evalCtx := tree.MakeTestingEvalContext(st)
    30  	defer evalCtx.Stop(ctx)
    31  	flowCtx := &execinfra.FlowCtx{
    32  		EvalCtx: &evalCtx,
    33  		Cfg: &execinfra.ServerConfig{
    34  			Settings: st,
    35  		},
    36  	}
    37  
    38  	for _, tc := range []struct {
    39  		tuples     tuples
    40  		renderExpr string
    41  		expected   tuples
    42  		inputTypes []*types.T
    43  	}{
    44  		{
    45  			// Basic test.
    46  			tuples:     tuples{{1}, {2}, {nil}, {3}},
    47  			renderExpr: "CASE WHEN @1 = 2 THEN 1 ELSE 0 END",
    48  			expected:   tuples{{0}, {1}, {0}, {0}},
    49  			inputTypes: []*types.T{types.Int},
    50  		},
    51  		{
    52  			// Test "reordered when's."
    53  			tuples:     tuples{{1, 1}, {2, 0}, {nil, nil}, {3, 3}},
    54  			renderExpr: "CASE WHEN @1 + @2 > 3 THEN 0 WHEN @1 = 2 THEN 1 ELSE 2 END",
    55  			expected:   tuples{{2}, {1}, {2}, {0}},
    56  			inputTypes: []*types.T{types.Int, types.Int},
    57  		},
    58  		{
    59  			// Test the short-circuiting behavior.
    60  			tuples:     tuples{{1, 2}, {2, 0}, {nil, nil}, {3, 3}},
    61  			renderExpr: "CASE WHEN @1 = 2 THEN 0::FLOAT WHEN @1 / @2 = 1 THEN 1::FLOAT END",
    62  			expected:   tuples{{nil}, {0.0}, {nil}, {1.0}},
    63  			inputTypes: []*types.T{types.Int, types.Int},
    64  		},
    65  	} {
    66  		runTests(t, []tuples{tc.tuples}, tc.expected, orderedVerifier, func(inputs []colexecbase.Operator) (colexecbase.Operator, error) {
    67  			caseOp, err := createTestProjectingOperator(
    68  				ctx, flowCtx, inputs[0], tc.inputTypes, tc.renderExpr,
    69  				false, /* canFallbackToRowexec */
    70  			)
    71  			if err != nil {
    72  				return nil, err
    73  			}
    74  			// We will project out the input columns in order to have test
    75  			// cases be less verbose.
    76  			return NewSimpleProjectOp(caseOp, len(tc.inputTypes)+1, []uint32{uint32(len(tc.inputTypes))}), nil
    77  		})
    78  	}
    79  }