From 925c527b4e776d49292a0fd747dcb16357418703 Mon Sep 17 00:00:00 2001 From: Tatsuo Ishii Date: Sun, 12 Oct 2025 16:21:40 +0900 Subject: [PATCH v1] Allow window functions to accept a null treatment clause by default. Previously window functions (either built-in or user defined) should call WinCheckAndInitializeNullTreatment with allowNullTreatment==true if they accept a null treatment clause (RESPECT NULLS/IGNORE NULLS). Otherwise, they are called as if null treatment clause is not specified. This commit changes the behavior so that window functions accept a null treatment clause as specified without calling WinCheckAndInitializeNullTreatment. If window functions do not want accept a null treatment clause, call WinCheckAndInitializeNullTreatment with allowNullTreatment==false. --- src/backend/executor/nodeWindowAgg.c | 17 +++++++++++------ src/backend/utils/adt/windowfuncs.c | 4 ---- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c index e6a53f95391..c2e2ca69347 100644 --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -1303,7 +1303,8 @@ begin_partition(WindowAggState *winstate) winobj->seekpos = -1; /* reset null map */ - if (winobj->ignore_nulls == IGNORE_NULLS) + if (winobj->ignore_nulls == IGNORE_NULLS || + winobj->ignore_nulls == PARSER_IGNORE_NULLS) memset(winobj->notnull_info, 0, NN_POS_TO_BYTES( perfuncstate->winobj->num_notnull_info)); @@ -3530,8 +3531,10 @@ put_notnull_info(WindowObject winobj, int64 pos, bool isnull) * WinCheckAndInitializeNullTreatment * Check null treatment clause and sets ignore_nulls * - * Window functions should call this to check if they are being called with - * a null treatment clause when they don't allow it, or to set ignore_nulls. + * Window functions call this if they do not accept a null treatment clause + * with allowNullTreatment==false. It's not mandatory but they can call this + * with allowNullTreatment==true to explicitly stat that they accept a a null + * treatment clause. */ void WinCheckAndInitializeNullTreatment(WindowObject winobj, @@ -3555,7 +3558,6 @@ WinCheckAndInitializeNullTreatment(WindowObject winobj, } else if (winobj->ignore_nulls == PARSER_IGNORE_NULLS) winobj->ignore_nulls = IGNORE_NULLS; - } /* @@ -3727,7 +3729,9 @@ WinGetFuncArgInPartition(WindowObject winobj, int argno, Assert(WindowObjectIsValid(winobj)); winstate = winobj->winstate; - null_treatment = (winobj->ignore_nulls == IGNORE_NULLS && relpos != 0); + null_treatment = ((winobj->ignore_nulls == IGNORE_NULLS || + winobj->ignore_nulls == PARSER_IGNORE_NULLS) && + relpos != 0); switch (seektype) { @@ -3866,7 +3870,8 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno, econtext = winstate->ss.ps.ps_ExprContext; slot = winstate->temp_slot_1; - if (winobj->ignore_nulls == IGNORE_NULLS) + if (winobj->ignore_nulls == IGNORE_NULLS || + winobj->ignore_nulls == PARSER_IGNORE_NULLS) return ignorenulls_getfuncarginframe(winobj, argno, relpos, seektype, set_mark, isnull, isout); diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c index 969f02aa59b..7e936a8bfbc 100644 --- a/src/backend/utils/adt/windowfuncs.c +++ b/src/backend/utils/adt/windowfuncs.c @@ -541,7 +541,6 @@ leadlag_common(FunctionCallInfo fcinfo, bool isnull; bool isout; - WinCheckAndInitializeNullTreatment(winobj, true, fcinfo); if (withoffset) { offset = DatumGetInt32(WinGetFuncArgCurrent(winobj, 1, &isnull)); @@ -659,7 +658,6 @@ window_first_value(PG_FUNCTION_ARGS) Datum result; bool isnull; - WinCheckAndInitializeNullTreatment(winobj, true, fcinfo); result = WinGetFuncArgInFrame(winobj, 0, 0, WINDOW_SEEK_HEAD, true, &isnull, NULL); @@ -681,7 +679,6 @@ window_last_value(PG_FUNCTION_ARGS) Datum result; bool isnull; - WinCheckAndInitializeNullTreatment(winobj, true, fcinfo); result = WinGetFuncArgInFrame(winobj, 0, 0, WINDOW_SEEK_TAIL, true, &isnull, NULL); @@ -705,7 +702,6 @@ window_nth_value(PG_FUNCTION_ARGS) bool isnull; int32 nth; - WinCheckAndInitializeNullTreatment(winobj, true, fcinfo); nth = DatumGetInt32(WinGetFuncArgCurrent(winobj, 1, &isnull)); if (isnull) PG_RETURN_NULL(); -- 2.43.0