FrameStartIdx returns the index of starting row in the frame (which is the first to be included).
(ctx context.Context, evalCtx *EvalContext)
| 107 | |
| 108 | // FrameStartIdx returns the index of starting row in the frame (which is the first to be included). |
| 109 | func (wfr *WindowFrameRun) FrameStartIdx(ctx context.Context, evalCtx *EvalContext) (int, error) { |
| 110 | if wfr.Frame == nil { |
| 111 | return 0, nil |
| 112 | } |
| 113 | switch wfr.Frame.Mode { |
| 114 | case RANGE: |
| 115 | switch wfr.Frame.Bounds.StartBound.BoundType { |
| 116 | case UnboundedPreceding: |
| 117 | return 0, nil |
| 118 | case OffsetPreceding: |
| 119 | value, err := wfr.getValueByOffset(ctx, evalCtx, wfr.StartBoundOffset, true /* negative */) |
| 120 | if err != nil { |
| 121 | return 0, err |
| 122 | } |
| 123 | if wfr.OrdDirection == encoding.Descending { |
| 124 | // We use binary search on [0, wfr.RowIdx) interval to find the first row |
| 125 | // whose value is smaller or equal to 'value'. If such row is not found, |
| 126 | // then Search will correctly return wfr.RowIdx. |
| 127 | return sort.Search(wfr.RowIdx, func(i int) bool { |
| 128 | if wfr.err != nil { |
| 129 | return false |
| 130 | } |
| 131 | valueAt, err := wfr.valueAt(ctx, i) |
| 132 | if err != nil { |
| 133 | wfr.err = err |
| 134 | return false |
| 135 | } |
| 136 | return valueAt.Compare(evalCtx, value) <= 0 |
| 137 | }), wfr.err |
| 138 | } |
| 139 | // We use binary search on [0, wfr.RowIdx) interval to find the first row |
| 140 | // whose value is greater or equal to 'value'. If such row is not found, |
| 141 | // then Search will correctly return wfr.RowIdx. |
| 142 | return sort.Search(wfr.RowIdx, func(i int) bool { |
| 143 | if wfr.err != nil { |
| 144 | return false |
| 145 | } |
| 146 | valueAt, err := wfr.valueAt(ctx, i) |
| 147 | if err != nil { |
| 148 | wfr.err = err |
| 149 | return false |
| 150 | } |
| 151 | return valueAt.Compare(evalCtx, value) >= 0 |
| 152 | }), wfr.err |
| 153 | case CurrentRow: |
| 154 | // Spec: in RANGE mode CURRENT ROW means that the frame starts with the current row's first peer. |
| 155 | return wfr.PeerHelper.GetFirstPeerIdx(wfr.CurRowPeerGroupNum), nil |
| 156 | case OffsetFollowing: |
| 157 | value, err := wfr.getValueByOffset(ctx, evalCtx, wfr.StartBoundOffset, false /* negative */) |
| 158 | if err != nil { |
| 159 | return 0, err |
| 160 | } |
| 161 | if wfr.OrdDirection == encoding.Descending { |
| 162 | // We use binary search on [0, wfr.PartitionSize()) interval to find |
| 163 | // the first row whose value is smaller or equal to 'value'. |
| 164 | return sort.Search(wfr.PartitionSize(), func(i int) bool { |
| 165 | if wfr.err != nil { |
| 166 | return false |
no test coverage detected