diff options
-rw-r--r-- | src/backend/executor/nodeWindowAgg.c | 77 |
1 files 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; } |