>
>
>
>> SET
>>   g = year % 19,
>>   c = year / 100,
>>   h = (c - c/4 - (8*c + 13)/25 + 19*g + 15) % 30,
>>   i = h - (h/28)*(1 - (h/28)*(29/(h + 1))*((21 - g)/11)),
>>   j = year + year/4 + i + 2 - c + c/4) % 7,
>>   p = i - j,
>>   easter_month = 3 + (p + 26)/30,
>>   easter_day = 1 + (p + 27 + (p + 6)/40) % 31
>> SELECT make_date(year, easter_month, easter_day)
>>
>> or maybe even WITH like this:
>>
>> WITH
>>   year % 19 AS g ,
>>   year / 100 AS c,
>>   (c - c/4 - (8*c + 13)/25 + 19*g + 15) % 30 AS h,
>>   h - (h/28)*(1 - (h/28)*(29/(h + 1))*((21 - g)/11)) AS i,
>>   year + year/4 + i + 2 - c + c/4) % 7 AS j,
>>   i - j AS p,
>>   3 + (p + 26)/30 AS easter_month,
>>   1 + (p + 27 + (p + 6)/40) % 31 AS easter_day
>> SELECT make_date(year, easter_month, easter_day)
>>
>
> I do not think this clause is necessary (because we have PLpgSQL or C),
> but other people can have different opinions (and it is true, so this
> feature can have some performance benefit - because it enhances the
> possibilities of inlined expressions and custom (own) extensions are
> prohibited in cloud environments (and will be) ).  Theoretically the
> implementation of this feature should not be hard, because these variables
> are very local only (the scope is just row), so this is just a game for
> parser and for expression's interpreter. But if you introduce this feature,
> then it is better to use syntax that is used by some other well known
> systems (Oracle or others).
>

The name for this feature can be "row scope variables" and yes, in OLAP
queries there are repeated expressions where this feature can be useful.

postgres=# explain verbose select  make_date(year, easter_month,
easter_day) from (select year,  3 + (p + 26)/30 AS easter_month, 1 + (p +
27 + (p + 6)/40) % 31 AS easter_day from (  select year, i - j AS p from
(select year, i, (year + year/4 + i + 2 - c + c/4) % 7 AS j from (select
year, c, h - (h/28)*(1 - (h/28)*(29/(h + 1))*((21 - g)/11)) AS i from
(select year, g, c, (c - c/4 - (8*c + 13)/25 + 19*g + 15) % 30 AS h  from
(select year, year % 19 as g, year / 100 as c from
generate_series(2019,2020) g(year) offset 0) s1 offset 0) s2 offset 0) s3
offset 0) s4 offset 0) s5 offset 0) s6;
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                                 QUERY
PLAN                                                                  │
╞═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╡
│ Subquery Scan on s6  (cost=0.00..0.35 rows=2 width=4)
                                                                  │
│   Output: make_date(s6.year, s6.easter_month, s6.easter_day)
                                                                   │
│   ->  Subquery Scan on s5  (cost=0.00..0.33 rows=2 width=12)
                                                                   │
│         Output: s5.year, (3 + ((s5.p + 26) / 30)), (1 + (((s5.p + 27) +
((s5.p + 6) / 40)) % 31))                                           │
│         ->  Subquery Scan on s4  (cost=0.00..0.26 rows=2 width=8)
                                                                  │
│               Output: s4.year, (s4.i - s4.j)
                                                                   │
│               ->  Subquery Scan on s3  (cost=0.00..0.24 rows=2 width=12)
                                                                   │
│                     Output: s3.year, s3.i, ((((((s3.year + (s3.year / 4))
+ s3.i) + 2) - s3.c) + (s3.c / 4)) % 7)                           │
│                     ->  Subquery Scan on s2  (cost=0.00..0.18 rows=2
width=12)                                                              │
│                           Output: s2.year, s2.c, (s2.h - ((s2.h / 28) *
(1 - (((s2.h / 28) * (29 / (s2.h + 1))) * ((21 - s2.g) / 11)))))    │
│                           ->  Subquery Scan on s1  (cost=0.00..0.10
rows=2 width=16)                                                        │
│                                 Output: s1.year, s1.g, s1.c, (((((s1.c -
(s1.c / 4)) - (((8 * s1.c) + 13) / 25)) + (19 * s1.g)) + 15) % 30) │
│                                 ->  Function Scan on
pg_catalog.generate_series g  (cost=0.00..0.03 rows=2 width=12)
           │
│                                       Output: g.year, (g.year % 19),
(g.year / 100)                                                         │
│                                       Function Call:
generate_series(2019, 2020)
           │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
(15 rows)



Pavel

Reply via email to