github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/schema.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package memex 15 16 import ( 17 "strings" 18 ) 19 20 // KeyInfo stores the defCausumns of one unique key or primary key. 21 type KeyInfo []*DeferredCauset 22 23 // Clone copies the entire UniqueKey. 24 func (ki KeyInfo) Clone() KeyInfo { 25 result := make([]*DeferredCauset, 0, len(ki)) 26 for _, defCaus := range ki { 27 result = append(result, defCaus.Clone().(*DeferredCauset)) 28 } 29 return result 30 } 31 32 // Schema stands for the event schemaReplicant and unique key information get from input. 33 type Schema struct { 34 DeferredCausets []*DeferredCauset 35 Keys []KeyInfo 36 } 37 38 // String implements fmt.Stringer interface. 39 func (s *Schema) String() string { 40 defCausStrs := make([]string, 0, len(s.DeferredCausets)) 41 for _, defCaus := range s.DeferredCausets { 42 defCausStrs = append(defCausStrs, defCaus.String()) 43 } 44 ukStrs := make([]string, 0, len(s.Keys)) 45 for _, key := range s.Keys { 46 ukDefCausStrs := make([]string, 0, len(key)) 47 for _, defCaus := range key { 48 ukDefCausStrs = append(ukDefCausStrs, defCaus.String()) 49 } 50 ukStrs = append(ukStrs, "["+strings.Join(ukDefCausStrs, ",")+"]") 51 } 52 return "DeferredCauset: [" + strings.Join(defCausStrs, ",") + "] Unique key: [" + strings.Join(ukStrs, ",") + "]" 53 } 54 55 // Clone copies the total schemaReplicant. 56 func (s *Schema) Clone() *Schema { 57 defcaus := make([]*DeferredCauset, 0, s.Len()) 58 keys := make([]KeyInfo, 0, len(s.Keys)) 59 for _, defCaus := range s.DeferredCausets { 60 defcaus = append(defcaus, defCaus.Clone().(*DeferredCauset)) 61 } 62 for _, key := range s.Keys { 63 keys = append(keys, key.Clone()) 64 } 65 schemaReplicant := NewSchema(defcaus...) 66 schemaReplicant.SetUniqueKeys(keys) 67 return schemaReplicant 68 } 69 70 // ExprFromSchema checks if all defCausumns of this memex are from the same schemaReplicant. 71 func ExprFromSchema(expr Expression, schemaReplicant *Schema) bool { 72 switch v := expr.(type) { 73 case *DeferredCauset: 74 return schemaReplicant.Contains(v) 75 case *ScalarFunction: 76 for _, arg := range v.GetArgs() { 77 if !ExprFromSchema(arg, schemaReplicant) { 78 return false 79 } 80 } 81 return true 82 case *CorrelatedDeferredCauset, *Constant: 83 return true 84 } 85 return false 86 } 87 88 // RetrieveDeferredCauset retrieves defCausumn in memex from the defCausumns in schemaReplicant. 89 func (s *Schema) RetrieveDeferredCauset(defCaus *DeferredCauset) *DeferredCauset { 90 index := s.DeferredCausetIndex(defCaus) 91 if index != -1 { 92 return s.DeferredCausets[index] 93 } 94 return nil 95 } 96 97 // IsUniqueKey checks if this defCausumn is a unique key. 98 func (s *Schema) IsUniqueKey(defCaus *DeferredCauset) bool { 99 for _, key := range s.Keys { 100 if len(key) == 1 && key[0].Equal(nil, defCaus) { 101 return true 102 } 103 } 104 return false 105 } 106 107 // DeferredCausetIndex finds the index for a defCausumn. 108 func (s *Schema) DeferredCausetIndex(defCaus *DeferredCauset) int { 109 for i, c := range s.DeferredCausets { 110 if c.UniqueID == defCaus.UniqueID { 111 return i 112 } 113 } 114 return -1 115 } 116 117 // Contains checks if the schemaReplicant contains the defCausumn. 118 func (s *Schema) Contains(defCaus *DeferredCauset) bool { 119 return s.DeferredCausetIndex(defCaus) != -1 120 } 121 122 // Len returns the number of defCausumns in schemaReplicant. 123 func (s *Schema) Len() int { 124 return len(s.DeferredCausets) 125 } 126 127 // Append append new defCausumn to the defCausumns stored in schemaReplicant. 128 func (s *Schema) Append(defCaus ...*DeferredCauset) { 129 s.DeferredCausets = append(s.DeferredCausets, defCaus...) 130 } 131 132 // SetUniqueKeys will set the value of Schema.Keys. 133 func (s *Schema) SetUniqueKeys(keys []KeyInfo) { 134 s.Keys = keys 135 } 136 137 // DeferredCausetsIndices will return a slice which contains the position of each defCausumn in schemaReplicant. 138 // If there is one defCausumn that doesn't match, nil will be returned. 139 func (s *Schema) DeferredCausetsIndices(defcaus []*DeferredCauset) (ret []int) { 140 ret = make([]int, 0, len(defcaus)) 141 for _, defCaus := range defcaus { 142 pos := s.DeferredCausetIndex(defCaus) 143 if pos != -1 { 144 ret = append(ret, pos) 145 } else { 146 return nil 147 } 148 } 149 return 150 } 151 152 // DeferredCausetsByIndices returns defCausumns by multiple offsets. 153 // Callers should guarantee that all the offsets provided should be valid, which means offset should: 154 // 1. not smaller than 0, and 155 // 2. not exceed len(s.DeferredCausets) 156 func (s *Schema) DeferredCausetsByIndices(offsets []int) []*DeferredCauset { 157 defcaus := make([]*DeferredCauset, 0, len(offsets)) 158 for _, offset := range offsets { 159 defcaus = append(defcaus, s.DeferredCausets[offset]) 160 } 161 return defcaus 162 } 163 164 // ExtractDefCausGroups checks if defCausumn groups are from current schemaReplicant, and returns 165 // offsets of those satisfied defCausumn groups. 166 func (s *Schema) ExtractDefCausGroups(defCausGroups [][]*DeferredCauset) ([][]int, []int) { 167 if len(defCausGroups) == 0 { 168 return nil, nil 169 } 170 extracted := make([][]int, 0, len(defCausGroups)) 171 offsets := make([]int, 0, len(defCausGroups)) 172 for i, g := range defCausGroups { 173 if j := s.DeferredCausetsIndices(g); j != nil { 174 extracted = append(extracted, j) 175 offsets = append(offsets, i) 176 } 177 } 178 return extracted, offsets 179 } 180 181 // MergeSchema will merge two schemaReplicant into one schemaReplicant. We shouldn't need to consider unique keys. 182 // That will be processed in build_key_info.go. 183 func MergeSchema(lSchema, rSchema *Schema) *Schema { 184 if lSchema == nil && rSchema == nil { 185 return nil 186 } 187 if lSchema == nil { 188 return rSchema.Clone() 189 } 190 if rSchema == nil { 191 return lSchema.Clone() 192 } 193 tmpL := lSchema.Clone() 194 tmpR := rSchema.Clone() 195 ret := NewSchema(append(tmpL.DeferredCausets, tmpR.DeferredCausets...)...) 196 return ret 197 } 198 199 // GetUsedList shows whether each defCausumn in schemaReplicant is contained in usedDefCauss. 200 func GetUsedList(usedDefCauss []*DeferredCauset, schemaReplicant *Schema) []bool { 201 tmpSchema := NewSchema(usedDefCauss...) 202 used := make([]bool, schemaReplicant.Len()) 203 for i, defCaus := range schemaReplicant.DeferredCausets { 204 used[i] = tmpSchema.Contains(defCaus) 205 } 206 return used 207 } 208 209 // NewSchema returns a schemaReplicant made by its parameter. 210 func NewSchema(defcaus ...*DeferredCauset) *Schema { 211 return &Schema{DeferredCausets: defcaus} 212 }