github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/opt/ordering/ordering_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 ordering
    12  
    13  import (
    14  	"fmt"
    15  	"testing"
    16  
    17  	"github.com/cockroachdb/cockroach/pkg/sql/opt"
    18  	"github.com/cockroachdb/cockroach/pkg/sql/opt/props"
    19  	"github.com/cockroachdb/cockroach/pkg/sql/opt/props/physical"
    20  )
    21  
    22  func TestTrimProvided(t *testing.T) {
    23  	emptyFD, equivFD, constFD := testFDs()
    24  	testCases := []struct {
    25  		req, prov string
    26  		fds       props.FuncDepSet
    27  		exp       string
    28  	}{
    29  		{ // case 1
    30  			req:  "+1 opt(2)",
    31  			prov: "+1,+2,+3",
    32  			fds:  emptyFD,
    33  			exp:  "+1",
    34  		},
    35  		{ // case 2
    36  			req:  "+1,+3 opt(2)",
    37  			prov: "+1,+2,+3",
    38  			fds:  emptyFD,
    39  			exp:  "+1,+2,+3",
    40  		},
    41  		{ // case 3
    42  			req:  "+4,-5 opt(1,2,3)",
    43  			prov: "-2,+4,-5,+7",
    44  			fds:  constFD,
    45  			exp:  "-2,+4,-5",
    46  		},
    47  		{ // case 4
    48  			req:  "+(1|2),-(3|4) opt(5)",
    49  			prov: "+2,-5,-3,+4",
    50  			fds:  equivFD,
    51  			exp:  "+2,-5,-3",
    52  		},
    53  	}
    54  	for tcIdx, tc := range testCases {
    55  		t.Run(fmt.Sprintf("case%d", tcIdx+1), func(t *testing.T) {
    56  			req := physical.ParseOrderingChoice(tc.req)
    57  			prov := physical.ParseOrdering(tc.prov)
    58  			res := trimProvided(prov, &req, &tc.fds).String()
    59  			if res != tc.exp {
    60  				t.Errorf("expected %s, got %s", tc.exp, res)
    61  			}
    62  		})
    63  	}
    64  }
    65  
    66  func TestRemapProvided(t *testing.T) {
    67  	emptyFD, equivFD, constFD := testFDs()
    68  	c := func(cols ...opt.ColumnID) opt.ColSet {
    69  		return opt.MakeColSet(cols...)
    70  	}
    71  	testCases := []struct {
    72  		prov string
    73  		fds  props.FuncDepSet
    74  		cols opt.ColSet
    75  		exp  string
    76  	}{
    77  		{ // case 1
    78  			prov: "+1,+2,+3",
    79  			fds:  emptyFD,
    80  			cols: c(1, 2, 3),
    81  			exp:  "+1,+2,+3",
    82  		},
    83  		{ // case 2
    84  			prov: "-1,+2,+3",
    85  			fds:  equivFD,
    86  			cols: c(1, 2, 3),
    87  			exp:  "-1,+3",
    88  		},
    89  		{ // case 3
    90  			prov: "+1,-2,+3",
    91  			fds:  equivFD,
    92  			cols: c(1, 3),
    93  			exp:  "+1,+3",
    94  		},
    95  		{ // case 4
    96  			prov: "-1,+2,+3",
    97  			fds:  equivFD,
    98  			cols: c(2, 4),
    99  			exp:  "-2,+4",
   100  		},
   101  		{ // case 5
   102  			prov: "+4,-1,-5,+2",
   103  			fds:  constFD,
   104  			cols: c(1, 2, 3, 4, 5),
   105  			exp:  "+4,-5",
   106  		},
   107  	}
   108  	for tcIdx, tc := range testCases {
   109  		t.Run(fmt.Sprintf("case%d", tcIdx+1), func(t *testing.T) {
   110  			prov := physical.ParseOrdering(tc.prov)
   111  			res := remapProvided(prov, &tc.fds, tc.cols).String()
   112  			if res != tc.exp {
   113  				t.Errorf("expected %s, got %s", tc.exp, res)
   114  			}
   115  		})
   116  	}
   117  }
   118  
   119  // testFDs returns FDs that can be used for testing:
   120  //   - emptyFD
   121  //   - equivFD: (1)==(2), (2)==(1), (3)==(4), (4)==(3)
   122  //   - constFD: ()-->(1,2)
   123  func testFDs() (emptyFD, equivFD, constFD props.FuncDepSet) {
   124  	equivFD.AddEquivalency(1, 2)
   125  	equivFD.AddEquivalency(3, 4)
   126  
   127  	constFD.AddConstants(opt.MakeColSet(1, 2))
   128  
   129  	return emptyFD, equivFD, constFD
   130  }