Skip to content

WITH RECURSIVE support #1976

@Hydrocharged

Description

@Hydrocharged

A Postgres user has mentioned that they would require WITH RECURSIVE support in Doltgres.

https://www.postgresql.org/docs/15/queries-with.html#QUERIES-WITH-RECURSIVE

A description of how it's used, along with some example code provided by the user:

Inside our project, the output of the folder structure is then converted into a text search vector, so a user can type "subdir1" into a search bar, and get everything under that folder

The results of the select are then fed into materialized views for performance and are daily indexed

-- drop table file, folder;

CREATE TABLE "folder" (
    "id" INT PRIMARY key GENERATED ALWAYS AS IDENTITY,
    "name" VARCHAR NOT NULL,
    "parent_id" INTEGER REFERENCES "folder"("id")--,
    --constraint folder_name UNIQUE NULLS NOT DISTINCT (name, parent_id)
);

CREATE TABLE "file" (
    "id" INT PRIMARY key GENERATED ALWAYS AS IDENTITY,
    "name" VARCHAR NOT NULL,
    "parent_id" INTEGER REFERENCES "folder"("id"),
    "contents" TEXT--,
    --constraint folder_name UNIQUE NULLS NOT DISTINCT (name, parent_id)
);

insert into folder (name, parent_id) values
('dir1', null),
('dir2', null),
('dir3', null),
('dir4', null);



insert into folder (name, parent_id)
select t.name, folder.id
from (values 
('subdir1'),
('subdir2'),
('subdir3'),
('subdir4')
) AS t (name)
inner join folder on true;


insert into folder (name, parent_id)
select t.name, folder.parent_id
from (values 
('subsubdir1'),
('subsubdir2'),
('subsubdir3'),
('subsubdir4')
) AS t (name)
inner join folder on folder.parent_id is not null;

insert into file(name, parent_id, contents)
select t.name, folder.id, ''
from (values 
('file1.txt'),
('t.test')
) AS t (name)
inner join folder on true;

insert into file(name, parent_id, contents)
values ('root.txt', null, '');

update file
set name = id || '-' || name;


WITH RECURSIVE tree(id, parent_id, name) AS (
    select id, parent_id, array[name] from folder
  UNION ALL
    SELECT tree.id, folder.parent_id, folder.name || tree.name
    from tree
    inner join folder on folder.id = tree.parent_id 
)
select 
file.id,
coalesce(array_to_string(tree.name || file.name, '/'), file.name) as path
from file
left join tree on tree.parent_id is null and tree.id = file.parent_id
order by 2

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions