summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/executor/nodeWindowAgg.c77
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;
}