@@ -37,6 +37,22 @@ import (
3737
3838const opName = "window"
3939
40+ // A Window call can spend a long time inside one frame evaluation, especially
41+ // for running frames whose aggregate work is quadratic in the partition size.
42+ // Keep the cancellation polling overhead bounded while still allowing KILL
43+ // QUERY / KILL CONNECTION to interrupt that work promptly.
44+ const cancellationCheckInterval = 1024
45+
46+ func checkCanceled (proc * process.Process , iteration int ) error {
47+ if iteration & (cancellationCheckInterval - 1 ) != 0 {
48+ return nil
49+ }
50+ if err , canceled := vm .CancelCheck (proc ); canceled {
51+ return err
52+ }
53+ return nil
54+ }
55+
4056func (window * Window ) String (buf * bytes.Buffer ) {
4157 buf .WriteString (opName )
4258 buf .WriteString (": window" )
@@ -80,6 +96,9 @@ func (window *Window) Call(proc *process.Process) (vm.CallResult, error) {
8096 ctr := & window .ctr
8197
8298 for {
99+ if err , canceled := vm .CancelCheck (proc ); canceled {
100+ return vm .CancelResult , err
101+ }
83102 switch ctr .status {
84103 case receiveAll :
85104 for {
@@ -154,6 +173,9 @@ func (window *Window) Call(proc *process.Process) (vm.CallResult, error) {
154173 }
155174 // calculate
156175 for i , w := range window .WinSpecList {
176+ if err = checkCanceled (proc , 0 ); err != nil {
177+ return result , err
178+ }
157179 // sort and partitions
158180 if window .Fs = makeOrderBy (w ); window .Fs != nil {
159181 if len (ctr .orderVecs ) == 0 {
@@ -277,7 +299,13 @@ func (ctr *container) processFunc(idx int, ap *Window, proc *process.Process, an
277299
278300 o := 0
279301 for p := 1 ; p < len (ctr .ps ); p ++ {
302+ if err = checkCanceled (proc , p ); err != nil {
303+ return err
304+ }
280305 for ; o < len (ctr .os ); o ++ {
306+ if err = checkCanceled (proc , o ); err != nil {
307+ return err
308+ }
281309
282310 if ctr .os [o ] <= ctr .ps [p ] {
283311 // For NTILE, pass both os vector and bucket count vector
@@ -302,6 +330,9 @@ func (ctr *container) processFunc(idx int, ap *Window, proc *process.Process, an
302330 } else {
303331 // plan.Function_AGG
304332 for j := 0 ; j < n ; j ++ {
333+ if err = checkCanceled (proc , j ); err != nil {
334+ return err
335+ }
305336
306337 start , end := 0 , n
307338
@@ -326,6 +357,9 @@ func (ctr *container) processFunc(idx int, ap *Window, proc *process.Process, an
326357 }
327358
328359 for k := left ; k < right ; k ++ {
360+ if err = checkCanceled (proc , k - left ); err != nil {
361+ return err
362+ }
329363 if err = ctr .batAggs [idx ].Fill (j , k , ctr .aggVecs [idx ].Vec ); err != nil {
330364 return err
331365 }
@@ -390,6 +424,9 @@ func (ctr *container) processValueFunc(idx int, ap *Window, proc *process.Proces
390424 defaultVec = ctr .aggVecs [idx ].Vec [2 ]
391425 }
392426 for j := 0 ; j < n ; j ++ {
427+ if err = checkCanceled (proc , j ); err != nil {
428+ return nil , err
429+ }
393430 offset , ok := constOffset , constOK
394431 if offsetVec != nil && ! offsetVec .IsConst () {
395432 offset , ok = getInt64FromVec (offsetVec , j )
@@ -430,6 +467,9 @@ func (ctr *container) processValueFunc(idx int, ap *Window, proc *process.Proces
430467 defaultVec = ctr .aggVecs [idx ].Vec [2 ]
431468 }
432469 for j := 0 ; j < n ; j ++ {
470+ if err = checkCanceled (proc , j ); err != nil {
471+ return nil , err
472+ }
433473 offset , ok := constOffset , constOK
434474 if offsetVec != nil && ! offsetVec .IsConst () {
435475 offset , ok = getInt64FromVec (offsetVec , j )
@@ -458,6 +498,9 @@ func (ctr *container) processValueFunc(idx int, ap *Window, proc *process.Proces
458498
459499 case "first_value" :
460500 for j := 0 ; j < n ; j ++ {
501+ if err = checkCanceled (proc , j ); err != nil {
502+ return nil , err
503+ }
461504 start , end := 0 , n
462505 if ctr .ps != nil {
463506 start , end = buildPartitionInterval (ctr .ps , j , n )
@@ -485,6 +528,9 @@ func (ctr *container) processValueFunc(idx int, ap *Window, proc *process.Proces
485528
486529 case "last_value" :
487530 for j := 0 ; j < n ; j ++ {
531+ if err = checkCanceled (proc , j ); err != nil {
532+ return nil , err
533+ }
488534 start , end := 0 , n
489535 if ctr .ps != nil {
490536 start , end = buildPartitionInterval (ctr .ps , j , n )
@@ -521,6 +567,9 @@ func (ctr *container) processValueFunc(idx int, ap *Window, proc *process.Proces
521567 }
522568 }
523569 for j := 0 ; j < n ; j ++ {
570+ if err = checkCanceled (proc , j ); err != nil {
571+ return nil , err
572+ }
524573 nthVal , ok := constNth , constOK
525574 if nthVec != nil && ! nthVec .IsConst () {
526575 nthVal , ok = getInt64FromVec (nthVec , j )
@@ -834,15 +883,24 @@ func (ctr *container) processOrder(idx int, ap *Window, bat *batch.Batch, proc *
834883 // }
835884 ctr .sels = make ([]int64 , rowCount )
836885 for i := 0 ; i < rowCount ; i ++ {
886+ if err := checkCanceled (proc , i ); err != nil {
887+ return false , err
888+ }
837889 ctr .sels [i ] = int64 (i )
838890 }
839891
840892 // skip sort for const vector
841893 if ! ovec .IsConst () {
894+ if err := checkCanceled (proc , 0 ); err != nil {
895+ return false , err
896+ }
842897 nullCnt := ovec .GetNulls ().Count ()
843898 if nullCnt < ovec .Length () {
844899 sort .Sort (ctr .desc [0 ], ctr .nullsLast [0 ], nullCnt > 0 , ctr .sels , ovec )
845900 }
901+ if err := checkCanceled (proc , 0 ); err != nil {
902+ return false , err
903+ }
846904 }
847905
848906 ps := make ([]int64 , 0 , 16 )
@@ -853,6 +911,9 @@ func (ctr *container) processOrder(idx int, ap *Window, bat *batch.Batch, proc *
853911
854912 i , j := 1 , len (ctr .orderVecs )
855913 for ; i < j ; i ++ {
914+ if err := checkCanceled (proc , 0 ); err != nil {
915+ return false , err
916+ }
856917 desc := ctr .desc [i ]
857918 nullsLast := ctr .nullsLast [i ]
858919 ps = partition .Partition (ctr .sels , ds , ps , ovec )
@@ -862,6 +923,9 @@ func (ctr *container) processOrder(idx int, ap *Window, bat *batch.Batch, proc *
862923 nullCnt := vec .GetNulls ().Count ()
863924 if nullCnt < vec .Length () {
864925 for i , j := 0 , len (ps ); i < j ; i ++ {
926+ if err := checkCanceled (proc , i ); err != nil {
927+ return false , err
928+ }
865929 if i == j - 1 {
866930 sort .Sort (desc , nullsLast , nullCnt > 0 , ctr .sels [ps [i ]:], vec )
867931 } else {
@@ -870,6 +934,9 @@ func (ctr *container) processOrder(idx int, ap *Window, bat *batch.Batch, proc *
870934 }
871935 }
872936 }
937+ if err := checkCanceled (proc , 0 ); err != nil {
938+ return false , err
939+ }
873940 ovec = vec
874941 if n == i {
875942 ctr .ps = make ([]int64 , len (ps ))
0 commit comments