Reputation: 2080
I'm trying to learn SQL, using PostgreSQL 9.1.3. I would like to understand some behavior that strikes me as inconsistent. To wit:
This works:
WITH innermost AS (SELECT 2)
SELECT * FROM innermost
UNION SELECT 3;
I get this:
?column?
----------
2
3
This works:
WITH outmost AS (
(WITH innermost AS (SELECT 2)
SELECT * FROM innermost)
)
SELECT * FROM outmost;
Result:
?column?
----------
2
This also works:
WITH outmost AS (
SELECT 1
UNION (WITH innermost AS (SELECT 2)
SELECT * FROM innermost)
)
SELECT * FROM outmost;
I get this:
?column?
----------
1
2
But this does not work:
WITH outmost AS (
SELECT 1
UNION (WITH innermost as (SELECT 2)
SELECT * FROM innermost
UNION SELECT 3)
)
SELECT * FROM outmost;
Result:
ERROR: relation "innermost" does not exist
LINE 4: SELECT * FROM innermost
To my way of thinking, either the last one should succeed or one of the other ones should fail. I don't see the pattern. Is there some general rule that would enable me to predict what combinations of nested CTEs and UNIONs will or will not work?
Upvotes: 35
Views: 12521
Reputation: 2080
The mystery is solved: the behavior I was observing is a known bug. I sent the same original post to a PostgreSQL-specific list and got this answer:
This is a bug :-(. The parse analysis code seems to think that WITH can only be attached to the top level or a leaf-level SELECT within a set operation tree; but the grammar follows the SQL standard which says no such thing. The WITH gets accepted, and attached to the intermediate-level UNION which is where syntactically it should go, and then it's entirely ignored during parse analysis. Will see about fixing it.
regards, tom lane
http://archives.postgresql.org/pgsql-novice/2012-07/msg00113.php
Upvotes: 31