vitess.io/vitess@v0.16.2/go/vt/vtgate/semantics/dependencies.go (about) 1 /* 2 Copyright 2021 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package semantics 18 19 import ( 20 querypb "vitess.io/vitess/go/vt/proto/query" 21 vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" 22 "vitess.io/vitess/go/vt/vterrors" 23 ) 24 25 type ( 26 // these types are used to go over dependencies provided by multiple 27 // tables and figure out bindings and/or errors by merging dependencies together 28 dependencies interface { 29 empty() bool 30 get() (dependency, error) 31 merge(other dependencies, allowMulti bool) dependencies 32 } 33 dependency struct { 34 direct TableSet 35 recursive TableSet 36 typ *Type 37 } 38 nothing struct{} 39 certain struct { 40 dependency 41 err error 42 } 43 uncertain struct { 44 dependency 45 fail bool 46 } 47 ) 48 49 var ambigousErr = vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "ambiguous") 50 51 func createCertain(direct TableSet, recursive TableSet, qt *Type) *certain { 52 c := &certain{ 53 dependency: dependency{ 54 direct: direct, 55 recursive: recursive, 56 }, 57 } 58 if qt != nil && qt.Type != querypb.Type_NULL_TYPE { 59 c.typ = qt 60 } 61 return c 62 } 63 64 func createUncertain(direct TableSet, recursive TableSet) *uncertain { 65 return &uncertain{ 66 dependency: dependency{ 67 direct: direct, 68 recursive: recursive, 69 }, 70 } 71 } 72 73 var _ dependencies = (*nothing)(nil) 74 var _ dependencies = (*certain)(nil) 75 var _ dependencies = (*uncertain)(nil) 76 77 func (u *uncertain) empty() bool { 78 return false 79 } 80 81 func (u *uncertain) get() (dependency, error) { 82 if u.fail { 83 return dependency{}, ambigousErr 84 } 85 return u.dependency, nil 86 } 87 88 func (u *uncertain) merge(d dependencies, _ bool) dependencies { 89 switch d := d.(type) { 90 case *uncertain: 91 if d.recursive != u.recursive { 92 u.fail = true 93 } 94 return u 95 case *certain: 96 return d 97 default: 98 return u 99 } 100 } 101 102 func (c *certain) empty() bool { 103 return false 104 } 105 106 func (c *certain) get() (dependency, error) { 107 return c.dependency, c.err 108 } 109 110 func (c *certain) merge(d dependencies, allowMulti bool) dependencies { 111 switch d := d.(type) { 112 case *certain: 113 if d.recursive == c.recursive { 114 return c 115 } 116 c.direct = c.direct.Merge(d.direct) 117 c.recursive = c.recursive.Merge(d.recursive) 118 if !allowMulti { 119 c.err = ambigousErr 120 } 121 122 return c 123 } 124 125 return c 126 } 127 128 func (n *nothing) empty() bool { 129 return true 130 } 131 132 func (n *nothing) get() (dependency, error) { 133 return dependency{}, nil 134 } 135 136 func (n *nothing) merge(d dependencies, _ bool) dependencies { 137 return d 138 }