Lukasz answer is how you should do it (but the "date" table should be a public table with years woorth of data in it) so it's just a JOIN/BETWEEN as he notes.
But if we are going the the realm of UDF, lets use a UDTF, this emits a row per day in the range of values:
CREATE OR REPLACE FUNCTION date_range ( start_date date, end_date date)
RETURNS TABLE ( day date )
LANGUAGE JAVASCRIPT
AS '{
processRow: function get_params(row, rowWriter, context){
var t_date = new Date(row.START_DATE);
while (t_date <= row.END_DATE){
rowWriter.writeRow({DAY: t_date.valueOf()});
t_date.setDate(t_date.getDate() + 1);
}
}
}';
then we can just do a cross join to that:
SELECT
v.id,
d.day
FROM VALUES
(1, '2021-05-10', '2021-05-12'),
(2, '2021-07-05', '2021-07-09')
v(id, start_date, end_date)
,TABLE(date_range(to_date(v.start_date), to_date(v.end_date))) d;
gives:
| ID |
DAY |
| 1 |
2021-05-10 |
| 1 |
2021-05-11 |
| 1 |
2021-05-12 |
| 2 |
2021-07-05 |
| 2 |
2021-07-06 |
| 2 |
2021-07-07 |
| 2 |
2021-07-08 |
| 2 |
2021-07-09 |
that can be rewritten, with a CTE to act and a quick source of "data" to show how the work to use this is rather simple:
WITH fake_data(id, start_date, end_date) AS (
SELECT column1, to_date(column2), to_date(column3)
FROM VALUES
(1, '2021-05-10', '2021-05-12'),
(2, '2021-07-05', '2021-07-09')
)
SELECT
f.id
,d.day as date
FROM fake_data AS f,
TABLE(date_range(f.start_date, f.end_date)) d;
which gives the same results again.