github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/aggregation/window_functions.go (about)

     1  // Copyright 2022 DoltHub, 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  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package aggregation
    16  
    17  import (
    18  	"sort"
    19  	"strings"
    20  
    21  	"github.com/dolthub/go-mysql-server/sql"
    22  	"github.com/dolthub/go-mysql-server/sql/expression"
    23  	"github.com/dolthub/go-mysql-server/sql/types"
    24  )
    25  
    26  var _ sql.WindowFunction = (*SumAgg)(nil)
    27  var _ sql.WindowFunction = (*MaxAgg)(nil)
    28  var _ sql.WindowFunction = (*MinAgg)(nil)
    29  var _ sql.WindowFunction = (*AvgAgg)(nil)
    30  var _ sql.WindowFunction = (*LastAgg)(nil)
    31  var _ sql.WindowFunction = (*FirstAgg)(nil)
    32  var _ sql.WindowFunction = (*CountAgg)(nil)
    33  var _ sql.WindowFunction = (*GroupConcatAgg)(nil)
    34  var _ sql.WindowFunction = (*WindowedJSONArrayAgg)(nil)
    35  var _ sql.WindowFunction = (*WindowedJSONObjectAgg)(nil)
    36  
    37  var _ sql.WindowFunction = (*PercentRank)(nil)
    38  var _ sql.WindowFunction = (*RowNumber)(nil)
    39  var _ sql.WindowFunction = (*Lag)(nil)
    40  var _ sql.WindowFunction = (*Lead)(nil)
    41  
    42  type AnyValueAgg struct {
    43  	expr   sql.Expression
    44  	framer sql.WindowFramer
    45  }
    46  
    47  func NewAnyValueAgg(e sql.Expression) *AnyValueAgg {
    48  	return &AnyValueAgg{
    49  		expr: e,
    50  	}
    51  }
    52  
    53  func (a *AnyValueAgg) WithWindow(w *sql.WindowDefinition) (sql.WindowFunction, error) {
    54  	na := *a
    55  	if w.Frame != nil {
    56  		framer, err := w.Frame.NewFramer(w)
    57  		if err != nil {
    58  			return nil, err
    59  		}
    60  		na.framer = framer
    61  	}
    62  	return &na, nil
    63  }
    64  
    65  func (a *AnyValueAgg) Dispose() {
    66  	expression.Dispose(a.expr)
    67  }
    68  
    69  // DefaultFramer returns a NewUnboundedPrecedingToCurrentRowFramer
    70  func (a *AnyValueAgg) DefaultFramer() sql.WindowFramer {
    71  	if a.framer != nil {
    72  		return a.framer
    73  	}
    74  	return NewUnboundedPrecedingToCurrentRowFramer()
    75  }
    76  
    77  func (a *AnyValueAgg) StartPartition(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) error {
    78  	a.Dispose()
    79  	return nil
    80  }
    81  
    82  func (a *AnyValueAgg) Compute(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) interface{} {
    83  	for i := interval.Start; i < interval.End; i++ {
    84  		row := buf[i]
    85  		v, err := a.expr.Eval(ctx, row)
    86  		if err != nil {
    87  			return err
    88  		}
    89  		return v
    90  	}
    91  	return nil
    92  }
    93  
    94  type SumAgg struct {
    95  	partitionStart, partitionEnd int
    96  	expr                         sql.Expression
    97  	framer                       sql.WindowFramer
    98  
    99  	// use prefix sums to quickly calculate arbitrary frame sum within partition
   100  	prefixSum []float64
   101  }
   102  
   103  func NewSumAgg(e sql.Expression) *SumAgg {
   104  	return &SumAgg{
   105  		partitionStart: -1,
   106  		partitionEnd:   -1,
   107  		expr:           e,
   108  	}
   109  }
   110  
   111  func (a *SumAgg) WithWindow(w *sql.WindowDefinition) (sql.WindowFunction, error) {
   112  	na := *a
   113  	if w.Frame != nil {
   114  		framer, err := w.Frame.NewFramer(w)
   115  		if err != nil {
   116  			return nil, err
   117  		}
   118  		na.framer = framer
   119  	}
   120  	return &na, nil
   121  }
   122  
   123  func (a *SumAgg) Dispose() {
   124  	expression.Dispose(a.expr)
   125  }
   126  
   127  // DefaultFramer returns a NewUnboundedPrecedingToCurrentRowFramer
   128  func (a *SumAgg) DefaultFramer() sql.WindowFramer {
   129  	if a.framer != nil {
   130  		return a.framer
   131  	}
   132  	return NewUnboundedPrecedingToCurrentRowFramer()
   133  }
   134  
   135  func (a *SumAgg) StartPartition(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) error {
   136  	a.partitionStart, a.partitionEnd = interval.Start, interval.End
   137  	a.Dispose()
   138  	var err error
   139  	a.prefixSum, _, err = floatPrefixSum(ctx, interval, buf, a.expr)
   140  	return err
   141  }
   142  
   143  func (a *SumAgg) NewSlidingFrameInterval(added, dropped sql.WindowInterval) {
   144  	panic("sliding window interface not implemented yet")
   145  }
   146  
   147  func (a *SumAgg) Compute(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) interface{} {
   148  	if interval.End-interval.Start < 1 {
   149  		return nil
   150  	}
   151  	return computePrefixSum(interval, a.partitionStart, a.prefixSum)
   152  }
   153  
   154  func floatPrefixSum(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer, e sql.Expression) ([]float64, []int, error) {
   155  	intervalLen := interval.End - interval.Start
   156  	sums := make([]float64, intervalLen)
   157  	nulls := make([]int, intervalLen)
   158  	var last float64
   159  	var nullCnt int
   160  	for i := 0; i < intervalLen; i++ {
   161  		v, err := e.Eval(ctx, buf[interval.Start+i])
   162  		if err != nil {
   163  			continue
   164  		}
   165  		val, _, err := types.Float64.Convert(v)
   166  		if err != nil || val == nil {
   167  			val = float64(0)
   168  			nullCnt += 1
   169  		}
   170  		last += val.(float64)
   171  		sums[i] = last
   172  		nulls[i] = nullCnt
   173  	}
   174  	return sums, nulls, nil
   175  }
   176  
   177  func computePrefixSum(interval sql.WindowInterval, partitionStart int, prefixSum []float64) float64 {
   178  	startIdx := interval.Start - partitionStart - 1
   179  	endIdx := interval.End - partitionStart - 1
   180  
   181  	var sum float64
   182  	if endIdx >= 0 {
   183  		sum = prefixSum[endIdx]
   184  	}
   185  	if startIdx >= 0 {
   186  		sum -= prefixSum[startIdx]
   187  	}
   188  	return sum
   189  }
   190  
   191  type AvgAgg struct {
   192  	partitionStart int
   193  	partitionEnd   int
   194  	expr           sql.Expression
   195  	framer         sql.WindowFramer
   196  
   197  	// use prefix sums to quickly calculate arbitrary frame sum within partition
   198  	prefixSum []float64
   199  	// exclude nulls in average denominator
   200  	nullCnt []int
   201  }
   202  
   203  func NewAvgAgg(e sql.Expression) *AvgAgg {
   204  	return &AvgAgg{
   205  		expr: e,
   206  	}
   207  }
   208  
   209  func (a *AvgAgg) WithWindow(w *sql.WindowDefinition) (sql.WindowFunction, error) {
   210  	na := *a
   211  	if w.Frame != nil {
   212  		framer, err := w.Frame.NewFramer(w)
   213  		if err != nil {
   214  			return nil, err
   215  		}
   216  		na.framer = framer
   217  	}
   218  	return &na, nil
   219  }
   220  
   221  func (a *AvgAgg) Dispose() {
   222  	expression.Dispose(a.expr)
   223  }
   224  
   225  // DefaultFramer returns a NewUnboundedPrecedingToCurrentRowFramer
   226  func (a *AvgAgg) DefaultFramer() sql.WindowFramer {
   227  	if a.framer != nil {
   228  		return a.framer
   229  	}
   230  	return NewUnboundedPrecedingToCurrentRowFramer()
   231  }
   232  
   233  func (a *AvgAgg) StartPartition(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) error {
   234  	a.Dispose()
   235  	a.partitionStart = interval.Start
   236  	a.partitionEnd = interval.End
   237  	var err error
   238  	a.prefixSum, a.nullCnt, err = floatPrefixSum(ctx, interval, buf, a.expr)
   239  	return err
   240  }
   241  
   242  func (a *AvgAgg) NewSlidingFrameInterval(added, dropped sql.WindowInterval) {
   243  	panic("sliding window interface not implemented yet")
   244  }
   245  
   246  func (a *AvgAgg) Compute(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) interface{} {
   247  	startIdx := interval.Start - a.partitionStart - 1
   248  	endIdx := interval.End - a.partitionStart - 1
   249  
   250  	var nonNullCnt int
   251  	if endIdx >= 0 {
   252  		nonNullCnt += endIdx + 1
   253  		nonNullCnt -= a.nullCnt[endIdx]
   254  	}
   255  	if startIdx >= 0 {
   256  		nonNullCnt -= startIdx + 1
   257  		nonNullCnt += a.nullCnt[startIdx]
   258  	}
   259  	return computePrefixSum(interval, a.partitionStart, a.prefixSum) / float64(nonNullCnt)
   260  }
   261  
   262  type BitAndAgg struct {
   263  	expr   sql.Expression
   264  	framer sql.WindowFramer
   265  }
   266  
   267  func NewBitAndAgg(e sql.Expression) *BitAndAgg {
   268  	return &BitAndAgg{
   269  		expr: e,
   270  	}
   271  }
   272  
   273  func (b *BitAndAgg) WithWindow(w *sql.WindowDefinition) (sql.WindowFunction, error) {
   274  	na := *b
   275  	if w.Frame != nil {
   276  		framer, err := w.Frame.NewFramer(w)
   277  		if err != nil {
   278  			return nil, err
   279  		}
   280  		na.framer = framer
   281  	}
   282  	return &na, nil
   283  }
   284  
   285  func (b *BitAndAgg) Dispose() {
   286  	expression.Dispose(b.expr)
   287  }
   288  
   289  // DefaultFramer returns a NewUnboundedPrecedingToCurrentRowFramer
   290  func (b *BitAndAgg) DefaultFramer() sql.WindowFramer {
   291  	if b.framer != nil {
   292  		return b.framer
   293  	}
   294  	return NewPartitionFramer()
   295  }
   296  
   297  func (b *BitAndAgg) StartPartition(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) error {
   298  	b.Dispose()
   299  	return nil
   300  }
   301  
   302  func (b *BitAndAgg) NewSlidingFrameInterval(added, dropped sql.WindowInterval) {
   303  	panic("sliding window interface not implemented yet")
   304  }
   305  
   306  func (b *BitAndAgg) Compute(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) interface{} {
   307  	res := ^uint64(0) // bitwise not xor, so 0xffff...
   308  	for i := interval.Start; i < interval.End; i++ {
   309  		row := buf[i]
   310  		v, err := b.expr.Eval(ctx, row)
   311  		if err != nil {
   312  			return err
   313  		}
   314  
   315  		if v == nil {
   316  			continue
   317  		}
   318  
   319  		val, _, err := types.Uint64.Convert(v)
   320  		if err != nil {
   321  			return 0
   322  		}
   323  
   324  		res &= val.(uint64)
   325  	}
   326  	return res
   327  }
   328  
   329  type BitOrAgg struct {
   330  	expr   sql.Expression
   331  	framer sql.WindowFramer
   332  }
   333  
   334  func NewBitOrAgg(e sql.Expression) *BitOrAgg {
   335  	return &BitOrAgg{
   336  		expr: e,
   337  	}
   338  }
   339  
   340  func (b *BitOrAgg) WithWindow(w *sql.WindowDefinition) (sql.WindowFunction, error) {
   341  	na := *b
   342  	if w.Frame != nil {
   343  		framer, err := w.Frame.NewFramer(w)
   344  		if err != nil {
   345  			return nil, err
   346  		}
   347  		na.framer = framer
   348  	}
   349  	return &na, nil
   350  }
   351  
   352  func (b *BitOrAgg) Dispose() {
   353  	expression.Dispose(b.expr)
   354  }
   355  
   356  // DefaultFramer returns a NewUnboundedPrecedingToCurrentRowFramer
   357  func (b *BitOrAgg) DefaultFramer() sql.WindowFramer {
   358  	if b.framer != nil {
   359  		return b.framer
   360  	}
   361  	return NewPartitionFramer()
   362  }
   363  
   364  func (b *BitOrAgg) StartPartition(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) error {
   365  	b.Dispose()
   366  	return nil
   367  }
   368  
   369  func (b *BitOrAgg) NewSlidingFrameInterval(added, dropped sql.WindowInterval) {
   370  	panic("sliding window interface not implemented yet")
   371  }
   372  
   373  func (b *BitOrAgg) Compute(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) interface{} {
   374  	var res uint64
   375  	for i := interval.Start; i < interval.End; i++ {
   376  		row := buf[i]
   377  		v, err := b.expr.Eval(ctx, row)
   378  		if err != nil {
   379  			return err
   380  		}
   381  
   382  		if v == nil {
   383  			continue
   384  		}
   385  
   386  		val, _, err := types.Uint64.Convert(v)
   387  		if err != nil {
   388  			return 0
   389  		}
   390  
   391  		res |= val.(uint64)
   392  	}
   393  	return res
   394  }
   395  
   396  type BitXorAgg struct {
   397  	expr   sql.Expression
   398  	framer sql.WindowFramer
   399  }
   400  
   401  func NewBitXorAgg(e sql.Expression) *BitXorAgg {
   402  	return &BitXorAgg{
   403  		expr: e,
   404  	}
   405  }
   406  
   407  func (b *BitXorAgg) WithWindow(w *sql.WindowDefinition) (sql.WindowFunction, error) {
   408  	na := *b
   409  	if w.Frame != nil {
   410  		framer, err := w.Frame.NewFramer(w)
   411  		if err != nil {
   412  			return nil, err
   413  		}
   414  		na.framer = framer
   415  	}
   416  	return &na, nil
   417  }
   418  
   419  func (b *BitXorAgg) Dispose() {
   420  	expression.Dispose(b.expr)
   421  }
   422  
   423  // DefaultFramer returns a NewUnboundedPrecedingToCurrentRowFramer
   424  func (b *BitXorAgg) DefaultFramer() sql.WindowFramer {
   425  	if b.framer != nil {
   426  		return b.framer
   427  	}
   428  	return NewPartitionFramer()
   429  }
   430  
   431  func (b *BitXorAgg) StartPartition(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) error {
   432  	b.Dispose()
   433  	return nil
   434  }
   435  
   436  func (b *BitXorAgg) NewSlidingFrameInterval(added, dropped sql.WindowInterval) {
   437  	panic("sliding window interface not implemented yet")
   438  }
   439  
   440  func (b *BitXorAgg) Compute(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) interface{} {
   441  	var res uint64
   442  	for i := interval.Start; i < interval.End; i++ {
   443  		row := buf[i]
   444  		v, err := b.expr.Eval(ctx, row)
   445  		if err != nil {
   446  			return err
   447  		}
   448  
   449  		if v == nil {
   450  			continue
   451  		}
   452  
   453  		// TODO: handle strings
   454  		val, _, err := types.Uint64.Convert(v)
   455  		if err != nil {
   456  			return 0
   457  		}
   458  
   459  		res ^= val.(uint64)
   460  	}
   461  	return res
   462  }
   463  
   464  type MaxAgg struct {
   465  	expr   sql.Expression
   466  	framer sql.WindowFramer
   467  }
   468  
   469  func NewMaxAgg(e sql.Expression) *MaxAgg {
   470  	return &MaxAgg{
   471  		expr: e,
   472  	}
   473  }
   474  
   475  func (a *MaxAgg) WithWindow(w *sql.WindowDefinition) (sql.WindowFunction, error) {
   476  	na := *a
   477  	if w.Frame != nil {
   478  		framer, err := w.Frame.NewFramer(w)
   479  		if err != nil {
   480  			return nil, err
   481  		}
   482  		na.framer = framer
   483  	}
   484  	return &na, nil
   485  }
   486  
   487  func (a *MaxAgg) Dispose() {
   488  	expression.Dispose(a.expr)
   489  }
   490  
   491  // DefaultFramer returns a NewPartitionFramer
   492  func (a *MaxAgg) DefaultFramer() sql.WindowFramer {
   493  	if a.framer != nil {
   494  		return a.framer
   495  	}
   496  	return NewPartitionFramer()
   497  }
   498  
   499  func (a *MaxAgg) StartPartition(ctx *sql.Context, interval sql.WindowInterval, buffer sql.WindowBuffer) error {
   500  	a.Dispose()
   501  	return nil
   502  }
   503  
   504  func (a *MaxAgg) NewSlidingFrameInterval(added, dropped sql.WindowInterval) {
   505  	panic("sliding window interface not implemented yet")
   506  }
   507  
   508  func (a *MaxAgg) Compute(ctx *sql.Context, interval sql.WindowInterval, buffer sql.WindowBuffer) interface{} {
   509  	var max interface{}
   510  	for i := interval.Start; i < interval.End; i++ {
   511  		row := buffer[i]
   512  		v, err := a.expr.Eval(ctx, row)
   513  		if err != nil {
   514  			return err
   515  		}
   516  
   517  		if v == nil {
   518  			continue
   519  		}
   520  
   521  		if max == nil {
   522  			max = v
   523  		}
   524  
   525  		cmp, err := a.expr.Type().Compare(v, max)
   526  		if err != nil {
   527  			return err
   528  		}
   529  		if cmp == 1 {
   530  			max = v
   531  		}
   532  	}
   533  	return max
   534  }
   535  
   536  type MinAgg struct {
   537  	expr   sql.Expression
   538  	framer sql.WindowFramer
   539  }
   540  
   541  func NewMinAgg(e sql.Expression) *MinAgg {
   542  	return &MinAgg{
   543  		expr: e,
   544  	}
   545  }
   546  
   547  func (a *MinAgg) WithWindow(w *sql.WindowDefinition) (sql.WindowFunction, error) {
   548  	na := *a
   549  	if w.Frame != nil {
   550  		framer, err := w.Frame.NewFramer(w)
   551  		if err != nil {
   552  			return nil, err
   553  		}
   554  		na.framer = framer
   555  	}
   556  	return &na, nil
   557  }
   558  
   559  func (a *MinAgg) Dispose() {
   560  	expression.Dispose(a.expr)
   561  }
   562  
   563  // DefaultFramer returns a NewUnboundedPrecedingToCurrentRowFramer
   564  func (a *MinAgg) DefaultFramer() sql.WindowFramer {
   565  	if a.framer != nil {
   566  		return a.framer
   567  	}
   568  	return NewUnboundedPrecedingToCurrentRowFramer()
   569  }
   570  
   571  func (a *MinAgg) StartPartition(ctx *sql.Context, interval sql.WindowInterval, buffer sql.WindowBuffer) error {
   572  	a.Dispose()
   573  	return nil
   574  }
   575  
   576  func (a *MinAgg) NewSlidingFrameInterval(added, dropped sql.WindowInterval) {
   577  	panic("sliding window interface not implemented yet")
   578  }
   579  
   580  func (a *MinAgg) Compute(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) interface{} {
   581  	var min interface{}
   582  	for _, row := range buf[interval.Start:interval.End] {
   583  		v, err := a.expr.Eval(ctx, row)
   584  		if err != nil {
   585  			return err
   586  		}
   587  
   588  		if v == nil {
   589  			continue
   590  		}
   591  
   592  		if min == nil {
   593  			min = v
   594  			continue
   595  		}
   596  
   597  		cmp, err := a.expr.Type().Compare(v, min)
   598  		if err != nil {
   599  			return err
   600  		}
   601  		if cmp == -1 {
   602  			min = v
   603  		}
   604  	}
   605  	return min
   606  }
   607  
   608  type LastAgg struct {
   609  	expr   sql.Expression
   610  	framer sql.WindowFramer
   611  }
   612  
   613  func NewLastAgg(e sql.Expression) *LastAgg {
   614  	return &LastAgg{
   615  		expr: e,
   616  	}
   617  }
   618  
   619  func (a *LastAgg) WithWindow(w *sql.WindowDefinition) (sql.WindowFunction, error) {
   620  	na := *a
   621  	if w != nil && w.Frame != nil {
   622  		framer, err := w.Frame.NewFramer(w)
   623  		if err != nil {
   624  			return nil, err
   625  		}
   626  		na.framer = framer
   627  	}
   628  	return &na, nil
   629  }
   630  
   631  func (a *LastAgg) Dispose() {
   632  	expression.Dispose(a.expr)
   633  }
   634  
   635  // DefaultFramer returns a NewUnboundedPrecedingToCurrentRowFramer
   636  func (a *LastAgg) DefaultFramer() sql.WindowFramer {
   637  	if a.framer != nil {
   638  		return a.framer
   639  	}
   640  	return NewUnboundedPrecedingToCurrentRowFramer()
   641  }
   642  
   643  func (a *LastAgg) StartPartition(ctx *sql.Context, interval sql.WindowInterval, buffer sql.WindowBuffer) error {
   644  	a.Dispose()
   645  	return nil
   646  }
   647  
   648  func (a *LastAgg) NewSlidingFrameInterval(added, dropped sql.WindowInterval) {
   649  	panic("sliding window interface not implemented yet")
   650  }
   651  
   652  func (a *LastAgg) Compute(ctx *sql.Context, interval sql.WindowInterval, buffer sql.WindowBuffer) interface{} {
   653  	if interval.End-interval.Start < 1 {
   654  		return nil
   655  	}
   656  	row := buffer[interval.End-1]
   657  	v, err := a.expr.Eval(ctx, row)
   658  	if err != nil {
   659  		return err
   660  	}
   661  	return v
   662  }
   663  
   664  type FirstAgg struct {
   665  	partitionStart, partitionEnd int
   666  	expr                         sql.Expression
   667  	framer                       sql.WindowFramer
   668  }
   669  
   670  func NewFirstAgg(e sql.Expression) *FirstAgg {
   671  	return &FirstAgg{
   672  		expr: e,
   673  	}
   674  }
   675  
   676  func (a *FirstAgg) WithWindow(w *sql.WindowDefinition) (sql.WindowFunction, error) {
   677  	na := *a
   678  	if w.Frame != nil {
   679  		framer, err := w.Frame.NewFramer(w)
   680  		if err != nil {
   681  			return nil, err
   682  		}
   683  		na.framer = framer
   684  	}
   685  	return &na, nil
   686  }
   687  
   688  func (a *FirstAgg) Dispose() {
   689  	expression.Dispose(a.expr)
   690  }
   691  
   692  // DefaultFramer returns a NewUnboundedPrecedingToCurrentRowFramer
   693  func (a *FirstAgg) DefaultFramer() sql.WindowFramer {
   694  	if a.framer != nil {
   695  		return a.framer
   696  	}
   697  	return NewUnboundedPrecedingToCurrentRowFramer()
   698  }
   699  
   700  func (a *FirstAgg) StartPartition(ctx *sql.Context, interval sql.WindowInterval, buffer sql.WindowBuffer) error {
   701  	a.Dispose()
   702  	a.partitionStart, a.partitionEnd = interval.Start, interval.End
   703  	return nil
   704  }
   705  
   706  func (a *FirstAgg) NewSlidingFrameInterval(added, dropped sql.WindowInterval) {
   707  	panic("sliding window interface not implemented yet")
   708  }
   709  
   710  func (a *FirstAgg) Compute(ctx *sql.Context, interval sql.WindowInterval, buffer sql.WindowBuffer) interface{} {
   711  	if interval.End-interval.Start < 1 {
   712  		return nil
   713  	}
   714  	row := buffer[interval.Start]
   715  	v, err := a.expr.Eval(ctx, row)
   716  	if err != nil {
   717  		return err
   718  	}
   719  	return v
   720  }
   721  
   722  type CountAgg struct {
   723  	partitionStart int
   724  	partitionEnd   int
   725  	expr           sql.Expression
   726  	framer         sql.WindowFramer
   727  
   728  	// use prefix sums to quickly calculate arbitrary a frame's row cnt within partition
   729  	prefixSum []float64
   730  	// orderBy tracks peer group increments
   731  	orderBy []sql.Expression
   732  	// pos increments every iteration
   733  	pos int
   734  	// peerGroup tracks value increments
   735  	peerGroup sql.WindowInterval
   736  }
   737  
   738  func NewCountAgg(e sql.Expression) *CountAgg {
   739  	return &CountAgg{
   740  		partitionStart: -1,
   741  		partitionEnd:   -1,
   742  		expr:           e,
   743  	}
   744  }
   745  
   746  func NewCountDistinctAgg(e sql.Expression) *CountAgg {
   747  	e = expression.NewDistinctExpression(e)
   748  	return &CountAgg{
   749  		partitionStart: -1,
   750  		partitionEnd:   -1,
   751  		expr:           e,
   752  	}
   753  }
   754  
   755  func (a *CountAgg) WithWindow(w *sql.WindowDefinition) (sql.WindowFunction, error) {
   756  	na := *a
   757  	if w.Frame != nil {
   758  		framer, err := w.Frame.NewFramer(w)
   759  		if err != nil {
   760  			return nil, err
   761  		}
   762  		na.framer = framer
   763  		return &na, nil
   764  	}
   765  	if w.OrderBy != nil {
   766  		na.orderBy = w.OrderBy.ToExpressions()
   767  	}
   768  	return &na, nil
   769  }
   770  
   771  func (a *CountAgg) Dispose() {
   772  	expression.Dispose(a.expr)
   773  }
   774  
   775  // DefaultFramer returns a NewPartitionFramer
   776  func (a *CountAgg) DefaultFramer() sql.WindowFramer {
   777  	if a.framer != nil {
   778  		return a.framer
   779  	}
   780  
   781  	if a.orderBy == nil || len(a.orderBy) < 1 {
   782  		return NewPartitionFramer()
   783  	}
   784  
   785  	return &RangeUnboundedPrecedingToCurrentRowFramer{
   786  		rangeFramerBase{
   787  			orderBy:            a.orderBy[0],
   788  			unboundedPreceding: true,
   789  			endCurrentRow:      true,
   790  		},
   791  	}
   792  }
   793  
   794  func (a *CountAgg) StartPartition(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) error {
   795  	a.Dispose()
   796  	a.partitionStart, a.partitionEnd = interval.Start, interval.End
   797  	a.pos = a.partitionStart
   798  	a.peerGroup = sql.WindowInterval{}
   799  	var err error
   800  	a.prefixSum, err = countPrefixSum(ctx, interval, buf, a.expr)
   801  	if err != nil {
   802  		return err
   803  	}
   804  	return nil
   805  }
   806  
   807  func (a *CountAgg) NewSlidingFrameInterval(added, dropped sql.WindowInterval) {
   808  	panic("sliding window interface not implemented yet")
   809  }
   810  
   811  func (a *CountAgg) Compute(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) interface{} {
   812  	a.pos++
   813  	return int64(computePrefixSum(sql.WindowInterval{Start: interval.Start, End: interval.End}, a.partitionStart, a.prefixSum))
   814  }
   815  
   816  func countPrefixSum(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer, expr sql.Expression) ([]float64, error) {
   817  	intervalLen := interval.End - interval.Start
   818  	sums := make([]float64, intervalLen)
   819  	var last float64
   820  	for i := 0; i < intervalLen; i++ {
   821  		row := buf[interval.Start+i]
   822  		var inc bool
   823  		if _, ok := expr.(*expression.Star); ok {
   824  			inc = true
   825  		} else {
   826  			v, err := expr.Eval(ctx, row)
   827  			if v != nil {
   828  				inc = true
   829  			}
   830  
   831  			if err != nil {
   832  				return nil, err
   833  			}
   834  		}
   835  
   836  		if inc {
   837  			last += 1
   838  		}
   839  		sums[i] = last
   840  	}
   841  	return sums, nil
   842  }
   843  
   844  type GroupConcatAgg struct {
   845  	gc     *GroupConcat
   846  	framer sql.WindowFramer
   847  	// hash map to deduplicate values
   848  	// TODO make this more efficient, ideally with sliding window and hashes
   849  	distinct map[string]struct{}
   850  	// original row order used for optional result sorting
   851  	rows []sql.Row
   852  }
   853  
   854  func NewGroupConcatAgg(gc *GroupConcat) *GroupConcatAgg {
   855  	return &GroupConcatAgg{
   856  		gc: gc,
   857  	}
   858  }
   859  
   860  func (a *GroupConcatAgg) WithWindow(w *sql.WindowDefinition) (sql.WindowFunction, error) {
   861  	na := *a
   862  	if w.Frame != nil {
   863  		framer, err := w.Frame.NewFramer(w)
   864  		if err != nil {
   865  			return nil, err
   866  		}
   867  		na.framer = framer
   868  	}
   869  	return &na, nil
   870  }
   871  
   872  func (a *GroupConcatAgg) Dispose() {
   873  	expression.Dispose(a.gc)
   874  }
   875  
   876  // DefaultFramer returns a NewUnboundedPrecedingToCurrentRowFramer
   877  func (a *GroupConcatAgg) DefaultFramer() sql.WindowFramer {
   878  	if a.framer != nil {
   879  		return a.framer
   880  	}
   881  	return NewUnboundedPrecedingToCurrentRowFramer()
   882  }
   883  
   884  func (a *GroupConcatAgg) StartPartition(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) error {
   885  	a.Dispose()
   886  	var err error
   887  	a.rows, a.distinct, err = a.filterToDistinct(ctx, buf[interval.Start:interval.End])
   888  	return err
   889  }
   890  
   891  func (a *GroupConcatAgg) NewSlidingFrameInterval(added, dropped sql.WindowInterval) {
   892  	panic("sliding window interface not implemented yet")
   893  }
   894  
   895  func (a *GroupConcatAgg) Compute(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) interface{} {
   896  	rows := a.rows
   897  
   898  	if len(rows) == 0 {
   899  		return nil
   900  	}
   901  
   902  	// Execute the order operation if it exists.
   903  	if a.gc.sf != nil {
   904  		sorter := &expression.Sorter{
   905  			SortFields: a.gc.sf,
   906  			Rows:       rows,
   907  			Ctx:        ctx,
   908  		}
   909  
   910  		sort.Stable(sorter)
   911  		if sorter.LastError != nil {
   912  			return nil
   913  		}
   914  	}
   915  
   916  	sb := strings.Builder{}
   917  	for i, row := range rows {
   918  		lastIdx := len(row) - 1
   919  		if i == 0 {
   920  			sb.WriteString(row[lastIdx].(string))
   921  		} else {
   922  			sb.WriteString(a.gc.separator)
   923  			sb.WriteString(row[lastIdx].(string))
   924  		}
   925  
   926  		// Don't allow the string to cross maxlen
   927  		if sb.Len() >= a.gc.maxLen {
   928  			break
   929  		}
   930  	}
   931  
   932  	ret := sb.String()
   933  
   934  	// There might be a couple of character differences even if we broke early in the loop
   935  	if len(ret) > a.gc.maxLen {
   936  		ret = ret[:a.gc.maxLen]
   937  	}
   938  
   939  	// Add this to handle any one off errors.
   940  	return ret
   941  }
   942  
   943  func (a *GroupConcatAgg) filterToDistinct(ctx *sql.Context, buf sql.WindowBuffer) ([]sql.Row, map[string]struct{}, error) {
   944  	rows := make([]sql.Row, 0)
   945  	distinct := make(map[string]struct{}, 0)
   946  	for _, row := range buf {
   947  		evalRow, retType, err := evalExprs(ctx, a.gc.selectExprs, row)
   948  		if err != nil {
   949  			return nil, nil, err
   950  		}
   951  
   952  		a.gc.returnType = retType
   953  
   954  		// Skip if this is a null row
   955  		if evalRow == nil {
   956  			continue
   957  		}
   958  
   959  		var v interface{}
   960  		if retType == types.Blob {
   961  			v, _, err = types.Blob.Convert(evalRow[0])
   962  		} else {
   963  			v, _, err = types.LongText.Convert(evalRow[0])
   964  		}
   965  
   966  		if err != nil {
   967  			return nil, nil, err
   968  		}
   969  
   970  		if v == nil {
   971  			continue
   972  		}
   973  
   974  		vs := v.(string)
   975  
   976  		// Get the current array of rows and the map
   977  		// Check if distinct is active if so look at and update our map
   978  		if a.gc.distinct != "" {
   979  			// If this value exists go ahead and return nil
   980  			if _, ok := distinct[vs]; ok {
   981  				continue
   982  			} else {
   983  				distinct[vs] = struct{}{}
   984  			}
   985  		}
   986  
   987  		// Append the current value to the end of the row. We want to preserve the row's original structure for
   988  		// for sort ordering in the final step.
   989  		rows = append(rows, append(row, nil, vs))
   990  	}
   991  	return rows, distinct, nil
   992  }
   993  
   994  type WindowedJSONArrayAgg struct {
   995  	expr   sql.Expression
   996  	framer sql.WindowFramer
   997  }
   998  
   999  func NewJsonArrayAgg(expr sql.Expression) *WindowedJSONArrayAgg {
  1000  	return &WindowedJSONArrayAgg{
  1001  		expr: expr,
  1002  	}
  1003  }
  1004  
  1005  func (a *WindowedJSONArrayAgg) WithWindow(w *sql.WindowDefinition) (sql.WindowFunction, error) {
  1006  	na := *a
  1007  	if w.Frame != nil {
  1008  		framer, err := w.Frame.NewFramer(w)
  1009  		if err != nil {
  1010  			return nil, err
  1011  		}
  1012  		na.framer = framer
  1013  	}
  1014  	return &na, nil
  1015  }
  1016  
  1017  func (a *WindowedJSONArrayAgg) Dispose() {
  1018  	expression.Dispose(a.expr)
  1019  }
  1020  
  1021  // DefaultFramer returns a NewUnboundedPrecedingToCurrentRowFramer
  1022  func (a *WindowedJSONArrayAgg) DefaultFramer() sql.WindowFramer {
  1023  	return NewUnboundedPrecedingToCurrentRowFramer()
  1024  }
  1025  
  1026  func (a *WindowedJSONArrayAgg) StartPartition(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) error {
  1027  	a.Dispose()
  1028  	return nil
  1029  }
  1030  
  1031  func (a *WindowedJSONArrayAgg) NewSlidingFrameInterval(added, dropped sql.WindowInterval) {
  1032  	panic("sliding window interface not implemented yet")
  1033  }
  1034  
  1035  func (a *WindowedJSONArrayAgg) Compute(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) interface{} {
  1036  	res, err := a.aggregateVals(ctx, interval, buf)
  1037  	if err != nil {
  1038  		return nil
  1039  	}
  1040  	return types.JSONDocument{Val: res}
  1041  }
  1042  
  1043  func (a *WindowedJSONArrayAgg) aggregateVals(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) ([]interface{}, error) {
  1044  	vals := make([]interface{}, 0, interval.End-interval.Start)
  1045  	for _, row := range buf[interval.Start:interval.End] {
  1046  		v, err := a.expr.Eval(ctx, row)
  1047  		if err != nil {
  1048  			return nil, err
  1049  		}
  1050  
  1051  		// unwrap JSON values
  1052  		if js, ok := v.(sql.JSONWrapper); ok {
  1053  			v = js.ToInterface()
  1054  		}
  1055  
  1056  		vals = append(vals, v)
  1057  	}
  1058  
  1059  	return vals, nil
  1060  }
  1061  
  1062  type WindowedJSONObjectAgg struct {
  1063  	j      *JSONObjectAgg
  1064  	framer sql.WindowFramer
  1065  	// we need to eval the partition before Compute to return nil key errors
  1066  	vals map[string]interface{}
  1067  }
  1068  
  1069  func NewWindowedJSONObjectAgg(j *JSONObjectAgg) *WindowedJSONObjectAgg {
  1070  	return &WindowedJSONObjectAgg{
  1071  		j: j,
  1072  	}
  1073  }
  1074  
  1075  func (a *WindowedJSONObjectAgg) WithWindow(w *sql.WindowDefinition) (sql.WindowFunction, error) {
  1076  	na := *a
  1077  	if w.Frame != nil {
  1078  		framer, err := w.Frame.NewFramer(w)
  1079  		if err != nil {
  1080  			return nil, err
  1081  		}
  1082  		na.framer = framer
  1083  	}
  1084  	return &na, nil
  1085  }
  1086  
  1087  func (a *WindowedJSONObjectAgg) Dispose() {
  1088  	expression.Dispose(a.j)
  1089  }
  1090  
  1091  // DefaultFramer returns a NewUnboundedPrecedingToCurrentRowFramer
  1092  func (a *WindowedJSONObjectAgg) DefaultFramer() sql.WindowFramer {
  1093  	if a.framer != nil {
  1094  		return a.framer
  1095  	}
  1096  	return NewUnboundedPrecedingToCurrentRowFramer()
  1097  }
  1098  
  1099  func (a *WindowedJSONObjectAgg) StartPartition(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) error {
  1100  	a.Dispose()
  1101  	var err error
  1102  	a.vals, err = a.aggregateVals(ctx, interval, buf)
  1103  	return err
  1104  }
  1105  
  1106  func (a *WindowedJSONObjectAgg) NewSlidingFrameInterval(added, dropped sql.WindowInterval) {
  1107  	panic("sliding window interface not implemented yet")
  1108  }
  1109  
  1110  func (a *WindowedJSONObjectAgg) Compute(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) interface{} {
  1111  	if len(a.vals) == 0 {
  1112  		return nil
  1113  	}
  1114  	return types.JSONDocument{Val: a.vals}
  1115  }
  1116  
  1117  func (a *WindowedJSONObjectAgg) aggregateVals(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) (map[string]interface{}, error) {
  1118  	vals := make(map[string]interface{}, 0)
  1119  	for _, row := range buf[interval.Start:interval.End] {
  1120  		key, err := a.j.key.Eval(ctx, row)
  1121  		if err != nil {
  1122  			return nil, err
  1123  		}
  1124  
  1125  		// An error occurs if any key name is NULL
  1126  		if key == nil {
  1127  			return nil, sql.ErrJSONObjectAggNullKey.New()
  1128  		}
  1129  
  1130  		val, err := a.j.value.Eval(ctx, row)
  1131  		if err != nil {
  1132  			return nil, err
  1133  		}
  1134  
  1135  		// unwrap JSON values
  1136  		if js, ok := val.(sql.JSONWrapper); ok {
  1137  			val = js.ToInterface()
  1138  		}
  1139  
  1140  		// Update the map.
  1141  		keyAsString, _, err := types.LongText.Convert(key)
  1142  		if err != nil {
  1143  			continue
  1144  		}
  1145  		vals[keyAsString.(string)] = val
  1146  
  1147  	}
  1148  
  1149  	return vals, nil
  1150  }
  1151  
  1152  type RowNumber struct {
  1153  	pos int
  1154  }
  1155  
  1156  func NewRowNumber() *RowNumber {
  1157  	return &RowNumber{
  1158  		pos: -1,
  1159  	}
  1160  }
  1161  
  1162  func (a *RowNumber) WithWindow(w *sql.WindowDefinition) (sql.WindowFunction, error) {
  1163  	return a, nil
  1164  }
  1165  
  1166  func (a *RowNumber) Dispose() {
  1167  	return
  1168  }
  1169  
  1170  // DefaultFramer returns a NewPartitionFramer
  1171  func (a *RowNumber) DefaultFramer() sql.WindowFramer {
  1172  	return NewPartitionFramer()
  1173  }
  1174  
  1175  func (a *RowNumber) StartPartition(ctx *sql.Context, interval sql.WindowInterval, buffer sql.WindowBuffer) error {
  1176  	a.Dispose()
  1177  	a.pos = 1
  1178  	return nil
  1179  }
  1180  
  1181  func (a *RowNumber) NewSlidingFrameInterval(added, dropped sql.WindowInterval) {
  1182  	panic("implement me")
  1183  }
  1184  
  1185  func (a *RowNumber) Compute(ctx *sql.Context, interval sql.WindowInterval, buffer sql.WindowBuffer) interface{} {
  1186  	if interval.End-interval.Start < 1 {
  1187  		return nil
  1188  	}
  1189  	defer func() { a.pos++ }()
  1190  	return a.pos
  1191  }
  1192  
  1193  type rankBase struct {
  1194  	partitionStart, partitionEnd int
  1195  
  1196  	// orderBy tracks peer group increments
  1197  	orderBy []sql.Expression
  1198  	// pos increments every iteration
  1199  	pos int
  1200  	// peerGroup tracks value increments
  1201  	peerGroup sql.WindowInterval
  1202  }
  1203  
  1204  func (a *rankBase) WithWindow(w *sql.WindowDefinition) (sql.WindowFunction, error) {
  1205  	na := *a
  1206  	na.orderBy = w.OrderBy.ToExpressions()
  1207  	return &na, nil
  1208  }
  1209  
  1210  func (a *rankBase) Dispose() {
  1211  	return
  1212  }
  1213  
  1214  func (a *rankBase) DefaultFramer() sql.WindowFramer {
  1215  	return NewPeerGroupFramer(a.orderBy)
  1216  }
  1217  
  1218  func (a *rankBase) StartPartition(ctx *sql.Context, interval sql.WindowInterval, buffer sql.WindowBuffer) error {
  1219  	a.Dispose()
  1220  	a.partitionStart, a.partitionEnd = interval.Start, interval.End
  1221  	a.pos = a.partitionStart
  1222  	a.peerGroup = sql.WindowInterval{}
  1223  	return nil
  1224  }
  1225  
  1226  func (a *rankBase) NewSlidingFrameInterval(added, dropped sql.WindowInterval) {
  1227  	panic("implement me")
  1228  }
  1229  
  1230  // Compute returns the number of elements before the current peer group (rank) + 1.
  1231  // ex: [1, 2, 2, 2, 3, 3, 3, 4, 5, 5, 6] => every 3 returns uint64(5) because
  1232  // there are 4 values less than 3
  1233  func (a *rankBase) Compute(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) interface{} {
  1234  	if interval.End-interval.Start < 1 {
  1235  		return nil
  1236  	}
  1237  	defer func() { a.pos++ }()
  1238  	switch {
  1239  	case a.pos == 0:
  1240  		return uint64(1)
  1241  	case a.partitionEnd-a.partitionStart == 1:
  1242  		return uint64(1)
  1243  	default:
  1244  		return uint64(interval.Start-a.partitionStart) + 1
  1245  	}
  1246  }
  1247  
  1248  type Rank struct {
  1249  	*rankBase
  1250  }
  1251  
  1252  func NewRank(orderBy []sql.Expression) *Rank {
  1253  	return &Rank{
  1254  		&rankBase{
  1255  			partitionStart: -1,
  1256  			partitionEnd:   -1,
  1257  			pos:            -1,
  1258  			orderBy:        orderBy,
  1259  		},
  1260  	}
  1261  }
  1262  
  1263  type PercentRank struct {
  1264  	*rankBase
  1265  }
  1266  
  1267  func NewPercentRank(orderBy []sql.Expression) *PercentRank {
  1268  	return &PercentRank{
  1269  		&rankBase{
  1270  			partitionStart: -1,
  1271  			partitionEnd:   -1,
  1272  			pos:            -1,
  1273  			orderBy:        orderBy,
  1274  		},
  1275  	}
  1276  }
  1277  
  1278  // Compute returns the number of elements before the current peer group (rank),
  1279  // and returns (rank - 1)/(rows - 1).
  1280  // ex: [1, 2, 2, 2, 3, 3, 3, 4, 5, 5, 6] => every 3 returns float64(4) / float64(9), because
  1281  // there are 4 values less than 3, and there are (10 - 1) total rows in the list.
  1282  func (a *PercentRank) Compute(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) interface{} {
  1283  	rank := a.rankBase.Compute(ctx, interval, buf)
  1284  	if rank == nil {
  1285  		return nil
  1286  	}
  1287  	if a.partitionEnd-a.partitionStart == 1 {
  1288  		return float64(0)
  1289  	}
  1290  	return float64(rank.(uint64)-1) / float64(a.partitionEnd-a.partitionStart-1)
  1291  }
  1292  
  1293  type DenseRank struct {
  1294  	*rankBase
  1295  	// prevRank tracks what the previous non-dense rank was
  1296  	prevRank uint64
  1297  	// denseRank tracks what the previous dense rank is
  1298  	denseRank uint64
  1299  }
  1300  
  1301  func NewDenseRank(orderBy []sql.Expression) *DenseRank {
  1302  	return &DenseRank{
  1303  		rankBase: &rankBase{
  1304  			partitionStart: -1,
  1305  			partitionEnd:   -1,
  1306  			pos:            -1,
  1307  			orderBy:        orderBy,
  1308  		},
  1309  	}
  1310  }
  1311  
  1312  // Compute returns the number of unique elements before the current peer group (rank) + 1.
  1313  // ex: [1, 2, 2, 2, 3, 3, 3, 4, 5, 5, 6] => every 3 returns uint64(3) because
  1314  // there are 2 unique values less than 3
  1315  func (a *DenseRank) Compute(ctx *sql.Context, interval sql.WindowInterval, buf sql.WindowBuffer) interface{} {
  1316  	rank := a.rankBase.Compute(ctx, interval, buf)
  1317  	if rank == nil {
  1318  		return nil
  1319  	}
  1320  
  1321  	if rank.(uint64) == 1 {
  1322  		a.prevRank = 1
  1323  		a.denseRank = 1
  1324  	} else if rank != a.prevRank {
  1325  		a.prevRank = rank.(uint64)
  1326  		a.denseRank += 1
  1327  	}
  1328  	return a.denseRank
  1329  }
  1330  
  1331  type Lag struct {
  1332  	leadLagBase
  1333  }
  1334  
  1335  func NewLag(expr, def sql.Expression, offset int) *Lag {
  1336  	return &Lag{
  1337  		leadLagBase: leadLagBase{
  1338  			expr:   expr,
  1339  			def:    def,
  1340  			offset: offset,
  1341  		},
  1342  	}
  1343  }
  1344  
  1345  type Lead struct {
  1346  	leadLagBase
  1347  }
  1348  
  1349  func NewLead(expr, def sql.Expression, offset int) *Lead {
  1350  	return &Lead{
  1351  		leadLagBase: leadLagBase{
  1352  			expr:   expr,
  1353  			def:    def,
  1354  			offset: -offset,
  1355  		},
  1356  	}
  1357  }
  1358  
  1359  type leadLagBase struct {
  1360  	expr   sql.Expression
  1361  	def    sql.Expression
  1362  	offset int
  1363  	pos    int
  1364  }
  1365  
  1366  func (a *leadLagBase) WithWindow(w *sql.WindowDefinition) (sql.WindowFunction, error) {
  1367  	return a, nil
  1368  }
  1369  
  1370  func (a *leadLagBase) Dispose() {
  1371  	return
  1372  }
  1373  
  1374  // DefaultFramer returns a NewPartitionFramer
  1375  func (a *leadLagBase) DefaultFramer() sql.WindowFramer {
  1376  	return NewPartitionFramer()
  1377  }
  1378  
  1379  func (a *leadLagBase) StartPartition(ctx *sql.Context, interval sql.WindowInterval, buffer sql.WindowBuffer) error {
  1380  	a.Dispose()
  1381  	return nil
  1382  }
  1383  
  1384  func (a *leadLagBase) NewSlidingFrameInterval(added, dropped sql.WindowInterval) {
  1385  	panic("implement me")
  1386  }
  1387  
  1388  func (a *leadLagBase) Compute(ctx *sql.Context, interval sql.WindowInterval, buffer sql.WindowBuffer) interface{} {
  1389  	var res interface{}
  1390  	var err error
  1391  	idx := a.pos - a.offset
  1392  	switch {
  1393  	case interval.Start > interval.End:
  1394  	case idx >= interval.Start && idx < interval.End:
  1395  		res, err = a.expr.Eval(ctx, buffer[idx])
  1396  	case a.def != nil:
  1397  		res, err = a.def.Eval(ctx, buffer[a.pos])
  1398  	}
  1399  	if err != nil {
  1400  		return nil
  1401  	}
  1402  	a.pos++
  1403  	return res
  1404  }