Below is for BigQuery Standard SQL
#standardSQL
SELECT * EXCEPT(day) REPLACE(day AS date_purchased)
FROM `project.dataset.table`, UNNEST((
SELECT CASE package
WHEN 'Week' THEN GENERATE_DATE_ARRAY(date_purchased, date_ended, INTERVAL 1 DAY)
WHEN 'Month' THEN GENERATE_DATE_ARRAY(date_purchased, date_ended, INTERVAL 1 WEEK)
WHEN 'Quarter' THEN GENERATE_DATE_ARRAY(date_purchased, date_ended, INTERVAL 1 MONTH)
WHEN 'Year' THEN GENERATE_DATE_ARRAY(date_purchased, date_ended, INTERVAL 1 QUARTER)
ELSE GENERATE_DATE_ARRAY(date_purchased, date_ended, INTERVAL 1 MONTH)
END
)) day
You can test, play above using dummy data as in below example
#standardSQL
WITH `project.dataset.table` AS (
SELECT DATE '2019-01-01' date_purchased, DATE '2019-02-01' date_ended, 'Month' package UNION ALL
SELECT '2019-01-01', '2019-03-31', 'Quarter' UNION ALL
SELECT '2019-01-01', '2020-12-31', 'Year'
)
SELECT * EXCEPT(day) REPLACE(day AS date_purchased)
FROM `project.dataset.table`, UNNEST((
SELECT CASE package
WHEN 'Week' THEN GENERATE_DATE_ARRAY(date_purchased, date_ended, INTERVAL 1 DAY)
WHEN 'Month' THEN GENERATE_DATE_ARRAY(date_purchased, date_ended, INTERVAL 1 WEEK)
WHEN 'Quarter' THEN GENERATE_DATE_ARRAY(date_purchased, date_ended, INTERVAL 1 MONTH)
WHEN 'Year' THEN GENERATE_DATE_ARRAY(date_purchased, date_ended, INTERVAL 1 QUARTER)
ELSE GENERATE_DATE_ARRAY(date_purchased, date_ended, INTERVAL 1 MONTH)
END
)) day
with result
Row date_purchased date_ended package
1 2019-01-01 2019-02-01 Month
2 2019-01-08 2019-02-01 Month
3 2019-01-15 2019-02-01 Month
4 2019-01-22 2019-02-01 Month
5 2019-01-29 2019-02-01 Month
6 2019-01-01 2019-03-31 Quarter
7 2019-02-01 2019-03-31 Quarter
8 2019-03-01 2019-03-31 Quarter
9 2019-01-01 2020-12-31 Year
10 2019-04-01 2020-12-31 Year
11 2019-07-01 2020-12-31 Year
12 2019-10-01 2020-12-31 Year
13 2020-01-01 2020-12-31 Year
14 2020-04-01 2020-12-31 Year
15 2020-07-01 2020-12-31 Year
16 2020-10-01 2020-12-31 Year