github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/interlock/aggfuncs/func_avg.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/cznic/mathutil"
    20  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    21  	"github.com/whtcorpsinc/milevadb/stochastikctx"
    22  	"github.com/whtcorpsinc/milevadb/types"
    23  	"github.com/whtcorpsinc/milevadb/soliton/chunk"
    24  	"github.com/whtcorpsinc/milevadb/soliton/replog"
    25  	"github.com/whtcorpsinc/milevadb/soliton/set"
    26  )
    27  
    28  const (
    29  	// DefPartialResult4AvgDecimalSize is the size of partialResult4AvgDecimal
    30  	DefPartialResult4AvgDecimalSize = int64(unsafe.Sizeof(partialResult4AvgDecimal{}))
    31  	// DefPartialResult4AvgDistinctDecimalSize is the size of partialResult4AvgDistinctDecimal
    32  	DefPartialResult4AvgDistinctDecimalSize = int64(unsafe.Sizeof(partialResult4AvgDistinctDecimal{}))
    33  	// DefPartialResult4AvgFloat64Size is the size of partialResult4AvgFloat64
    34  	DefPartialResult4AvgFloat64Size = int64(unsafe.Sizeof(partialResult4AvgFloat64{}))
    35  	// DefPartialResult4AvgDistinctFloat64Size is the size of partialResult4AvgDistinctFloat64
    36  	DefPartialResult4AvgDistinctFloat64Size = int64(unsafe.Sizeof(partialResult4AvgDistinctFloat64{}))
    37  )
    38  
    39  // All the following avg function implementations return the decimal result,
    40  // which causetstore the partial results in "partialResult4AvgDecimal".
    41  //
    42  // "baseAvgDecimal" is wrapped by:
    43  // - "avgOriginal4Decimal"
    44  // - "avgPartial4Decimal"
    45  type baseAvgDecimal struct {
    46  	baseAggFunc
    47  }
    48  
    49  type partialResult4AvgDecimal struct {
    50  	sum   types.MyDecimal
    51  	count int64
    52  }
    53  
    54  func (e *baseAvgDecimal) AllocPartialResult() (pr PartialResult, memDelta int64) {
    55  	return PartialResult(&partialResult4AvgDecimal{}), DefPartialResult4AvgDecimalSize
    56  }
    57  
    58  func (e *baseAvgDecimal) ResetPartialResult(pr PartialResult) {
    59  	p := (*partialResult4AvgDecimal)(pr)
    60  	p.sum = *types.NewDecFromInt(0)
    61  	p.count = int64(0)
    62  }
    63  
    64  func (e *baseAvgDecimal) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error {
    65  	p := (*partialResult4AvgDecimal)(pr)
    66  	if p.count == 0 {
    67  		chk.AppendNull(e.ordinal)
    68  		return nil
    69  	}
    70  	decimalCount := types.NewDecFromInt(p.count)
    71  	finalResult := new(types.MyDecimal)
    72  	err := types.DecimalDiv(&p.sum, decimalCount, finalResult, types.DivFracIncr)
    73  	if err != nil {
    74  		return err
    75  	}
    76  	// Make the decimal be the result of type inferring.
    77  	frac := e.args[0].GetType().Decimal
    78  	if len(e.args) == 2 {
    79  		frac = e.args[1].GetType().Decimal
    80  	}
    81  	if frac == -1 {
    82  		frac = allegrosql.MaxDecimalScale
    83  	}
    84  	err = finalResult.Round(finalResult, mathutil.Min(frac, allegrosql.MaxDecimalScale), types.ModeHalfEven)
    85  	if err != nil {
    86  		return err
    87  	}
    88  	chk.AppendMyDecimal(e.ordinal, finalResult)
    89  	return nil
    90  }
    91  
    92  type avgOriginal4Decimal struct {
    93  	baseAvgDecimal
    94  }
    95  
    96  func (e *avgOriginal4Decimal) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) {
    97  	p := (*partialResult4AvgDecimal)(pr)
    98  	for _, event := range rowsInGroup {
    99  		input, isNull, err := e.args[0].EvalDecimal(sctx, event)
   100  		if err != nil {
   101  			return 0, err
   102  		}
   103  		if isNull {
   104  			continue
   105  		}
   106  
   107  		newSum := new(types.MyDecimal)
   108  		err = types.DecimalAdd(&p.sum, input, newSum)
   109  		if err != nil {
   110  			return 0, err
   111  		}
   112  		p.sum = *newSum
   113  		p.count++
   114  	}
   115  	return 0, nil
   116  }
   117  
   118  func (e *avgOriginal4Decimal) Slide(sctx stochastikctx.Context, rows []chunk.Event, lastStart, lastEnd uint64, shiftStart, shiftEnd uint64, pr PartialResult) error {
   119  	p := (*partialResult4AvgDecimal)(pr)
   120  	for i := uint64(0); i < shiftEnd; i++ {
   121  		input, isNull, err := e.args[0].EvalDecimal(sctx, rows[lastEnd+i])
   122  		if err != nil {
   123  			return err
   124  		}
   125  		if isNull {
   126  			continue
   127  		}
   128  		newSum := new(types.MyDecimal)
   129  		err = types.DecimalAdd(&p.sum, input, newSum)
   130  		if err != nil {
   131  			return err
   132  		}
   133  		p.sum = *newSum
   134  		p.count++
   135  	}
   136  	for i := uint64(0); i < shiftStart; i++ {
   137  		input, isNull, err := e.args[0].EvalDecimal(sctx, rows[lastStart+i])
   138  		if err != nil {
   139  			return err
   140  		}
   141  		if isNull {
   142  			continue
   143  		}
   144  		newSum := new(types.MyDecimal)
   145  		err = types.DecimalSub(&p.sum, input, newSum)
   146  		if err != nil {
   147  			return err
   148  		}
   149  		p.sum = *newSum
   150  		p.count--
   151  	}
   152  	return nil
   153  }
   154  
   155  type avgPartial4Decimal struct {
   156  	baseAvgDecimal
   157  }
   158  
   159  func (e *avgPartial4Decimal) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) {
   160  	p := (*partialResult4AvgDecimal)(pr)
   161  	for _, event := range rowsInGroup {
   162  		inputSum, isNull, err := e.args[1].EvalDecimal(sctx, event)
   163  		if err != nil {
   164  			return 0, err
   165  		}
   166  		if isNull {
   167  			continue
   168  		}
   169  
   170  		inputCount, isNull, err := e.args[0].EvalInt(sctx, event)
   171  		if err != nil {
   172  			return 0, err
   173  		}
   174  		if isNull {
   175  			continue
   176  		}
   177  
   178  		newSum := new(types.MyDecimal)
   179  		err = types.DecimalAdd(&p.sum, inputSum, newSum)
   180  		if err != nil {
   181  			return 0, err
   182  		}
   183  		p.sum = *newSum
   184  		p.count += inputCount
   185  	}
   186  	return 0, nil
   187  }
   188  
   189  func (e *avgPartial4Decimal) MergePartialResult(sctx stochastikctx.Context, src, dst PartialResult) (memDelta int64, err error) {
   190  	p1, p2 := (*partialResult4AvgDecimal)(src), (*partialResult4AvgDecimal)(dst)
   191  	if p1.count == 0 {
   192  		return 0, nil
   193  	}
   194  	newSum := new(types.MyDecimal)
   195  	err = types.DecimalAdd(&p1.sum, &p2.sum, newSum)
   196  	if err != nil {
   197  		return 0, err
   198  	}
   199  	p2.sum = *newSum
   200  	p2.count += p1.count
   201  	return 0, nil
   202  }
   203  
   204  type partialResult4AvgDistinctDecimal struct {
   205  	partialResult4AvgDecimal
   206  	valSet set.StringSet
   207  }
   208  
   209  type avgOriginal4DistinctDecimal struct {
   210  	baseAggFunc
   211  }
   212  
   213  func (e *avgOriginal4DistinctDecimal) AllocPartialResult() (pr PartialResult, memDelta int64) {
   214  	p := &partialResult4AvgDistinctDecimal{
   215  		valSet: set.NewStringSet(),
   216  	}
   217  	return PartialResult(p), DefPartialResult4AvgDistinctDecimalSize
   218  }
   219  
   220  func (e *avgOriginal4DistinctDecimal) ResetPartialResult(pr PartialResult) {
   221  	p := (*partialResult4AvgDistinctDecimal)(pr)
   222  	p.sum = *types.NewDecFromInt(0)
   223  	p.count = int64(0)
   224  	p.valSet = set.NewStringSet()
   225  }
   226  
   227  func (e *avgOriginal4DistinctDecimal) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) {
   228  	p := (*partialResult4AvgDistinctDecimal)(pr)
   229  	for _, event := range rowsInGroup {
   230  		input, isNull, err := e.args[0].EvalDecimal(sctx, event)
   231  		if err != nil {
   232  			return memDelta, err
   233  		}
   234  		if isNull {
   235  			continue
   236  		}
   237  		hash, err := input.ToHashKey()
   238  		if err != nil {
   239  			return memDelta, err
   240  		}
   241  		decStr := string(replog.String(hash))
   242  		if p.valSet.Exist(decStr) {
   243  			continue
   244  		}
   245  		p.valSet.Insert(decStr)
   246  		memDelta += int64(len(decStr))
   247  		newSum := new(types.MyDecimal)
   248  		err = types.DecimalAdd(&p.sum, input, newSum)
   249  		if err != nil {
   250  			return memDelta, err
   251  		}
   252  		p.sum = *newSum
   253  		p.count++
   254  	}
   255  	return memDelta, nil
   256  }
   257  
   258  func (e *avgOriginal4DistinctDecimal) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error {
   259  	p := (*partialResult4AvgDistinctDecimal)(pr)
   260  	if p.count == 0 {
   261  		chk.AppendNull(e.ordinal)
   262  		return nil
   263  	}
   264  	decimalCount := types.NewDecFromInt(p.count)
   265  	finalResult := new(types.MyDecimal)
   266  	err := types.DecimalDiv(&p.sum, decimalCount, finalResult, types.DivFracIncr)
   267  	if err != nil {
   268  		return err
   269  	}
   270  	// Make the decimal be the result of type inferring.
   271  	frac := e.args[0].GetType().Decimal
   272  	if frac == -1 {
   273  		frac = allegrosql.MaxDecimalScale
   274  	}
   275  	err = finalResult.Round(finalResult, mathutil.Min(frac, allegrosql.MaxDecimalScale), types.ModeHalfEven)
   276  	if err != nil {
   277  		return err
   278  	}
   279  	chk.AppendMyDecimal(e.ordinal, finalResult)
   280  	return nil
   281  }
   282  
   283  // All the following avg function implementations return the float64 result,
   284  // which causetstore the partial results in "partialResult4AvgFloat64".
   285  //
   286  // "baseAvgFloat64" is wrapped by:
   287  // - "avgOriginal4Float64"
   288  // - "avgPartial4Float64"
   289  type baseAvgFloat64 struct {
   290  	baseAggFunc
   291  }
   292  
   293  type partialResult4AvgFloat64 struct {
   294  	sum   float64
   295  	count int64
   296  }
   297  
   298  func (e *baseAvgFloat64) AllocPartialResult() (pr PartialResult, memDelta int64) {
   299  	return (PartialResult)(&partialResult4AvgFloat64{}), DefPartialResult4AvgFloat64Size
   300  }
   301  
   302  func (e *baseAvgFloat64) ResetPartialResult(pr PartialResult) {
   303  	p := (*partialResult4AvgFloat64)(pr)
   304  	p.sum = 0
   305  	p.count = 0
   306  }
   307  
   308  func (e *baseAvgFloat64) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error {
   309  	p := (*partialResult4AvgFloat64)(pr)
   310  	if p.count == 0 {
   311  		chk.AppendNull(e.ordinal)
   312  	} else {
   313  		chk.AppendFloat64(e.ordinal, p.sum/float64(p.count))
   314  	}
   315  	return nil
   316  }
   317  
   318  type avgOriginal4Float64HighPrecision struct {
   319  	baseAvgFloat64
   320  }
   321  
   322  func (e *avgOriginal4Float64HighPrecision) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) {
   323  	p := (*partialResult4AvgFloat64)(pr)
   324  	for _, event := range rowsInGroup {
   325  		input, isNull, err := e.args[0].EvalReal(sctx, event)
   326  		if err != nil {
   327  			return 0, err
   328  		}
   329  		if isNull {
   330  			continue
   331  		}
   332  
   333  		p.sum += input
   334  		p.count++
   335  	}
   336  	return 0, nil
   337  }
   338  
   339  type avgOriginal4Float64 struct {
   340  	avgOriginal4Float64HighPrecision
   341  }
   342  
   343  func (e *avgOriginal4Float64) Slide(sctx stochastikctx.Context, rows []chunk.Event, lastStart, lastEnd uint64, shiftStart, shiftEnd uint64, pr PartialResult) error {
   344  	p := (*partialResult4AvgFloat64)(pr)
   345  	for i := uint64(0); i < shiftEnd; i++ {
   346  		input, isNull, err := e.args[0].EvalReal(sctx, rows[lastEnd+i])
   347  		if err != nil {
   348  			return err
   349  		}
   350  		if isNull {
   351  			continue
   352  		}
   353  		p.sum += input
   354  		p.count++
   355  	}
   356  	for i := uint64(0); i < shiftStart; i++ {
   357  		input, isNull, err := e.args[0].EvalReal(sctx, rows[lastStart+i])
   358  		if err != nil {
   359  			return err
   360  		}
   361  		if isNull {
   362  			continue
   363  		}
   364  		p.sum -= input
   365  		p.count--
   366  	}
   367  	return nil
   368  }
   369  
   370  type avgPartial4Float64 struct {
   371  	baseAvgFloat64
   372  }
   373  
   374  func (e *avgPartial4Float64) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) {
   375  	p := (*partialResult4AvgFloat64)(pr)
   376  	for _, event := range rowsInGroup {
   377  		inputSum, isNull, err := e.args[1].EvalReal(sctx, event)
   378  		if err != nil {
   379  			return 0, err
   380  		}
   381  		if isNull {
   382  			continue
   383  		}
   384  
   385  		inputCount, isNull, err := e.args[0].EvalInt(sctx, event)
   386  		if err != nil {
   387  			return 0, err
   388  		}
   389  		if isNull {
   390  			continue
   391  		}
   392  		p.sum += inputSum
   393  		p.count += inputCount
   394  	}
   395  	return 0, nil
   396  }
   397  
   398  func (e *avgPartial4Float64) MergePartialResult(sctx stochastikctx.Context, src, dst PartialResult) (memDelta int64, err error) {
   399  	p1, p2 := (*partialResult4AvgFloat64)(src), (*partialResult4AvgFloat64)(dst)
   400  	p2.sum += p1.sum
   401  	p2.count += p1.count
   402  	return 0, nil
   403  }
   404  
   405  type partialResult4AvgDistinctFloat64 struct {
   406  	partialResult4AvgFloat64
   407  	valSet set.Float64Set
   408  }
   409  
   410  type avgOriginal4DistinctFloat64 struct {
   411  	baseAggFunc
   412  }
   413  
   414  func (e *avgOriginal4DistinctFloat64) AllocPartialResult() (pr PartialResult, memDelta int64) {
   415  	p := &partialResult4AvgDistinctFloat64{
   416  		valSet: set.NewFloat64Set(),
   417  	}
   418  	return PartialResult(p), DefPartialResult4AvgDistinctFloat64Size
   419  }
   420  
   421  func (e *avgOriginal4DistinctFloat64) ResetPartialResult(pr PartialResult) {
   422  	p := (*partialResult4AvgDistinctFloat64)(pr)
   423  	p.sum = float64(0)
   424  	p.count = int64(0)
   425  	p.valSet = set.NewFloat64Set()
   426  }
   427  
   428  func (e *avgOriginal4DistinctFloat64) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) {
   429  	p := (*partialResult4AvgDistinctFloat64)(pr)
   430  	for _, event := range rowsInGroup {
   431  		input, isNull, err := e.args[0].EvalReal(sctx, event)
   432  		if err != nil {
   433  			return memDelta, err
   434  		}
   435  		if isNull || p.valSet.Exist(input) {
   436  			continue
   437  		}
   438  
   439  		p.sum += input
   440  		p.count++
   441  		p.valSet.Insert(input)
   442  		memDelta += DefFloat64Size
   443  	}
   444  	return memDelta, nil
   445  }
   446  
   447  func (e *avgOriginal4DistinctFloat64) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error {
   448  	p := (*partialResult4AvgDistinctFloat64)(pr)
   449  	if p.count == 0 {
   450  		chk.AppendNull(e.ordinal)
   451  		return nil
   452  	}
   453  	chk.AppendFloat64(e.ordinal, p.sum/float64(p.count))
   454  	return nil
   455  }