github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/interlock/aggfuncs/func_value.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 aggfuncs 15 16 import ( 17 "unsafe" 18 19 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 20 "github.com/whtcorpsinc/milevadb/memex" 21 "github.com/whtcorpsinc/milevadb/stochastikctx" 22 "github.com/whtcorpsinc/milevadb/types" 23 "github.com/whtcorpsinc/milevadb/types/json" 24 "github.com/whtcorpsinc/milevadb/soliton/chunk" 25 ) 26 27 const ( 28 // DefPartialResult4FirstValueSize is the size of partialResult4FirstValue 29 DefPartialResult4FirstValueSize = int64(unsafe.Sizeof(partialResult4FirstValue{})) 30 // DefPartialResult4LastValueSize is the size of partialResult4LastValue 31 DefPartialResult4LastValueSize = int64(unsafe.Sizeof(partialResult4LastValue{})) 32 // DefPartialResult4NthValueSize is the size of partialResult4NthValue 33 DefPartialResult4NthValueSize = int64(unsafe.Sizeof(partialResult4NthValue{})) 34 35 // DefValue4IntSize is the size of value4Int 36 DefValue4IntSize = int64(unsafe.Sizeof(value4Int{})) 37 // DefValue4Float32Size is the size of value4Float32 38 DefValue4Float32Size = int64(unsafe.Sizeof(value4Float32{})) 39 // DefValue4Float64Size is the size of value4Float64 40 DefValue4Float64Size = int64(unsafe.Sizeof(value4Float64{})) 41 // DefValue4DecimalSize is the size of value4Decimal 42 DefValue4DecimalSize = int64(unsafe.Sizeof(value4Decimal{})) 43 // DefValue4TimeSize is the size of value4Time 44 DefValue4TimeSize = int64(unsafe.Sizeof(value4Time{})) 45 // DefValue4DurationSize is the size of value4Duration 46 DefValue4DurationSize = int64(unsafe.Sizeof(value4Duration{})) 47 // DefValue4StringSize is the size of value4String 48 DefValue4StringSize = int64(unsafe.Sizeof(value4String{})) 49 // DefValue4JSONSize is the size of value4JSON 50 DefValue4JSONSize = int64(unsafe.Sizeof(value4JSON{})) 51 ) 52 53 // valueEvaluator is used to evaluate values for `first_value`, `last_value`, `nth_value`, 54 // `lead` and `lag`. 55 type valueEvaluator interface { 56 // evaluateEvent evaluates the memex using event and stores the result inside. 57 evaluateEvent(ctx stochastikctx.Context, expr memex.Expression, event chunk.Event) (memDelta int64, err error) 58 // appendResult appends the result to chunk. 59 appendResult(chk *chunk.Chunk, defCausIdx int) 60 } 61 62 type value4Int struct { 63 val int64 64 isNull bool 65 } 66 67 func (v *value4Int) evaluateEvent(ctx stochastikctx.Context, expr memex.Expression, event chunk.Event) (memDelta int64, err error) { 68 v.val, v.isNull, err = expr.EvalInt(ctx, event) 69 return 0, err 70 } 71 72 func (v *value4Int) appendResult(chk *chunk.Chunk, defCausIdx int) { 73 if v.isNull { 74 chk.AppendNull(defCausIdx) 75 } else { 76 chk.AppendInt64(defCausIdx, v.val) 77 } 78 } 79 80 type value4Float32 struct { 81 val float32 82 isNull bool 83 } 84 85 func (v *value4Float32) evaluateEvent(ctx stochastikctx.Context, expr memex.Expression, event chunk.Event) (memDelta int64, err error) { 86 var val float64 87 val, v.isNull, err = expr.EvalReal(ctx, event) 88 v.val = float32(val) 89 return 0, err 90 } 91 92 func (v *value4Float32) appendResult(chk *chunk.Chunk, defCausIdx int) { 93 if v.isNull { 94 chk.AppendNull(defCausIdx) 95 } else { 96 chk.AppendFloat32(defCausIdx, v.val) 97 } 98 } 99 100 type value4Decimal struct { 101 val *types.MyDecimal 102 isNull bool 103 } 104 105 func (v *value4Decimal) evaluateEvent(ctx stochastikctx.Context, expr memex.Expression, event chunk.Event) (memDelta int64, err error) { 106 v.val, v.isNull, err = expr.EvalDecimal(ctx, event) 107 return 0, err 108 } 109 110 func (v *value4Decimal) appendResult(chk *chunk.Chunk, defCausIdx int) { 111 if v.isNull { 112 chk.AppendNull(defCausIdx) 113 } else { 114 chk.AppendMyDecimal(defCausIdx, v.val) 115 } 116 } 117 118 type value4Float64 struct { 119 val float64 120 isNull bool 121 } 122 123 func (v *value4Float64) evaluateEvent(ctx stochastikctx.Context, expr memex.Expression, event chunk.Event) (memDelta int64, err error) { 124 v.val, v.isNull, err = expr.EvalReal(ctx, event) 125 return 0, err 126 } 127 128 func (v *value4Float64) appendResult(chk *chunk.Chunk, defCausIdx int) { 129 if v.isNull { 130 chk.AppendNull(defCausIdx) 131 } else { 132 chk.AppendFloat64(defCausIdx, v.val) 133 } 134 } 135 136 type value4String struct { 137 val string 138 isNull bool 139 } 140 141 func (v *value4String) evaluateEvent(ctx stochastikctx.Context, expr memex.Expression, event chunk.Event) (memDelta int64, err error) { 142 originalLength := len(v.val) 143 v.val, v.isNull, err = expr.EvalString(ctx, event) 144 return int64(len(v.val) - originalLength), err 145 } 146 147 func (v *value4String) appendResult(chk *chunk.Chunk, defCausIdx int) { 148 if v.isNull { 149 chk.AppendNull(defCausIdx) 150 } else { 151 chk.AppendString(defCausIdx, v.val) 152 } 153 } 154 155 type value4Time struct { 156 val types.Time 157 isNull bool 158 } 159 160 func (v *value4Time) evaluateEvent(ctx stochastikctx.Context, expr memex.Expression, event chunk.Event) (memDelta int64, err error) { 161 v.val, v.isNull, err = expr.EvalTime(ctx, event) 162 return 0, err 163 } 164 165 func (v *value4Time) appendResult(chk *chunk.Chunk, defCausIdx int) { 166 if v.isNull { 167 chk.AppendNull(defCausIdx) 168 } else { 169 chk.AppendTime(defCausIdx, v.val) 170 } 171 } 172 173 type value4Duration struct { 174 val types.Duration 175 isNull bool 176 } 177 178 func (v *value4Duration) evaluateEvent(ctx stochastikctx.Context, expr memex.Expression, event chunk.Event) (memDelta int64, err error) { 179 v.val, v.isNull, err = expr.EvalDuration(ctx, event) 180 return 0, err 181 } 182 183 func (v *value4Duration) appendResult(chk *chunk.Chunk, defCausIdx int) { 184 if v.isNull { 185 chk.AppendNull(defCausIdx) 186 } else { 187 chk.AppendDuration(defCausIdx, v.val) 188 } 189 } 190 191 type value4JSON struct { 192 val json.BinaryJSON 193 isNull bool 194 } 195 196 func (v *value4JSON) evaluateEvent(ctx stochastikctx.Context, expr memex.Expression, event chunk.Event) (memDelta int64, err error) { 197 originalLength := len(v.val.Value) 198 v.val, v.isNull, err = expr.EvalJSON(ctx, event) 199 v.val = v.val.Copy() // deep copy to avoid content change. 200 return int64(len(v.val.Value) - originalLength), err 201 } 202 203 func (v *value4JSON) appendResult(chk *chunk.Chunk, defCausIdx int) { 204 if v.isNull { 205 chk.AppendNull(defCausIdx) 206 } else { 207 chk.AppendJSON(defCausIdx, v.val) 208 } 209 } 210 211 func buildValueEvaluator(tp *types.FieldType) (ve valueEvaluator, memDelta int64) { 212 evalType := tp.EvalType() 213 if tp.Tp == allegrosql.TypeBit { 214 evalType = types.ETString 215 } 216 switch evalType { 217 case types.ETInt: 218 return &value4Int{}, DefValue4IntSize 219 case types.ETReal: 220 switch tp.Tp { 221 case allegrosql.TypeFloat: 222 return &value4Float32{}, DefValue4Float32Size 223 case allegrosql.TypeDouble: 224 return &value4Float64{}, DefValue4Float64Size 225 } 226 case types.ETDecimal: 227 return &value4Decimal{}, DefValue4DecimalSize 228 case types.ETDatetime, types.ETTimestamp: 229 return &value4Time{}, DefValue4TimeSize 230 case types.ETDuration: 231 return &value4Duration{}, DefValue4DurationSize 232 case types.ETString: 233 return &value4String{}, DefValue4StringSize 234 case types.ETJson: 235 return &value4JSON{}, DefValue4JSONSize 236 } 237 return nil, 0 238 } 239 240 type firstValue struct { 241 baseAggFunc 242 243 tp *types.FieldType 244 } 245 246 type partialResult4FirstValue struct { 247 gotFirstValue bool 248 evaluator valueEvaluator 249 } 250 251 func (v *firstValue) AllocPartialResult() (pr PartialResult, memDelta int64) { 252 ve, veMemDelta := buildValueEvaluator(v.tp) 253 p := &partialResult4FirstValue{evaluator: ve} 254 return PartialResult(p), DefPartialResult4FirstValueSize + veMemDelta 255 } 256 257 func (v *firstValue) ResetPartialResult(pr PartialResult) { 258 p := (*partialResult4FirstValue)(pr) 259 p.gotFirstValue = false 260 } 261 262 func (v *firstValue) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 263 p := (*partialResult4FirstValue)(pr) 264 if p.gotFirstValue { 265 return 0, nil 266 } 267 if len(rowsInGroup) > 0 { 268 p.gotFirstValue = true 269 memDelta, err = p.evaluator.evaluateEvent(sctx, v.args[0], rowsInGroup[0]) 270 if err != nil { 271 return 0, err 272 } 273 } 274 return memDelta, nil 275 } 276 277 func (v *firstValue) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 278 p := (*partialResult4FirstValue)(pr) 279 if !p.gotFirstValue { 280 chk.AppendNull(v.ordinal) 281 } else { 282 p.evaluator.appendResult(chk, v.ordinal) 283 } 284 return nil 285 } 286 287 type lastValue struct { 288 baseAggFunc 289 290 tp *types.FieldType 291 } 292 293 type partialResult4LastValue struct { 294 gotLastValue bool 295 evaluator valueEvaluator 296 } 297 298 func (v *lastValue) AllocPartialResult() (pr PartialResult, memDelta int64) { 299 ve, veMemDelta := buildValueEvaluator(v.tp) 300 p := &partialResult4FirstValue{evaluator: ve} 301 return PartialResult(p), DefPartialResult4LastValueSize + veMemDelta 302 } 303 304 func (v *lastValue) ResetPartialResult(pr PartialResult) { 305 p := (*partialResult4LastValue)(pr) 306 p.gotLastValue = false 307 } 308 309 func (v *lastValue) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 310 p := (*partialResult4LastValue)(pr) 311 if len(rowsInGroup) > 0 { 312 p.gotLastValue = true 313 memDelta, err = p.evaluator.evaluateEvent(sctx, v.args[0], rowsInGroup[len(rowsInGroup)-1]) 314 if err != nil { 315 return 0, err 316 } 317 } 318 return memDelta, nil 319 } 320 321 func (v *lastValue) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 322 p := (*partialResult4LastValue)(pr) 323 if !p.gotLastValue { 324 chk.AppendNull(v.ordinal) 325 } else { 326 p.evaluator.appendResult(chk, v.ordinal) 327 } 328 return nil 329 } 330 331 type nthValue struct { 332 baseAggFunc 333 334 tp *types.FieldType 335 nth uint64 336 } 337 338 type partialResult4NthValue struct { 339 seenEvents uint64 340 evaluator valueEvaluator 341 } 342 343 func (v *nthValue) AllocPartialResult() (pr PartialResult, memDelta int64) { 344 ve, veMemDelta := buildValueEvaluator(v.tp) 345 p := &partialResult4FirstValue{evaluator: ve} 346 return PartialResult(p), DefPartialResult4NthValueSize + veMemDelta 347 } 348 349 func (v *nthValue) ResetPartialResult(pr PartialResult) { 350 p := (*partialResult4NthValue)(pr) 351 p.seenEvents = 0 352 } 353 354 func (v *nthValue) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 355 if v.nth == 0 { 356 return 0, nil 357 } 358 p := (*partialResult4NthValue)(pr) 359 numEvents := uint64(len(rowsInGroup)) 360 if v.nth > p.seenEvents && v.nth-p.seenEvents <= numEvents { 361 memDelta, err = p.evaluator.evaluateEvent(sctx, v.args[0], rowsInGroup[v.nth-p.seenEvents-1]) 362 if err != nil { 363 return 0, err 364 } 365 } 366 p.seenEvents += numEvents 367 return memDelta, nil 368 } 369 370 func (v *nthValue) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 371 p := (*partialResult4NthValue)(pr) 372 if v.nth == 0 || p.seenEvents < v.nth { 373 chk.AppendNull(v.ordinal) 374 } else { 375 p.evaluator.appendResult(chk, v.ordinal) 376 } 377 return nil 378 }