v1-0001-Allow-window-functions-to-accept-a-null-treatment.patch
application/octet-stream
Filename: v1-0001-Allow-window-functions-to-accept-a-null-treatment.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v1-0001
Subject: Allow window functions to accept a null treatment clause by default.
| File | + | − |
|---|---|---|
| src/backend/executor/nodeWindowAgg.c | 11 | 6 |
| src/backend/utils/adt/windowfuncs.c | 0 | 4 |
From 925c527b4e776d49292a0fd747dcb16357418703 Mon Sep 17 00:00:00 2001
From: Tatsuo Ishii <ishii@postgresql.org>
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