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 }