| 2308 | } |
| 2309 | |
| 2310 | static void |
| 2311 | compute_start_end_offsets(WindowAggState *winstate) |
| 2312 | { |
| 2313 | int frameOptions = winstate->frameOptions; |
| 2314 | ExprContext *econtext = winstate->ss.ps.ps_ExprContext; |
| 2315 | Datum value; |
| 2316 | bool isnull; |
| 2317 | int16 len; |
| 2318 | bool byval; |
| 2319 | |
| 2320 | /* |
| 2321 | * Compute frame offset values, if any |
| 2322 | */ |
| 2323 | if (!winstate->start_offset_valid) |
| 2324 | { |
| 2325 | econtext->ecxt_outertuple = winstate->ss.ss_ScanTupleSlot; |
| 2326 | if (frameOptions & FRAMEOPTION_START_OFFSET) |
| 2327 | { |
| 2328 | Assert(winstate->startOffset != NULL); |
| 2329 | value = ExecEvalExprSwitchContext(winstate->startOffset, |
| 2330 | econtext, |
| 2331 | &isnull); |
| 2332 | if (isnull) |
| 2333 | ereport(ERROR, |
| 2334 | (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), |
| 2335 | errmsg("frame starting offset must not be null"))); |
| 2336 | /* copy value into query-lifespan context */ |
| 2337 | get_typlenbyval(exprType((Node *) winstate->startOffset->expr), |
| 2338 | &len, &byval); |
| 2339 | winstate->startOffsetValue = datumCopy(value, byval, len); |
| 2340 | if (frameOptions & (FRAMEOPTION_ROWS | FRAMEOPTION_GROUPS)) |
| 2341 | { |
| 2342 | /* value is known to be int8 */ |
| 2343 | int64 offset = DatumGetInt64(value); |
| 2344 | |
| 2345 | if (offset < 0) |
| 2346 | ereport(ERROR, |
| 2347 | (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE), |
| 2348 | errmsg("frame starting offset must not be negative"))); |
| 2349 | } |
| 2350 | } |
| 2351 | winstate->start_offset_valid = true; |
| 2352 | } |
| 2353 | if (!winstate->end_offset_valid) |
| 2354 | { |
| 2355 | econtext->ecxt_outertuple = winstate->ss.ss_ScanTupleSlot; |
| 2356 | if (frameOptions & FRAMEOPTION_END_OFFSET) |
| 2357 | { |
| 2358 | Assert(winstate->endOffset != NULL); |
| 2359 | value = ExecEvalExprSwitchContext(winstate->endOffset, |
| 2360 | econtext, |
| 2361 | &isnull); |
| 2362 | if (isnull) |
| 2363 | ereport(ERROR, |
| 2364 | (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), |
| 2365 | errmsg("frame ending offset must not be null"))); |
| 2366 | /* copy value into query-lifespan context */ |
| 2367 | get_typlenbyval(exprType((Node *) winstate->endOffset->expr), |
no test coverage detected