* eval_windowfunction * * Arguments of window functions are not evaluated here, because a window * function can need random access to arbitrary rows in the partition. * The window function uses the special WinGetFuncArgInPartition and * WinGetFuncArgInFrame functions to evaluate the arguments for the rows * it wants. */
| 1285 | * it wants. |
| 1286 | */ |
| 1287 | static void |
| 1288 | eval_windowfunction(WindowAggState *winstate, WindowStatePerFunc perfuncstate, |
| 1289 | Datum *result, bool *isnull) |
| 1290 | { |
| 1291 | LOCAL_FCINFO(fcinfo, FUNC_MAX_ARGS); |
| 1292 | MemoryContext oldContext; |
| 1293 | |
| 1294 | oldContext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_tuple_memory); |
| 1295 | |
| 1296 | /* |
| 1297 | * We don't pass any normal arguments to a window function, but we do pass |
| 1298 | * it the number of arguments, in order to permit window function |
| 1299 | * implementations to support varying numbers of arguments. The real info |
| 1300 | * goes through the WindowObject, which is passed via fcinfo->context. |
| 1301 | */ |
| 1302 | InitFunctionCallInfoData(*fcinfo, &(perfuncstate->flinfo), |
| 1303 | perfuncstate->numArguments, |
| 1304 | perfuncstate->winCollation, |
| 1305 | (void *) perfuncstate->winobj, NULL); |
| 1306 | /* Just in case, make all the regular argument slots be null */ |
| 1307 | for (int argno = 0; argno < perfuncstate->numArguments; argno++) |
| 1308 | fcinfo->args[argno].isnull = true; |
| 1309 | /* Window functions don't have a current aggregate context, either */ |
| 1310 | winstate->curaggcontext = NULL; |
| 1311 | |
| 1312 | *result = FunctionCallInvoke(fcinfo); |
| 1313 | *isnull = fcinfo->isnull; |
| 1314 | |
| 1315 | /* |
| 1316 | * Make sure pass-by-ref data is allocated in the appropriate context. (We |
| 1317 | * need this in case the function returns a pointer into some short-lived |
| 1318 | * tuple, as is entirely possible.) |
| 1319 | */ |
| 1320 | if (!perfuncstate->resulttypeByVal && !fcinfo->isnull && |
| 1321 | !MemoryContextContainsGenericAllocation(CurrentMemoryContext, |
| 1322 | DatumGetPointer(*result)) |
| 1323 | ) |
| 1324 | *result = datumCopy(*result, |
| 1325 | perfuncstate->resulttypeByVal, |
| 1326 | perfuncstate->resulttypeLen); |
| 1327 | |
| 1328 | MemoryContextSwitchTo(oldContext); |
| 1329 | } |
| 1330 | |
| 1331 | /* |
| 1332 | * begin_partition |
no test coverage detected