WIP: Hierarchical Queries - stage 1
От | Mark Cave-Ayland |
---|---|
Тема | WIP: Hierarchical Queries - stage 1 |
Дата | |
Msg-id | 1158781418.5658.57.camel@mca-desktop обсуждение исходный текст |
Ответы |
Re: WIP: Hierarchical Queries - stage 1
|
Список | pgsql-patches |
Hi everyone, After spending several days reading PostgreSQL source code (and another couple of days coding), I've managed to come up with some alpha code that attempts to implement non-recursive WITH common table expressions. Having got this far, I feel that I need to ask for advice from some more experienced PostgreSQL hackers and so I post the alpha version here. The patch attempts to alter the parser grammar, and using code modified from that used when processing subselects in the FROM clause, attempts to treat the CTE as if it were presented the same as a FROM subselect. My main issue at the moment is that the code in transformFromClauseItem seems a terrible hack, mainly because the grammar returns each string within the FROM clause as a RangeVar, and transformFromClauseItem assumes that each RangeVar represents a physical relation. Of course, this is not the case when referencing a CTE and so the code first checks to see if an entry has already been created when processing the WITH clause; if it does then we return NULL to indicate that transformFromClause should do nothing. Messy, but I wanted to see what other developers thought before jumping in and rewriting this part of the code. Another point to think about is what should a query return if the SELECT doesn't refer to a CTE? For example: - WITH foo(a, b) AS (SELECT * FROM pg_class) SELECT * FROM pg_class; Since I've inserted the CTE as a range table entry of type RTE_SUBQUERY then the current behaviour is to perform a cross-join between foo and bar which I'm not sure is the correct behaviour since CTEs seem to be more like views in this respect. Finally, the current code fails when supplying an additional alias to a CTE in the select statement and then trying to refer to it, e.g. - with myrel(p1) as (select oid from pg_class) select myrel.p1 from myrel AS foo, pg_class AS bar WHERE myrel.p1 = bar.oid; -- WORKS - with myrel(p1) as (select oid from pg_class) select myrel.p1 from myrel AS foo, pg_class AS bar WHERE foo.p1 = bar.oid; -- FAILS ERROR: missing FROM-clause entry for table "foo" at character 103 So in this case, should foo be accepted as a valid alias for myrel? My feeling is that I will end up with an RTE_CTE range table entry kind which borrows from the current subquery behaviour, but it would be very useful to see where the similarity between the two range table entry types ends. TIA, Mark.
Вложения
В списке pgsql-patches по дате отправления: