Согласен первый код работает,
create or replace table persons (person_id number, deceased_date date);
insert into persons values (1,'2019-10-01'),(1,'2019-09-01'),(2,'1901-01-01'),(3,'2019-11-04');
SELECT COUNT(DISTINCT person_id)
FROM persons
WHERE (deceased_date = '1901-01-01' OR deceased_date > '2019-11-04');
CREATE OR REPLACE FUNCTION person_count(d date)
RETURNS number
AS
$$
SELECT COUNT(DISTINCT person_id)
FROM persons
WHERE (deceased_date > d)
$$;
select column1 as date
,person_count(column1) as cnt
from values ('2019-11-01'), ('2019-11-02'), ('2019-11-03'), ('2019-11-04'), ('2019-11-05'), ('2019-11-06'), ('2019-11-07')
order by 1;
Но эти альтернативы нет. СОЗДАТЬ ИЛИ ЗАМЕНИТЬ ФУНКЦИЮ person_count (дата d) ВОЗВРАЩАЕТ номер КАК $$ ВЫБРАТЬ СЧЕТ (DISTINCT person_id) ИЗ ЛИЦА, ГДЕ (deceased_date = '1901-01-01' ИЛИ deceased_date> d) $$;
CREATE OR REPLACE FUNCTION person_count(d date)
RETURNS number
AS
$$
SELECT COUNT(DISTINCT person_id)
FROM (
SELECT person_id FROM PERSONS WHERE deceased_date > d
UNION
SELECT person_id FROM PERSONS WHERE deceased_date = '1901-01-01'
)
$$;
Причина в том, что, когда они расширяют FUNCTION, они превращают его в коррелированный подзапрос (даже если это можно сделать как JOIN) и единственную работу с очень простыми коррелированными подзапросами,и вы не контролируете это. Мы ударились об это, когда хотим использовать ТАБЛИЦУЮ ФУНКЦИЮ в качестве справочных таблиц. В одном месте мы просто выкатили оператор CASE, чтобы избежать поиска (брутто), а в другом мы использовали UDF Javascript для выполнения поиска.
Но это по сути ошибка, поэтому я бы сообщил об этом.