github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/opt/constraint/spans_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 // This file implements data structures used by index constraints generation. 12 13 package constraint 14 15 import ( 16 "testing" 17 18 "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" 19 "github.com/cockroachdb/cockroach/pkg/util/randutil" 20 ) 21 22 func TestSpans(t *testing.T) { 23 var s Spans 24 check := func(exp string) { 25 if actual := s.String(); actual != exp { 26 t.Errorf("expected %s, got %s", exp, actual) 27 } 28 } 29 add := func(x int) { 30 k := MakeKey(tree.NewDInt(tree.DInt(x))) 31 var span Span 32 span.Init(k, IncludeBoundary, k, IncludeBoundary) 33 s.Append(&span) 34 } 35 check("") 36 add(1) 37 check("[/1 - /1]") 38 add(2) 39 check("[/1 - /1] [/2 - /2]") 40 add(3) 41 check("[/1 - /1] [/2 - /2] [/3 - /3]") 42 43 // Verify that Alloc doesn't lose spans. 44 s.Alloc(10) 45 check("[/1 - /1] [/2 - /2] [/3 - /3]") 46 47 s.Truncate(2) 48 check("[/1 - /1] [/2 - /2]") 49 s.Truncate(1) 50 check("[/1 - /1]") 51 s.Truncate(0) 52 check("") 53 } 54 55 func TestSpansSortAndMerge(t *testing.T) { 56 keyCtx := testKeyContext(1) 57 evalCtx := keyCtx.EvalCtx 58 59 // To test SortAndMerge, we note that the result can also be obtained by 60 // creating a constraint per span and calculating the union. We generate 61 // random cases and cross-check. 62 for testIdx := 0; testIdx < 100; testIdx++ { 63 rng, _ := randutil.NewPseudoRand() 64 n := 1 + rng.Intn(10) 65 var spans Spans 66 for i := 0; i < n; i++ { 67 x, y := rng.Intn(20), rng.Intn(20) 68 if x > y { 69 x, y = y, x 70 } 71 xk, yk := EmptyKey, EmptyKey 72 if x > 0 { 73 xk = MakeKey(tree.NewDInt(tree.DInt(x))) 74 } 75 if y > 0 { 76 yk = MakeKey(tree.NewDInt(tree.DInt(y))) 77 } 78 79 xb, yb := IncludeBoundary, IncludeBoundary 80 if x != 0 && x != y && rng.Intn(2) == 0 { 81 xb = ExcludeBoundary 82 } 83 if y != 0 && x != y && rng.Intn(2) == 0 { 84 yb = ExcludeBoundary 85 } 86 var sp Span 87 if x != 0 || y != 0 { 88 sp.Init(xk, xb, yk, yb) 89 } 90 spans.Append(&sp) 91 } 92 origStr := spans.String() 93 94 // Calculate via constraints. 95 var c Constraint 96 c.InitSingleSpan(keyCtx, spans.Get(0)) 97 for i := 1; i < spans.Count(); i++ { 98 var d Constraint 99 d.InitSingleSpan(keyCtx, spans.Get(i)) 100 c.UnionWith(evalCtx, &d) 101 } 102 expected := c.Spans.String() 103 104 spans.SortAndMerge(keyCtx) 105 if actual := spans.String(); actual != expected { 106 t.Fatalf("%s : expected %s got %s", origStr, expected, actual) 107 } 108 } 109 }