github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/interlock/aggfuncs/func_max_min.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 "container/heap" 18 "unsafe" 19 20 "github.com/whtcorpsinc/milevadb/stochastikctx" 21 "github.com/whtcorpsinc/milevadb/types" 22 "github.com/whtcorpsinc/milevadb/types/json" 23 "github.com/whtcorpsinc/milevadb/soliton/chunk" 24 "github.com/whtcorpsinc/milevadb/soliton/stringutil" 25 ) 26 27 type maxMinHeap struct { 28 data []interface{} 29 h heap.Interface 30 varSet map[interface{}]int64 31 isMax bool 32 cmpFunc func(i, j interface{}) int 33 } 34 35 func newMaxMinHeap(isMax bool, cmpFunc func(i, j interface{}) int) *maxMinHeap { 36 h := &maxMinHeap{ 37 data: make([]interface{}, 0), 38 varSet: make(map[interface{}]int64), 39 isMax: isMax, 40 cmpFunc: cmpFunc, 41 } 42 return h 43 } 44 45 func (h *maxMinHeap) Len() int { return len(h.data) } 46 func (h *maxMinHeap) Less(i, j int) bool { 47 if h.isMax { 48 return h.cmpFunc(h.data[i], h.data[j]) > 0 49 } 50 return h.cmpFunc(h.data[i], h.data[j]) < 0 51 } 52 func (h *maxMinHeap) Swap(i, j int) { h.data[i], h.data[j] = h.data[j], h.data[i] } 53 54 func (h *maxMinHeap) Push(x interface{}) { 55 h.data = append(h.data, x) 56 } 57 func (h *maxMinHeap) Pop() interface{} { 58 old := h.data 59 n := len(old) 60 x := old[n-1] 61 h.data = old[0 : n-1] 62 return x 63 } 64 65 func (h *maxMinHeap) Reset() { 66 h.data = h.data[:0] 67 h.varSet = make(map[interface{}]int64) 68 } 69 func (h *maxMinHeap) Append(val interface{}) { 70 h.varSet[val]++ 71 if h.varSet[val] == 1 { 72 heap.Push(h, val) 73 } 74 } 75 func (h *maxMinHeap) Remove(val interface{}) { 76 if h.varSet[val] > 0 { 77 h.varSet[val]-- 78 } else { 79 panic("remove a not exist value") 80 } 81 } 82 func (h *maxMinHeap) Top() (val interface{}, isEmpty bool) { 83 retry: 84 if h.Len() == 0 { 85 return nil, true 86 } 87 top := h.data[0] 88 if h.varSet[top] == 0 { 89 _ = heap.Pop(h) 90 goto retry 91 } 92 return top, false 93 } 94 95 func (h *maxMinHeap) AppendMyDecimal(val types.MyDecimal) error { 96 key, err := val.ToHashKey() 97 if err != nil { 98 return err 99 } 100 h.varSet[string(key)]++ 101 if h.varSet[string(key)] == 1 { 102 heap.Push(h, val) 103 } 104 return nil 105 } 106 func (h *maxMinHeap) RemoveMyDecimal(val types.MyDecimal) error { 107 key, err := val.ToHashKey() 108 if err != nil { 109 return err 110 } 111 if h.varSet[string(key)] > 0 { 112 h.varSet[string(key)]-- 113 } else { 114 panic("remove a not exist value") 115 } 116 return nil 117 } 118 func (h *maxMinHeap) ToFIDelecimal() (val types.MyDecimal, isEmpty bool) { 119 retry: 120 if h.Len() == 0 { 121 return types.MyDecimal{}, true 122 } 123 top := h.data[0].(types.MyDecimal) 124 key, err := top.ToHashKey() 125 if err != nil { 126 panic(err) 127 } 128 if h.varSet[string(key)] == 0 { 129 _ = heap.Pop(h) 130 goto retry 131 } 132 return top, false 133 } 134 135 const ( 136 // DefPartialResult4MaxMinIntSize is the size of partialResult4MaxMinInt 137 DefPartialResult4MaxMinIntSize = int64(unsafe.Sizeof(partialResult4MaxMinInt{})) 138 // DefPartialResult4MaxMinUintSize is the size of partialResult4MaxMinUint 139 DefPartialResult4MaxMinUintSize = int64(unsafe.Sizeof(partialResult4MaxMinUint{})) 140 // DefPartialResult4MaxMinDecimalSize is the size of partialResult4MaxMinDecimal 141 DefPartialResult4MaxMinDecimalSize = int64(unsafe.Sizeof(partialResult4MaxMinDecimal{})) 142 // DefPartialResult4MaxMinFloat32Size is the size of partialResult4MaxMinFloat32 143 DefPartialResult4MaxMinFloat32Size = int64(unsafe.Sizeof(partialResult4MaxMinFloat32{})) 144 // DefPartialResult4MaxMinFloat64Size is the size of partialResult4MaxMinFloat64 145 DefPartialResult4MaxMinFloat64Size = int64(unsafe.Sizeof(partialResult4MaxMinFloat64{})) 146 // DefPartialResult4TimeSize is the size of partialResult4Time 147 DefPartialResult4TimeSize = int64(unsafe.Sizeof(partialResult4Time{})) 148 // DefPartialResult4MaxMinDurationSize is the size of partialResult4MaxMinDuration 149 DefPartialResult4MaxMinDurationSize = int64(unsafe.Sizeof(partialResult4MaxMinDuration{})) 150 // DefPartialResult4MaxMinStringSize is the size of partialResult4MaxMinString 151 DefPartialResult4MaxMinStringSize = int64(unsafe.Sizeof(partialResult4MaxMinString{})) 152 // DefPartialResult4MaxMinJSONSize is the size of partialResult4MaxMinJSON 153 DefPartialResult4MaxMinJSONSize = int64(unsafe.Sizeof(partialResult4MaxMinJSON{})) 154 // DefPartialResult4MaxMinEnumSize is the size of partialResult4MaxMinEnum 155 DefPartialResult4MaxMinEnumSize = int64(unsafe.Sizeof(partialResult4MaxMinEnum{})) 156 // DefPartialResult4MaxMinSetSize is the size of partialResult4MaxMinSet 157 DefPartialResult4MaxMinSetSize = int64(unsafe.Sizeof(partialResult4MaxMinSet{})) 158 ) 159 160 type partialResult4MaxMinInt struct { 161 val int64 162 // isNull is used to indicates: 163 // 1. whether the partial result is the initialization value which should not be compared during evaluation; 164 // 2. whether all the values of arg are all null, if so, we should return null as the default value for MAX/MIN. 165 isNull bool 166 // maxMinHeap is an ordered queue, using to evaluate the maximum or minimum value in a sliding window. 167 heap *maxMinHeap 168 } 169 170 type partialResult4MaxMinUint struct { 171 val uint64 172 isNull bool 173 heap *maxMinHeap 174 } 175 176 type partialResult4MaxMinDecimal struct { 177 val types.MyDecimal 178 isNull bool 179 heap *maxMinHeap 180 } 181 182 type partialResult4MaxMinFloat32 struct { 183 val float32 184 isNull bool 185 heap *maxMinHeap 186 } 187 188 type partialResult4MaxMinFloat64 struct { 189 val float64 190 isNull bool 191 heap *maxMinHeap 192 } 193 194 type partialResult4Time struct { 195 val types.Time 196 isNull bool 197 heap *maxMinHeap 198 } 199 200 type partialResult4MaxMinDuration struct { 201 val types.Duration 202 isNull bool 203 heap *maxMinHeap 204 } 205 206 type partialResult4MaxMinString struct { 207 val string 208 isNull bool 209 heap *maxMinHeap 210 } 211 212 type partialResult4MaxMinJSON struct { 213 val json.BinaryJSON 214 isNull bool 215 } 216 217 type partialResult4MaxMinEnum struct { 218 val types.Enum 219 isNull bool 220 } 221 222 type partialResult4MaxMinSet struct { 223 val types.Set 224 isNull bool 225 } 226 227 type baseMaxMinAggFunc struct { 228 baseAggFunc 229 230 isMax bool 231 } 232 233 type maxMin4Int struct { 234 baseMaxMinAggFunc 235 } 236 237 func (e *maxMin4Int) AllocPartialResult() (pr PartialResult, memDelta int64) { 238 p := new(partialResult4MaxMinInt) 239 p.isNull = true 240 p.heap = newMaxMinHeap(e.isMax, func(i, j interface{}) int { 241 return types.CompareInt64(i.(int64), j.(int64)) 242 }) 243 return PartialResult(p), DefPartialResult4MaxMinIntSize 244 } 245 246 func (e *maxMin4Int) ResetPartialResult(pr PartialResult) { 247 p := (*partialResult4MaxMinInt)(pr) 248 p.val = 0 249 p.isNull = true 250 p.heap.Reset() 251 } 252 253 func (e *maxMin4Int) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 254 p := (*partialResult4MaxMinInt)(pr) 255 if p.isNull { 256 chk.AppendNull(e.ordinal) 257 return nil 258 } 259 chk.AppendInt64(e.ordinal, p.val) 260 return nil 261 } 262 263 func (e *maxMin4Int) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 264 p := (*partialResult4MaxMinInt)(pr) 265 for _, event := range rowsInGroup { 266 input, isNull, err := e.args[0].EvalInt(sctx, event) 267 if err != nil { 268 return 0, err 269 } 270 if isNull { 271 continue 272 } 273 if p.isNull { 274 p.val = input 275 p.isNull = false 276 continue 277 } 278 if e.isMax && input > p.val || !e.isMax && input < p.val { 279 p.val = input 280 } 281 } 282 return 0, nil 283 } 284 285 func (e *maxMin4Int) MergePartialResult(sctx stochastikctx.Context, src, dst PartialResult) (memDelta int64, err error) { 286 p1, p2 := (*partialResult4MaxMinInt)(src), (*partialResult4MaxMinInt)(dst) 287 if p1.isNull { 288 return 0, nil 289 } 290 if p2.isNull { 291 *p2 = *p1 292 return 0, nil 293 } 294 if e.isMax && p1.val > p2.val || !e.isMax && p1.val < p2.val { 295 p2.val, p2.isNull = p1.val, false 296 } 297 return 0, nil 298 } 299 300 type maxMin4IntSliding struct { 301 maxMin4Int 302 } 303 304 func (e *maxMin4IntSliding) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 305 p := (*partialResult4MaxMinInt)(pr) 306 for _, event := range rowsInGroup { 307 input, isNull, err := e.args[0].EvalInt(sctx, event) 308 if err != nil { 309 return 0, err 310 } 311 if isNull { 312 continue 313 } 314 p.heap.Append(input) 315 } 316 if val, isEmpty := p.heap.Top(); !isEmpty { 317 p.val = val.(int64) 318 p.isNull = false 319 } else { 320 p.isNull = true 321 } 322 return 0, nil 323 } 324 325 func (e *maxMin4IntSliding) Slide(sctx stochastikctx.Context, rows []chunk.Event, lastStart, lastEnd uint64, shiftStart, shiftEnd uint64, pr PartialResult) error { 326 p := (*partialResult4MaxMinInt)(pr) 327 for i := uint64(0); i < shiftEnd; i++ { 328 input, isNull, err := e.args[0].EvalInt(sctx, rows[lastEnd+i]) 329 if err != nil { 330 return err 331 } 332 if isNull { 333 continue 334 } 335 p.heap.Append(input) 336 } 337 for i := uint64(0); i < shiftStart; i++ { 338 input, isNull, err := e.args[0].EvalInt(sctx, rows[lastStart+i]) 339 if err != nil { 340 return err 341 } 342 if isNull { 343 continue 344 } 345 p.heap.Remove(input) 346 } 347 if val, isEmpty := p.heap.Top(); !isEmpty { 348 p.val = val.(int64) 349 p.isNull = false 350 } else { 351 p.isNull = true 352 } 353 return nil 354 } 355 356 type maxMin4Uint struct { 357 baseMaxMinAggFunc 358 } 359 360 func (e *maxMin4Uint) AllocPartialResult() (pr PartialResult, memDelta int64) { 361 p := new(partialResult4MaxMinUint) 362 p.isNull = true 363 p.heap = newMaxMinHeap(e.isMax, func(i, j interface{}) int { 364 return types.CompareUint64(i.(uint64), j.(uint64)) 365 }) 366 return PartialResult(p), DefPartialResult4MaxMinUintSize 367 } 368 369 func (e *maxMin4Uint) ResetPartialResult(pr PartialResult) { 370 p := (*partialResult4MaxMinUint)(pr) 371 p.val = 0 372 p.isNull = true 373 p.heap.Reset() 374 } 375 376 func (e *maxMin4Uint) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 377 p := (*partialResult4MaxMinUint)(pr) 378 if p.isNull { 379 chk.AppendNull(e.ordinal) 380 return nil 381 } 382 chk.AppendUint64(e.ordinal, p.val) 383 return nil 384 } 385 386 func (e *maxMin4Uint) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 387 p := (*partialResult4MaxMinUint)(pr) 388 for _, event := range rowsInGroup { 389 input, isNull, err := e.args[0].EvalInt(sctx, event) 390 if err != nil { 391 return 0, err 392 } 393 if isNull { 394 continue 395 } 396 uintVal := uint64(input) 397 if p.isNull { 398 p.val = uintVal 399 p.isNull = false 400 continue 401 } 402 if e.isMax && uintVal > p.val || !e.isMax && uintVal < p.val { 403 p.val = uintVal 404 } 405 } 406 return 0, nil 407 } 408 409 func (e *maxMin4Uint) MergePartialResult(sctx stochastikctx.Context, src, dst PartialResult) (memDelta int64, err error) { 410 p1, p2 := (*partialResult4MaxMinUint)(src), (*partialResult4MaxMinUint)(dst) 411 if p1.isNull { 412 return 0, nil 413 } 414 if p2.isNull { 415 *p2 = *p1 416 return 0, nil 417 } 418 if e.isMax && p1.val > p2.val || !e.isMax && p1.val < p2.val { 419 p2.val, p2.isNull = p1.val, false 420 } 421 return 0, nil 422 } 423 424 type maxMin4UintSliding struct { 425 maxMin4Uint 426 } 427 428 func (e *maxMin4UintSliding) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 429 p := (*partialResult4MaxMinUint)(pr) 430 for _, event := range rowsInGroup { 431 input, isNull, err := e.args[0].EvalInt(sctx, event) 432 if err != nil { 433 return 0, err 434 } 435 if isNull { 436 continue 437 } 438 p.heap.Append(uint64(input)) 439 } 440 if val, isEmpty := p.heap.Top(); !isEmpty { 441 p.val = val.(uint64) 442 p.isNull = false 443 } else { 444 p.isNull = true 445 } 446 return 0, nil 447 } 448 449 func (e *maxMin4UintSliding) Slide(sctx stochastikctx.Context, rows []chunk.Event, lastStart, lastEnd uint64, shiftStart, shiftEnd uint64, pr PartialResult) error { 450 p := (*partialResult4MaxMinUint)(pr) 451 for i := uint64(0); i < shiftEnd; i++ { 452 input, isNull, err := e.args[0].EvalInt(sctx, rows[lastEnd+i]) 453 if err != nil { 454 return err 455 } 456 if isNull { 457 continue 458 } 459 p.heap.Append(uint64(input)) 460 } 461 for i := uint64(0); i < shiftStart; i++ { 462 input, isNull, err := e.args[0].EvalInt(sctx, rows[lastStart+i]) 463 if err != nil { 464 return err 465 } 466 if isNull { 467 continue 468 } 469 p.heap.Remove(uint64(input)) 470 } 471 if val, isEmpty := p.heap.Top(); !isEmpty { 472 p.val = val.(uint64) 473 p.isNull = false 474 } else { 475 p.isNull = true 476 } 477 return nil 478 } 479 480 // maxMin4Float32 gets a float32 input and returns a float32 result. 481 type maxMin4Float32 struct { 482 baseMaxMinAggFunc 483 } 484 485 func (e *maxMin4Float32) AllocPartialResult() (pr PartialResult, memDelta int64) { 486 p := new(partialResult4MaxMinFloat32) 487 p.isNull = true 488 p.heap = newMaxMinHeap(e.isMax, func(i, j interface{}) int { 489 return types.CompareFloat64(float64(i.(float32)), float64(j.(float32))) 490 }) 491 return PartialResult(p), DefPartialResult4MaxMinFloat32Size 492 } 493 494 func (e *maxMin4Float32) ResetPartialResult(pr PartialResult) { 495 p := (*partialResult4MaxMinFloat32)(pr) 496 p.val = 0 497 p.isNull = true 498 p.heap.Reset() 499 } 500 501 func (e *maxMin4Float32) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 502 p := (*partialResult4MaxMinFloat32)(pr) 503 if p.isNull { 504 chk.AppendNull(e.ordinal) 505 return nil 506 } 507 chk.AppendFloat32(e.ordinal, p.val) 508 return nil 509 } 510 511 func (e *maxMin4Float32) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 512 p := (*partialResult4MaxMinFloat32)(pr) 513 for _, event := range rowsInGroup { 514 input, isNull, err := e.args[0].EvalReal(sctx, event) 515 if err != nil { 516 return 0, err 517 } 518 if isNull { 519 continue 520 } 521 f := float32(input) 522 if p.isNull { 523 p.val = f 524 p.isNull = false 525 continue 526 } 527 if e.isMax && f > p.val || !e.isMax && f < p.val { 528 p.val = f 529 } 530 } 531 return 0, nil 532 } 533 534 func (e *maxMin4Float32) MergePartialResult(sctx stochastikctx.Context, src, dst PartialResult) (memDelta int64, err error) { 535 p1, p2 := (*partialResult4MaxMinFloat32)(src), (*partialResult4MaxMinFloat32)(dst) 536 if p1.isNull { 537 return 0, nil 538 } 539 if p2.isNull { 540 *p2 = *p1 541 return 0, nil 542 } 543 if e.isMax && p1.val > p2.val || !e.isMax && p1.val < p2.val { 544 p2.val, p2.isNull = p1.val, false 545 } 546 return 0, nil 547 } 548 549 type maxMin4Float32Sliding struct { 550 maxMin4Float32 551 } 552 553 func (e *maxMin4Float32Sliding) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 554 p := (*partialResult4MaxMinFloat32)(pr) 555 for _, event := range rowsInGroup { 556 input, isNull, err := e.args[0].EvalReal(sctx, event) 557 if err != nil { 558 return 0, err 559 } 560 if isNull { 561 continue 562 } 563 p.heap.Append(float32(input)) 564 } 565 if val, isEmpty := p.heap.Top(); !isEmpty { 566 p.val = val.(float32) 567 p.isNull = false 568 } else { 569 p.isNull = true 570 } 571 return 0, nil 572 } 573 574 func (e *maxMin4Float32Sliding) Slide(sctx stochastikctx.Context, rows []chunk.Event, lastStart, lastEnd uint64, shiftStart, shiftEnd uint64, pr PartialResult) error { 575 p := (*partialResult4MaxMinFloat32)(pr) 576 for i := uint64(0); i < shiftEnd; i++ { 577 input, isNull, err := e.args[0].EvalReal(sctx, rows[lastEnd+i]) 578 if err != nil { 579 return err 580 } 581 if isNull { 582 continue 583 } 584 p.heap.Append(float32(input)) 585 } 586 for i := uint64(0); i < shiftStart; i++ { 587 input, isNull, err := e.args[0].EvalReal(sctx, rows[lastStart+i]) 588 if err != nil { 589 return err 590 } 591 if isNull { 592 continue 593 } 594 p.heap.Remove(float32(input)) 595 } 596 if val, isEmpty := p.heap.Top(); !isEmpty { 597 p.val = val.(float32) 598 p.isNull = false 599 } else { 600 p.isNull = true 601 } 602 return nil 603 } 604 605 type maxMin4Float64 struct { 606 baseMaxMinAggFunc 607 } 608 609 func (e *maxMin4Float64) AllocPartialResult() (pr PartialResult, memDelta int64) { 610 p := new(partialResult4MaxMinFloat64) 611 p.isNull = true 612 p.heap = newMaxMinHeap(e.isMax, func(i, j interface{}) int { 613 return types.CompareFloat64(i.(float64), j.(float64)) 614 }) 615 return PartialResult(p), DefPartialResult4MaxMinFloat64Size 616 } 617 618 func (e *maxMin4Float64) ResetPartialResult(pr PartialResult) { 619 p := (*partialResult4MaxMinFloat64)(pr) 620 p.val = 0 621 p.isNull = true 622 p.heap.Reset() 623 } 624 625 func (e *maxMin4Float64) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 626 p := (*partialResult4MaxMinFloat64)(pr) 627 if p.isNull { 628 chk.AppendNull(e.ordinal) 629 return nil 630 } 631 chk.AppendFloat64(e.ordinal, p.val) 632 return nil 633 } 634 635 func (e *maxMin4Float64) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 636 p := (*partialResult4MaxMinFloat64)(pr) 637 for _, event := range rowsInGroup { 638 input, isNull, err := e.args[0].EvalReal(sctx, event) 639 if err != nil { 640 return 0, err 641 } 642 if isNull { 643 continue 644 } 645 if p.isNull { 646 p.val = input 647 p.isNull = false 648 continue 649 } 650 if e.isMax && input > p.val || !e.isMax && input < p.val { 651 p.val = input 652 } 653 } 654 return 0, nil 655 } 656 657 func (e *maxMin4Float64) MergePartialResult(sctx stochastikctx.Context, src, dst PartialResult) (memDelta int64, err error) { 658 p1, p2 := (*partialResult4MaxMinFloat64)(src), (*partialResult4MaxMinFloat64)(dst) 659 if p1.isNull { 660 return 0, nil 661 } 662 if p2.isNull { 663 *p2 = *p1 664 return 0, nil 665 } 666 if e.isMax && p1.val > p2.val || !e.isMax && p1.val < p2.val { 667 p2.val, p2.isNull = p1.val, false 668 } 669 return 0, nil 670 } 671 672 type maxMin4Float64Sliding struct { 673 maxMin4Float64 674 } 675 676 func (e *maxMin4Float64Sliding) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 677 p := (*partialResult4MaxMinFloat64)(pr) 678 for _, event := range rowsInGroup { 679 input, isNull, err := e.args[0].EvalReal(sctx, event) 680 if err != nil { 681 return 0, err 682 } 683 if isNull { 684 continue 685 } 686 p.heap.Append(input) 687 } 688 if val, isEmpty := p.heap.Top(); !isEmpty { 689 p.val = val.(float64) 690 p.isNull = false 691 } else { 692 p.isNull = true 693 } 694 return 0, nil 695 } 696 697 func (e *maxMin4Float64Sliding) Slide(sctx stochastikctx.Context, rows []chunk.Event, lastStart, lastEnd uint64, shiftStart, shiftEnd uint64, pr PartialResult) error { 698 p := (*partialResult4MaxMinFloat64)(pr) 699 for i := uint64(0); i < shiftEnd; i++ { 700 input, isNull, err := e.args[0].EvalReal(sctx, rows[lastEnd+i]) 701 if err != nil { 702 return err 703 } 704 if isNull { 705 continue 706 } 707 p.heap.Append(input) 708 } 709 for i := uint64(0); i < shiftStart; i++ { 710 input, isNull, err := e.args[0].EvalReal(sctx, rows[lastStart+i]) 711 if err != nil { 712 return err 713 } 714 if isNull { 715 continue 716 } 717 p.heap.Remove(input) 718 } 719 if val, isEmpty := p.heap.Top(); !isEmpty { 720 p.val = val.(float64) 721 p.isNull = false 722 } else { 723 p.isNull = true 724 } 725 return nil 726 } 727 728 type maxMin4Decimal struct { 729 baseMaxMinAggFunc 730 } 731 732 func (e *maxMin4Decimal) AllocPartialResult() (pr PartialResult, memDelta int64) { 733 p := new(partialResult4MaxMinDecimal) 734 p.isNull = true 735 p.heap = newMaxMinHeap(e.isMax, func(i, j interface{}) int { 736 src := i.(types.MyDecimal) 737 dst := j.(types.MyDecimal) 738 return src.Compare(&dst) 739 }) 740 return PartialResult(p), DefPartialResult4MaxMinDecimalSize 741 } 742 743 func (e *maxMin4Decimal) ResetPartialResult(pr PartialResult) { 744 p := (*partialResult4MaxMinDecimal)(pr) 745 p.isNull = true 746 p.heap.Reset() 747 } 748 749 func (e *maxMin4Decimal) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 750 p := (*partialResult4MaxMinDecimal)(pr) 751 if p.isNull { 752 chk.AppendNull(e.ordinal) 753 return nil 754 } 755 chk.AppendMyDecimal(e.ordinal, &p.val) 756 return nil 757 } 758 759 func (e *maxMin4Decimal) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 760 p := (*partialResult4MaxMinDecimal)(pr) 761 for _, event := range rowsInGroup { 762 input, isNull, err := e.args[0].EvalDecimal(sctx, event) 763 if err != nil { 764 return 0, err 765 } 766 if isNull { 767 continue 768 } 769 if p.isNull { 770 p.val = *input 771 p.isNull = false 772 continue 773 } 774 cmp := input.Compare(&p.val) 775 if e.isMax && cmp > 0 || !e.isMax && cmp < 0 { 776 p.val = *input 777 } 778 } 779 return 0, nil 780 } 781 782 func (e *maxMin4Decimal) MergePartialResult(sctx stochastikctx.Context, src, dst PartialResult) (memDelta int64, err error) { 783 p1, p2 := (*partialResult4MaxMinDecimal)(src), (*partialResult4MaxMinDecimal)(dst) 784 if p1.isNull { 785 return 0, nil 786 } 787 if p2.isNull { 788 *p2 = *p1 789 return 0, nil 790 } 791 cmp := (&p1.val).Compare(&p2.val) 792 if e.isMax && cmp > 0 || !e.isMax && cmp < 0 { 793 p2.val, p2.isNull = p1.val, false 794 } 795 return 0, nil 796 } 797 798 type maxMin4DecimalSliding struct { 799 maxMin4Decimal 800 } 801 802 func (e *maxMin4DecimalSliding) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 803 p := (*partialResult4MaxMinDecimal)(pr) 804 for _, event := range rowsInGroup { 805 input, isNull, err := e.args[0].EvalDecimal(sctx, event) 806 if err != nil { 807 return 0, err 808 } 809 if isNull { 810 continue 811 } 812 if err := p.heap.AppendMyDecimal(*input); err != nil { 813 return 0, err 814 } 815 } 816 if val, isEmpty := p.heap.ToFIDelecimal(); !isEmpty { 817 p.val = val 818 p.isNull = false 819 } else { 820 p.isNull = true 821 } 822 return 0, nil 823 } 824 825 func (e *maxMin4DecimalSliding) Slide(sctx stochastikctx.Context, rows []chunk.Event, lastStart, lastEnd uint64, shiftStart, shiftEnd uint64, pr PartialResult) error { 826 p := (*partialResult4MaxMinDecimal)(pr) 827 for i := uint64(0); i < shiftEnd; i++ { 828 input, isNull, err := e.args[0].EvalDecimal(sctx, rows[lastEnd+i]) 829 if err != nil { 830 return err 831 } 832 if isNull { 833 continue 834 } 835 if err := p.heap.AppendMyDecimal(*input); err != nil { 836 return err 837 } 838 } 839 for i := uint64(0); i < shiftStart; i++ { 840 input, isNull, err := e.args[0].EvalDecimal(sctx, rows[lastStart+i]) 841 if err != nil { 842 return err 843 } 844 if isNull { 845 continue 846 } 847 if err := p.heap.RemoveMyDecimal(*input); err != nil { 848 return err 849 } 850 } 851 if val, isEmpty := p.heap.ToFIDelecimal(); !isEmpty { 852 p.val = val 853 p.isNull = false 854 } else { 855 p.isNull = true 856 } 857 return nil 858 } 859 860 type maxMin4String struct { 861 baseMaxMinAggFunc 862 retTp *types.FieldType 863 } 864 865 func (e *maxMin4String) AllocPartialResult() (pr PartialResult, memDelta int64) { 866 p := new(partialResult4MaxMinString) 867 p.isNull = true 868 tp := e.args[0].GetType() 869 p.heap = newMaxMinHeap(e.isMax, func(i, j interface{}) int { 870 return types.CompareString(i.(string), j.(string), tp.DefCauslate) 871 }) 872 return PartialResult(p), DefPartialResult4MaxMinStringSize 873 } 874 875 func (e *maxMin4String) ResetPartialResult(pr PartialResult) { 876 p := (*partialResult4MaxMinString)(pr) 877 p.isNull = true 878 p.heap.Reset() 879 } 880 881 func (e *maxMin4String) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 882 p := (*partialResult4MaxMinString)(pr) 883 if p.isNull { 884 chk.AppendNull(e.ordinal) 885 return nil 886 } 887 chk.AppendString(e.ordinal, p.val) 888 return nil 889 } 890 891 func (e *maxMin4String) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 892 p := (*partialResult4MaxMinString)(pr) 893 tp := e.args[0].GetType() 894 for _, event := range rowsInGroup { 895 input, isNull, err := e.args[0].EvalString(sctx, event) 896 if err != nil { 897 return memDelta, err 898 } 899 if isNull { 900 continue 901 } 902 if p.isNull { 903 // The string returned by `EvalString` may be referenced to an underlying buffer, 904 // for example ‘Chunk’, which could be reset and reused multiply times. 905 // We have to deep copy that string to avoid some potential risks 906 // when the content of that underlying buffer changed. 907 p.val = stringutil.Copy(input) 908 memDelta += int64(len(input)) 909 p.isNull = false 910 continue 911 } 912 cmp := types.CompareString(input, p.val, tp.DefCauslate) 913 if e.isMax && cmp == 1 || !e.isMax && cmp == -1 { 914 oldMem := len(p.val) 915 newMem := len(input) 916 memDelta += int64(newMem - oldMem) 917 p.val = stringutil.Copy(input) 918 } 919 } 920 return memDelta, nil 921 } 922 923 func (e *maxMin4String) MergePartialResult(sctx stochastikctx.Context, src, dst PartialResult) (memDelta int64, err error) { 924 p1, p2 := (*partialResult4MaxMinString)(src), (*partialResult4MaxMinString)(dst) 925 if p1.isNull { 926 return 0, nil 927 } 928 if p2.isNull { 929 *p2 = *p1 930 return 0, nil 931 } 932 tp := e.args[0].GetType() 933 cmp := types.CompareString(p1.val, p2.val, tp.DefCauslate) 934 if e.isMax && cmp > 0 || !e.isMax && cmp < 0 { 935 p2.val, p2.isNull = p1.val, false 936 } 937 return 0, nil 938 } 939 940 type maxMin4StringSliding struct { 941 maxMin4String 942 } 943 944 func (e *maxMin4StringSliding) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 945 p := (*partialResult4MaxMinString)(pr) 946 for _, event := range rowsInGroup { 947 input, isNull, err := e.args[0].EvalString(sctx, event) 948 if err != nil { 949 return 0, err 950 } 951 if isNull { 952 continue 953 } 954 p.heap.Append(input) 955 } 956 if val, isEmpty := p.heap.Top(); !isEmpty { 957 p.val = val.(string) 958 p.isNull = false 959 } else { 960 p.isNull = true 961 } 962 return 0, nil 963 } 964 965 func (e *maxMin4StringSliding) Slide(sctx stochastikctx.Context, rows []chunk.Event, lastStart, lastEnd uint64, shiftStart, shiftEnd uint64, pr PartialResult) error { 966 p := (*partialResult4MaxMinString)(pr) 967 for i := uint64(0); i < shiftEnd; i++ { 968 input, isNull, err := e.args[0].EvalString(sctx, rows[lastEnd+i]) 969 if err != nil { 970 return err 971 } 972 if isNull { 973 continue 974 } 975 p.heap.Append(input) 976 } 977 for i := uint64(0); i < shiftStart; i++ { 978 input, isNull, err := e.args[0].EvalString(sctx, rows[lastStart+i]) 979 if err != nil { 980 return err 981 } 982 if isNull { 983 continue 984 } 985 p.heap.Remove(input) 986 } 987 if val, isEmpty := p.heap.Top(); !isEmpty { 988 p.val = val.(string) 989 p.isNull = false 990 } else { 991 p.isNull = true 992 } 993 return nil 994 } 995 996 type maxMin4Time struct { 997 baseMaxMinAggFunc 998 } 999 1000 func (e *maxMin4Time) AllocPartialResult() (pr PartialResult, memDelta int64) { 1001 p := new(partialResult4Time) 1002 p.isNull = true 1003 p.heap = newMaxMinHeap(e.isMax, func(i, j interface{}) int { 1004 src := i.(types.Time) 1005 dst := j.(types.Time) 1006 return src.Compare(dst) 1007 }) 1008 return PartialResult(p), DefPartialResult4TimeSize 1009 } 1010 1011 func (e *maxMin4Time) ResetPartialResult(pr PartialResult) { 1012 p := (*partialResult4Time)(pr) 1013 p.isNull = true 1014 p.heap.Reset() 1015 } 1016 1017 func (e *maxMin4Time) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 1018 p := (*partialResult4Time)(pr) 1019 if p.isNull { 1020 chk.AppendNull(e.ordinal) 1021 return nil 1022 } 1023 chk.AppendTime(e.ordinal, p.val) 1024 return nil 1025 } 1026 1027 func (e *maxMin4Time) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 1028 p := (*partialResult4Time)(pr) 1029 for _, event := range rowsInGroup { 1030 input, isNull, err := e.args[0].EvalTime(sctx, event) 1031 if err != nil { 1032 return 0, err 1033 } 1034 if isNull { 1035 continue 1036 } 1037 if p.isNull { 1038 p.val = input 1039 p.isNull = false 1040 continue 1041 } 1042 cmp := input.Compare(p.val) 1043 if e.isMax && cmp == 1 || !e.isMax && cmp == -1 { 1044 p.val = input 1045 } 1046 } 1047 return 0, nil 1048 } 1049 1050 func (e *maxMin4Time) MergePartialResult(sctx stochastikctx.Context, src, dst PartialResult) (memDelta int64, err error) { 1051 p1, p2 := (*partialResult4Time)(src), (*partialResult4Time)(dst) 1052 if p1.isNull { 1053 return 0, nil 1054 } 1055 if p2.isNull { 1056 *p2 = *p1 1057 return 0, nil 1058 } 1059 cmp := p1.val.Compare(p2.val) 1060 if e.isMax && cmp == 1 || !e.isMax && cmp == -1 { 1061 p2.val, p2.isNull = p1.val, false 1062 } 1063 return 0, nil 1064 } 1065 1066 type maxMin4TimeSliding struct { 1067 maxMin4Time 1068 } 1069 1070 func (e *maxMin4TimeSliding) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 1071 p := (*partialResult4Time)(pr) 1072 for _, event := range rowsInGroup { 1073 input, isNull, err := e.args[0].EvalTime(sctx, event) 1074 if err != nil { 1075 return 0, err 1076 } 1077 if isNull { 1078 continue 1079 } 1080 p.heap.Append(input) 1081 } 1082 if val, isEmpty := p.heap.Top(); !isEmpty { 1083 p.val = val.(types.Time) 1084 p.isNull = false 1085 } else { 1086 p.isNull = true 1087 } 1088 return 0, nil 1089 } 1090 1091 func (e *maxMin4TimeSliding) Slide(sctx stochastikctx.Context, rows []chunk.Event, lastStart, lastEnd uint64, shiftStart, shiftEnd uint64, pr PartialResult) error { 1092 p := (*partialResult4Time)(pr) 1093 for i := uint64(0); i < shiftEnd; i++ { 1094 input, isNull, err := e.args[0].EvalTime(sctx, rows[lastEnd+i]) 1095 if err != nil { 1096 return err 1097 } 1098 if isNull { 1099 continue 1100 } 1101 p.heap.Append(input) 1102 } 1103 for i := uint64(0); i < shiftStart; i++ { 1104 input, isNull, err := e.args[0].EvalTime(sctx, rows[lastStart+i]) 1105 if err != nil { 1106 return err 1107 } 1108 if isNull { 1109 continue 1110 } 1111 p.heap.Remove(input) 1112 } 1113 if val, isEmpty := p.heap.Top(); !isEmpty { 1114 p.val = val.(types.Time) 1115 p.isNull = false 1116 } else { 1117 p.isNull = true 1118 } 1119 return nil 1120 } 1121 1122 type maxMin4Duration struct { 1123 baseMaxMinAggFunc 1124 } 1125 1126 func (e *maxMin4Duration) AllocPartialResult() (pr PartialResult, memDelta int64) { 1127 p := new(partialResult4MaxMinDuration) 1128 p.isNull = true 1129 p.heap = newMaxMinHeap(e.isMax, func(i, j interface{}) int { 1130 src := i.(types.Duration) 1131 dst := j.(types.Duration) 1132 return src.Compare(dst) 1133 }) 1134 return PartialResult(p), DefPartialResult4MaxMinDurationSize 1135 } 1136 1137 func (e *maxMin4Duration) ResetPartialResult(pr PartialResult) { 1138 p := (*partialResult4MaxMinDuration)(pr) 1139 p.isNull = true 1140 p.heap.Reset() 1141 } 1142 1143 func (e *maxMin4Duration) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 1144 p := (*partialResult4MaxMinDuration)(pr) 1145 if p.isNull { 1146 chk.AppendNull(e.ordinal) 1147 return nil 1148 } 1149 chk.AppendDuration(e.ordinal, p.val) 1150 return nil 1151 } 1152 1153 func (e *maxMin4Duration) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 1154 p := (*partialResult4MaxMinDuration)(pr) 1155 for _, event := range rowsInGroup { 1156 input, isNull, err := e.args[0].EvalDuration(sctx, event) 1157 if err != nil { 1158 return 0, err 1159 } 1160 if isNull { 1161 continue 1162 } 1163 if p.isNull { 1164 p.val = input 1165 p.isNull = false 1166 continue 1167 } 1168 cmp := input.Compare(p.val) 1169 if e.isMax && cmp == 1 || !e.isMax && cmp == -1 { 1170 p.val = input 1171 } 1172 } 1173 return 0, nil 1174 } 1175 1176 func (e *maxMin4Duration) MergePartialResult(sctx stochastikctx.Context, src, dst PartialResult) (memDelta int64, err error) { 1177 p1, p2 := (*partialResult4MaxMinDuration)(src), (*partialResult4MaxMinDuration)(dst) 1178 if p1.isNull { 1179 return 0, nil 1180 } 1181 if p2.isNull { 1182 *p2 = *p1 1183 return 0, nil 1184 } 1185 cmp := p1.val.Compare(p2.val) 1186 if e.isMax && cmp == 1 || !e.isMax && cmp == -1 { 1187 p2.val, p2.isNull = p1.val, false 1188 } 1189 return 0, nil 1190 } 1191 1192 type maxMin4DurationSliding struct { 1193 maxMin4Duration 1194 } 1195 1196 func (e *maxMin4DurationSliding) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 1197 p := (*partialResult4MaxMinDuration)(pr) 1198 for _, event := range rowsInGroup { 1199 input, isNull, err := e.args[0].EvalDuration(sctx, event) 1200 if err != nil { 1201 return 0, err 1202 } 1203 if isNull { 1204 continue 1205 } 1206 p.heap.Append(input) 1207 } 1208 if val, isEmpty := p.heap.Top(); !isEmpty { 1209 p.val = val.(types.Duration) 1210 p.isNull = false 1211 } else { 1212 p.isNull = true 1213 } 1214 return 0, nil 1215 } 1216 1217 func (e *maxMin4DurationSliding) Slide(sctx stochastikctx.Context, rows []chunk.Event, lastStart, lastEnd uint64, shiftStart, shiftEnd uint64, pr PartialResult) error { 1218 p := (*partialResult4MaxMinDuration)(pr) 1219 for i := uint64(0); i < shiftEnd; i++ { 1220 input, isNull, err := e.args[0].EvalDuration(sctx, rows[lastEnd+i]) 1221 if err != nil { 1222 return err 1223 } 1224 if isNull { 1225 continue 1226 } 1227 p.heap.Append(input) 1228 } 1229 for i := uint64(0); i < shiftStart; i++ { 1230 input, isNull, err := e.args[0].EvalDuration(sctx, rows[lastStart+i]) 1231 if err != nil { 1232 return err 1233 } 1234 if isNull { 1235 continue 1236 } 1237 p.heap.Remove(input) 1238 } 1239 if val, isEmpty := p.heap.Top(); !isEmpty { 1240 p.val = val.(types.Duration) 1241 p.isNull = false 1242 } else { 1243 p.isNull = true 1244 } 1245 return nil 1246 } 1247 1248 type maxMin4JSON struct { 1249 baseMaxMinAggFunc 1250 } 1251 1252 func (e *maxMin4JSON) AllocPartialResult() (pr PartialResult, memDelta int64) { 1253 p := new(partialResult4MaxMinJSON) 1254 p.isNull = true 1255 return PartialResult(p), DefPartialResult4MaxMinJSONSize 1256 } 1257 1258 func (e *maxMin4JSON) ResetPartialResult(pr PartialResult) { 1259 p := (*partialResult4MaxMinJSON)(pr) 1260 p.isNull = true 1261 } 1262 1263 func (e *maxMin4JSON) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 1264 p := (*partialResult4MaxMinJSON)(pr) 1265 if p.isNull { 1266 chk.AppendNull(e.ordinal) 1267 return nil 1268 } 1269 chk.AppendJSON(e.ordinal, p.val) 1270 return nil 1271 } 1272 1273 func (e *maxMin4JSON) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 1274 p := (*partialResult4MaxMinJSON)(pr) 1275 for _, event := range rowsInGroup { 1276 input, isNull, err := e.args[0].EvalJSON(sctx, event) 1277 if err != nil { 1278 return memDelta, err 1279 } 1280 if isNull { 1281 continue 1282 } 1283 if p.isNull { 1284 p.val = input.Copy() 1285 memDelta += int64(len(input.Value)) 1286 p.isNull = false 1287 continue 1288 } 1289 cmp := json.CompareBinary(input, p.val) 1290 if e.isMax && cmp > 0 || !e.isMax && cmp < 0 { 1291 oldMem := len(p.val.Value) 1292 newMem := len(input.Value) 1293 memDelta += int64(newMem - oldMem) 1294 p.val = input.Copy() 1295 } 1296 } 1297 return memDelta, nil 1298 } 1299 1300 func (e *maxMin4JSON) MergePartialResult(sctx stochastikctx.Context, src, dst PartialResult) (memDelta int64, err error) { 1301 p1, p2 := (*partialResult4MaxMinJSON)(src), (*partialResult4MaxMinJSON)(dst) 1302 if p1.isNull { 1303 return 0, nil 1304 } 1305 if p2.isNull { 1306 *p2 = *p1 1307 return 0, nil 1308 } 1309 cmp := json.CompareBinary(p1.val, p2.val) 1310 if e.isMax && cmp > 0 || !e.isMax && cmp < 0 { 1311 p2.val = p1.val 1312 p2.isNull = false 1313 } 1314 return 0, nil 1315 } 1316 1317 type maxMin4Enum struct { 1318 baseMaxMinAggFunc 1319 } 1320 1321 func (e *maxMin4Enum) AllocPartialResult() (pr PartialResult, memDelta int64) { 1322 p := new(partialResult4MaxMinEnum) 1323 p.isNull = true 1324 return PartialResult(p), DefPartialResult4MaxMinEnumSize 1325 } 1326 1327 func (e *maxMin4Enum) ResetPartialResult(pr PartialResult) { 1328 p := (*partialResult4MaxMinEnum)(pr) 1329 p.isNull = true 1330 } 1331 1332 func (e *maxMin4Enum) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 1333 p := (*partialResult4MaxMinEnum)(pr) 1334 if p.isNull { 1335 chk.AppendNull(e.ordinal) 1336 return nil 1337 } 1338 chk.AppendEnum(e.ordinal, p.val) 1339 return nil 1340 } 1341 1342 func (e *maxMin4Enum) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 1343 p := (*partialResult4MaxMinEnum)(pr) 1344 for _, event := range rowsInGroup { 1345 d, err := e.args[0].Eval(event) 1346 if err != nil { 1347 return memDelta, err 1348 } 1349 if d.IsNull() { 1350 continue 1351 } 1352 if p.isNull { 1353 p.val = d.GetMysqlEnum().Copy() 1354 memDelta += int64(len(d.GetMysqlEnum().Name)) 1355 p.isNull = false 1356 continue 1357 } 1358 en := d.GetMysqlEnum() 1359 if e.isMax && en.Value > p.val.Value || !e.isMax && en.Value < p.val.Value { 1360 oldMem := len(p.val.Name) 1361 newMem := len(en.Name) 1362 memDelta += int64(newMem - oldMem) 1363 p.val = en.Copy() 1364 } 1365 } 1366 return memDelta, nil 1367 } 1368 1369 func (e *maxMin4Enum) MergePartialResult(sctx stochastikctx.Context, src, dst PartialResult) (memDelta int64, err error) { 1370 p1, p2 := (*partialResult4MaxMinEnum)(src), (*partialResult4MaxMinEnum)(dst) 1371 if p1.isNull { 1372 return 0, nil 1373 } 1374 if p2.isNull { 1375 *p2 = *p1 1376 return 0, nil 1377 } 1378 if e.isMax && p1.val.Value > p2.val.Value || !e.isMax && p1.val.Value < p2.val.Value { 1379 p2.val, p2.isNull = p1.val, false 1380 } 1381 return 0, nil 1382 } 1383 1384 type maxMin4Set struct { 1385 baseMaxMinAggFunc 1386 } 1387 1388 func (e *maxMin4Set) AllocPartialResult() (pr PartialResult, memDelta int64) { 1389 p := new(partialResult4MaxMinSet) 1390 p.isNull = true 1391 return PartialResult(p), DefPartialResult4MaxMinSetSize 1392 } 1393 1394 func (e *maxMin4Set) ResetPartialResult(pr PartialResult) { 1395 p := (*partialResult4MaxMinSet)(pr) 1396 p.isNull = true 1397 } 1398 1399 func (e *maxMin4Set) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 1400 p := (*partialResult4MaxMinSet)(pr) 1401 if p.isNull { 1402 chk.AppendNull(e.ordinal) 1403 return nil 1404 } 1405 chk.AppendSet(e.ordinal, p.val) 1406 return nil 1407 } 1408 1409 func (e *maxMin4Set) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 1410 p := (*partialResult4MaxMinSet)(pr) 1411 for _, event := range rowsInGroup { 1412 d, err := e.args[0].Eval(event) 1413 if err != nil { 1414 return memDelta, err 1415 } 1416 if d.IsNull() { 1417 continue 1418 } 1419 if p.isNull { 1420 p.val = d.GetMysqlSet().Copy() 1421 memDelta += int64(len(d.GetMysqlSet().Name)) 1422 p.isNull = false 1423 continue 1424 } 1425 s := d.GetMysqlSet() 1426 if e.isMax && s.Value > p.val.Value || !e.isMax && s.Value < p.val.Value { 1427 oldMem := len(p.val.Name) 1428 newMem := len(s.Name) 1429 memDelta += int64(newMem - oldMem) 1430 p.val = s.Copy() 1431 } 1432 } 1433 return memDelta, nil 1434 } 1435 1436 func (e *maxMin4Set) MergePartialResult(sctx stochastikctx.Context, src, dst PartialResult) (memDelta int64, err error) { 1437 p1, p2 := (*partialResult4MaxMinSet)(src), (*partialResult4MaxMinSet)(dst) 1438 if p1.isNull { 1439 return 0, nil 1440 } 1441 if p2.isNull { 1442 *p2 = *p1 1443 return 0, nil 1444 } 1445 if e.isMax && p1.val.Value > p2.val.Value || !e.isMax && p1.val.Value < p2.val.Value { 1446 p2.val, p2.isNull = p1.val, false 1447 } 1448 return 0, nil 1449 }