```sql
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED       FOLLOWING
VS 
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED       PRECEDING


select product_name, price, group_name, round(avg0), round(avg1)
from (
SELECT
	product_name,
	price,
	group_name,
	avg(price) OVER (PARTITION BY group_name ORDER BY price) avg0,
	avg(price) OVER (PARTITION BY group_name ORDER BY
			price RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) avg1
FROM products INNER JOIN  product_groups USING (group_id)) t
order by group_name, product_name, price;




SELECT
    product_name,
    price,
    group_name,
    round(avg0),
    round(avg1)
FROM
(
    SELECT
        product_name,
        price,
        group_name,
        avg(price) OVER (PARTITION BY group_name ORDER BY price ASC) AS avg0,
        avg(price) OVER (PARTITION BY group_name ORDER BY price ASC RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED PRECEDING) AS avg1
    FROM products
    INNER JOIN product_groups USING (group_id)
) AS t
ORDER BY
    group_name ASC,
    product_name ASC,
    price ASC

```
settings.ostr << "CURRENT ROW";
        }
        else if (frame.begin_type == WindowFrame::BoundaryType::Unbounded)
        {
            settings.ostr << "UNBOUNDED PRECEDING";
        }
        else
        {
            settings.ostr << abs(frame.begin_offset);
            settings.ostr << " "
                << (!frame.begin_preceding ? "FOLLOWING" : "PRECEDING");
        }
        settings.ostr << " AND ";
        if (frame.end_type == WindowFrame::BoundaryType::Current)
        {
            settings.ostr << "CURRENT ROW";
        }
        else if (frame.end_type == WindowFrame::BoundaryType::Unbounded)
        {
            settings.ostr << "UNBOUNDED PRECEDING";
        }
        else
        {
            settings.ostr << abs(frame.end_offset);
            settings.ostr << " "
                << (!frame.end_preceding ? "FOLLOWING" : "PRECEDING");
        }
    }
}
std::string ASTWindowDefinition::getDefaultWindowName() const