From 2273fa32bce7c1fb856c726d01d8cdaaba36f849 Mon Sep 17 00:00:00 2001 From: Tatsuo Ishii Date: Wed, 8 Oct 2025 09:26:49 +0900 Subject: [PATCH] Fix Coverity issues reported in commit 25a30bbd423. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Fix several issues pointed out by Coverity (reported by Tome Lane). - In row_is_in_frame(), return value of window_gettupleslot() was not checked. - WinGetFuncArgInPartition() tried to derefference "isout" pointer even if it could be NULL in some places. Besides the issues, I also fixed a compiler warning reported by Álvaro Herrera. Moreover, in WinGetFuncArgInPartition refactor the do...while loop so that the codes inside the loop simpler. Also simplify the case when abs_pos < 0. Author: Tatsuo Ishii Reviewed-by: Paul Ramsey Reported-by: Tom Lane Reported-by: Álvaro Herrera Discussion: https://postgr.es/m/1686755.1759679957%40sss.pgh.pa.us Discussion: https://postgr.es/m/202510051612.gw67jlc2iqpw%40alvherre.pgsql --- src/backend/executor/nodeWindowAgg.c | 77 ++++++++++++++-------------- 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c index cf667c81211..0698aae37a7 100644 --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -1501,8 +1501,9 @@ row_is_in_frame(WindowObject winobj, int64 pos, TupleTableSlot *slot, /* following row that is not peer is out of frame */ if (pos > winstate->currentpos) { - if (fetch_tuple) - window_gettupleslot(winobj, pos, slot); + if (fetch_tuple) /* need to fetch tuple? */ + if (!window_gettupleslot(winobj, pos, slot)) + return -1; if (!are_peers(winstate, slot, winstate->ss.ss_ScanTupleSlot)) return -1; } @@ -3721,6 +3722,7 @@ WinGetFuncArgInPartition(WindowObject winobj, int argno, int notnull_offset; int notnull_relpos; int forward; + bool myisout; Assert(WindowObjectIsValid(winobj)); winstate = winobj->winstate; @@ -3759,63 +3761,60 @@ WinGetFuncArgInPartition(WindowObject winobj, int argno, if (!null_treatment) /* IGNORE NULLS is not specified */ { + /* get tupple and evaluate in a partition */ datum = gettuple_eval_partition(winobj, argno, - abs_pos, isnull, isout); - if (!*isout && set_mark) + abs_pos, isnull, &myisout); + if (!myisout && set_mark) WinSetMarkPosition(winobj, abs_pos); + if (isout) + *isout = myisout; return datum; } + myisout = false; + datum = 0; + /* * Get the next nonnull value in the partition, moving forward or backward * until we find a value or reach the partition's end. */ do { + int nn_info; /* NOT NULL info */ + abs_pos += forward; - if (abs_pos < 0) - { - /* out of partition */ - if (isout) - *isout = true; - *isnull = true; - datum = 0; + if (abs_pos < 0) /* apparently out of partition */ break; - } - switch (get_notnull_info(winobj, abs_pos)) + /* check NOT NULL cached info */ + nn_info = get_notnull_info(winobj, abs_pos); + if (nn_info == NN_NOTNULL) /* this row is known to be NOT NULL */ + notnull_offset++; + + else if (nn_info == NN_NULL) /* this row is known to be NULL */ + continue; /* keep on moving forward or backward */ + + else /* need to check NULL or not */ { - case NN_NOTNULL: /* this row is known to be NOT NULL */ - notnull_offset++; - if (notnull_offset >= notnull_relpos) - { - /* prepare to exit this loop */ - datum = gettuple_eval_partition(winobj, argno, - abs_pos, isnull, isout); - } - break; - case NN_NULL: /* this row is known to be NULL */ - if (isout) - *isout = false; - *isnull = true; - datum = 0; - break; - default: /* need to check NULL or not */ - datum = gettuple_eval_partition(winobj, argno, - abs_pos, isnull, isout); - if (*isout) /* out of partition? */ - return datum; - - if (!*isnull) - notnull_offset++; - /* record the row status */ - put_notnull_info(winobj, abs_pos, *isnull); + /* get tupple and evaluate in a partition */ + datum = gettuple_eval_partition(winobj, argno, + abs_pos, isnull, &myisout); + if (myisout) /* out of partition? */ break; + if (!*isnull) + notnull_offset++; + /* record the row status */ + put_notnull_info(winobj, abs_pos, *isnull); } } while (notnull_offset < notnull_relpos); - if (!*isout && set_mark) + /* get tupple and evaluate in a partition */ + datum = gettuple_eval_partition(winobj, argno, + abs_pos, isnull, &myisout); + if (!myisout && set_mark) WinSetMarkPosition(winobj, abs_pos); + if (isout) + *isout = myisout; return datum; } -- 2.47.3