Thread: BUG #17061: Impossible to query the fields of the tuple created by SEARCH BREADTH FIRST BY .. SET ..
BUG #17061: Impossible to query the fields of the tuple created by SEARCH BREADTH FIRST BY .. SET ..
From
PG Bug reporting form
Date:
The following bug has been logged on the website: Bug reference: 17061 Logged by: Benoit Lobréau Email address: blo.talkto@gmail.com PostgreSQL version: 14beta1 Operating system: Fedora 33 Description: Hi, I try to access the field inside the tuple generated by SEARCH BREADTH FIRST. A use case would be to get all the records with depth 3. I fail to access it and I don't understand the error. I wonder if it works as intended ? Here is a test case : DROP TABLE tree; CREATE TABLE tree(id int, parent_id int, name text); ALTER TABLE tree ADD PRIMARY KEY (id); INSERT INTO tree(id, parent_id, name) VALUES (1, NULL, 'Albert'), (2, 1, 'Bob'), (3, 1, 'Barbara'), (4, 1, 'Britney'), (5, 3, 'Clara'), (6, 3, 'Clement'), (7, 2, 'Craig'), (8, 5, 'Debby'), (9, 5, 'Dave'), (10, 9, 'Edwin'); -- The following query shows that the fields of the tuple are named: -- -- row_to_json -- ----------------------- -- {"*DEPTH*":0,"id":1} -- {"*DEPTH*":1,"id":2} -- {"*DEPTH*":1,"id":3} -- {"*DEPTH*":1,"id":4} -- {"*DEPTH*":2,"id":5} -- {"*DEPTH*":2,"id":6} -- {"*DEPTH*":2,"id":7} -- {"*DEPTH*":3,"id":8} -- {"*DEPTH*":3,"id":9} -- {"*DEPTH*":4,"id":10} -- (10 rows) WITH RECURSIVE mtree(id, name) AS ( SELECT id, name FROM tree WHERE id = 1 UNION ALL SELECT t.id, t.name FROM tree AS t INNER JOIN mtree AS m ON t.parent_id = m.id ) SEARCH BREADTH FIRST BY id SET breadth SELECT row_to_json(breadth) FROM mtree m; -- So I try to get the "*DEPTH*" column but it fails with (I get the same error with (breadth).id) : -- -- ERROR: CTE m does not have attribute 3 WITH RECURSIVE mtree(id, name) AS ( SELECT id, name FROM tree WHERE id = 1 UNION ALL SELECT t.id, t.name FROM tree AS t INNER JOIN mtree AS m ON t.parent_id = m.id ) SEARCH BREADTH FIRST BY id SET breadth SELECT (breadth)."*DEPTH*" FROM mtree m; -- The following works but feels a little hacky WITH RECURSIVE mtree(id, name) AS ( SELECT id, name FROM tree WHERE id = 1 UNION ALL SELECT t.id, t.name FROM tree AS t INNER JOIN mtree AS m ON t.parent_id = m.id ) SEARCH BREADTH FIRST BY id SET breadth SELECT row_to_json(breadth) -> '*DEPTH*' FROM mtree m;
Re: BUG #17061: Impossible to query the fields of the tuple created by SEARCH BREADTH FIRST BY .. SET ..
From
Tom Lane
Date:
[ screwed up the cc somehow the first time, sorry for the duplicate ] PG Bug reporting form <noreply@postgresql.org> writes: > WITH RECURSIVE mtree(id, name) AS ( ... > ) SEARCH BREADTH FIRST BY id SET breadth > SELECT (breadth)."*DEPTH*" > FROM mtree m; > ERROR: CTE m does not have attribute 3 Yeah, I get that with "SELECT (breadth).*" as well. I'm not entirely sure what this silly-looking syntax is supposed to mean, but it seems to be adding an output column named "breadth" to the CTE. The error is occurring because said column has not been added to the relevant CommonTableExpr struct. Peter? regards, tom lane
Re: BUG #17061: Impossible to query the fields of the tuple created by SEARCH BREADTH FIRST BY .. SET ..
From
talk to ben
Date:
On Thu, Jun 17, 2021 at 4:50 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
[ screwed up the cc somehow the first time, sorry for the duplicate ]
PG Bug reporting form <noreply@postgresql.org> writes:
> WITH RECURSIVE mtree(id, name) AS ( ...
> ) SEARCH BREADTH FIRST BY id SET breadth
> SELECT (breadth)."*DEPTH*"
> FROM mtree m;
> ERROR: CTE m does not have attribute 3
Yeah, I get that with "SELECT (breadth).*" as well. I'm not entirely sure
what this silly-looking syntax is supposed to mean, but it seems to be
adding an output column named "breadth" to the CTE. The error is
occurring because said column has not been added to the relevant
CommonTableExpr struct. Peter?
regards, tom lane
Quick update : I checked if BETA2 somehow fixed it, it didn't.
Re: BUG #17061: Impossible to query the fields of the tuple created by SEARCH BREADTH FIRST BY .. SET ..
From
Peter Eisentraut
Date:
On 17.06.21 13:44, PG Bug reporting form wrote: > -- So I try to get the "*DEPTH*" column but it fails with (I get the same > error with (breadth).id) : > -- > -- ERROR: CTE m does not have attribute 3 > > WITH RECURSIVE mtree(id, name) AS ( > SELECT id, name > FROM tree > WHERE id = 1 > UNION ALL > SELECT t.id, t.name > FROM tree AS t > INNER JOIN mtree AS m ON t.parent_id = m.id > ) SEARCH BREADTH FIRST BY id SET breadth > SELECT (breadth)."*DEPTH*" > FROM mtree m; We could put a workaround for this into expandRecordVariable() to handle the extra columns similar to what we have in markTargetListOrigin(), but it's still not going to work, because then you'll get ERROR: record type has not been registered This is similar to what you get now if you write something like ... ) SEARCH DEPTH FIRST BY id SET seq SELECT (seq[1]).* FROM mtree m; It's not really meant to be used that way. I'm not sure whether it's worth spending extra effort on. > -- The following works but feels a little hacky > > WITH RECURSIVE mtree(id, name) AS ( > SELECT id, name > FROM tree > WHERE id = 1 > UNION ALL > SELECT t.id, t.name > FROM tree AS t > INNER JOIN mtree AS m ON t.parent_id = m.id > ) SEARCH BREADTH FIRST BY id SET breadth > SELECT row_to_json(breadth) -> '*DEPTH*' > FROM mtree m; This works because it does not require type information for the fields in the row you're digging into (which is what the "registering" of the record type would accomplish).
Re: BUG #17061: Impossible to query the fields of the tuple created by SEARCH BREADTH FIRST BY .. SET ..
From
Michael Paquier
Date:
On Tue, Jul 06, 2021 at 07:56:10PM +0200, Peter Eisentraut wrote: > It's not really meant to be used that way. I'm not sure whether it's worth > spending extra effort on. Peter has contacted the RTM about this issue, and we are classifying this item as a "won't fix" per this argument. -- Michael
Attachment
Re: BUG #17061: Impossible to query the fields of the tuple created by SEARCH BREADTH FIRST BY .. SET ..
From
talk to ben
Date:
On Sat, Jul 31, 2021 at 3:40 AM Michael Paquier <michael@paquier.xyz> wrote:
Thanks for the explanation and the awesome work on PostgreSQL.
On Tue, Jul 06, 2021 at 07:56:10PM +0200, Peter Eisentraut wrote:
> It's not really meant to be used that way. I'm not sure whether it's worth
> spending extra effort on.
Peter has contacted the RTM about this issue, and we are classifying
this item as a "won't fix" per this argument.
--
Michael
Hi,
Sorry, for the delayed answer.
I am a little surprised, when I see client who create that kind of hierarchical queries they usually
want to have the depth or the path in the return query. And then they realise that they should
protect them selves from loops and deep recursions after an incident where queries wouldn't
stop or ran for too long.
So if they want the data and the protection in v14, they have to either :
* use the feature but recompute the column that the feature built internally (or use the json trick);
* not use the feature at all and do it the old way.
It seems counterintruitive to me.
Thanks for the explanation and the awesome work on PostgreSQL.
Benoit
Re: BUG #17061: Impossible to query the fields of the tuple created by SEARCH BREADTH FIRST BY .. SET ..
From
Jaime Casanova
Date:
On Thu, Jun 17, 2021 at 10:50:14AM -0400, Tom Lane wrote: > [ screwed up the cc somehow the first time, sorry for the duplicate ] > > PG Bug reporting form <noreply@postgresql.org> writes: > > WITH RECURSIVE mtree(id, name) AS ( ... > > ) SEARCH BREADTH FIRST BY id SET breadth > > SELECT (breadth)."*DEPTH*" > > FROM mtree m; > > ERROR: CTE m does not have attribute 3 > > Yeah, I get that with "SELECT (breadth).*" as well. I'm not entirely sure > what this silly-looking syntax is supposed to mean, but it seems to be > adding an output column named "breadth" to the CTE. The error is > occurring because said column has not been added to the relevant > CommonTableExpr struct. Peter? > Just to add fuel to the fire, I just noted that you cannot create a view based on a recursive CTE using this syntax. """ create view v1 as WITH RECURSIVE mtree(id, name) AS ( SELECT id, name FROM tree WHERE id = 1 UNION ALL SELECT t.id, t.name FROM tree AS t INNER JOIN mtree AS m ON t.parent_id = m.id ) SEARCH BREADTH FIRST BY id SET breadth SELECT * FROM mtree m; ERROR: column "breadth" has pseudo-type record """ -- Jaime Casanova Director de Servicios Profesionales SystemGuards - Consultores de PostgreSQL
Re: BUG #17061: Impossible to query the fields of the tuple created by SEARCH BREADTH FIRST BY .. SET ..
From
Tom Lane
Date:
Jaime Casanova <jcasanov@systemguards.com.ec> writes: > Just to add fuel to the fire, I just noted that you cannot create a view > based on a recursive CTE using this syntax. > ... > ERROR: column "breadth" has pseudo-type record Yeah, I've run into that too. There's no time to reconsider the implementation for v14, but I'd sure like to see this revisited later. I'm kind of wondering if, instead of a single RECORD column, we could add each of the SEARCH columns and the depth column as a separate resjunk column. (However, I'm not sure how to extend that approach to the DEPTH FIRST case, which wants an array.) regards, tom lane