Обсуждение: User defined window functions calling WinGetFuncArgInPartition/WINDOW_SEEK_HEAD
User defined window functions calling WinGetFuncArgInPartition/WINDOW_SEEK_HEAD
От
Tatsuo Ishii
Дата:
Hi Oliver, PostGis has user defined window functions. I checked them and found they call WinGetFuncArgInPartition with WINDOW_SEEK_HEAD. https://gitea.osgeo.org/postgis/postgis/search?q=WinGetFuncArgInPartition&fuzzy=true If they decide to call the window functions with IGNORE NULLS option, I think they may be surprised that WinGetFuncArgInPartition/WINDOW_SEEK_HEAD returns somewhat counter intuitive results. To study this I created a tiny user defined window function which calls WinGetFuncArgInPartition with WINDOW_SEEK_HEAD (see attached). CREATE FUNCTION mywindowfunc(IN anycompatible, IN int) RETURNS anycompatible AS 'MODULE_PATHNAME', 'mywindowfunc' LANGUAGE C WINDOW STRICT; The first argument is an any expression and the second argument is passed to WinGetFuncArgInPartition's relpos argument. Here is the result: CREATE TEMP TABLE g(x INT, y INT); CREATE TABLE INSERT INTO g (VALUES(NULL,1),(NULL,2),(10,3),(20,4)); INSERT 0 4 SELECT * FROM g; x | y ----+--- | 1 | 2 10 | 3 20 | 4 (4 rows) SELECT x, y, mywindowfunc(x, 0) IGNORE NULLS OVER w FROM g WINDOW w AS (ORDER BY y); x | y | mywindowfunc ----+---+-------------- | 1 | | 2 | 10 | 3 | 20 | 4 | (4 rows) SELECT x, y, mywindowfunc(x, 1) IGNORE NULLS OVER w FROM g WINDOW w AS (ORDER BY y); x | y | mywindowfunc ----+---+-------------- | 1 | 10 | 2 | 10 10 | 3 | 10 20 | 4 | 10 (4 rows) SELECT x, y, mywindowfunc(x, 2) IGNORE NULLS OVER w FROM g WINDOW w AS (ORDER BY y); x | y | mywindowfunc ----+---+-------------- | 1 | 20 | 2 | 20 10 | 3 | 20 20 | 4 | 20 (4 rows) For relpos==0, 1, 2 it returns NULL, 10, 20 on the first result row. I can explain why for relpos==0, NULL is returned. If IGNORE NULLS and relpos==0, it is treated as if RESPECT NULLS is specified. But this may be counterintuitive result. reslpos==1, 2 case also seems strange to me. I expected for relpos==1, the second non null row (20) is returned, but it returns 10. For relpos==2, I expected NULL since there's no third non null row. But others may think differently. Since there's no such an idea like WINDOW_SEEK_HEAD in the SQL standard, I think we have to decide what to do with WINDOW_SEEK_HEAD case. One idea is, we treat it as nth_value with "ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING" frame option. With nth_value we get 10, 20 and NULL for offset 1, 2 and 3. What do you think? Best regards, -- Tatsuo Ishii SRA OSS K.K. English: http://www.sraoss.co.jp/index_en/ Japanese:http://www.sraoss.co.jp