Skip to content

Add with_ clause for Common Table Expressions - #1440

Open
SahilRajputdotexe wants to merge 1 commit into
piccolo-orm:masterfrom
SahilRajputdotexe:feat/cte-support
Open

SahilRajputdotexe wants to merge 1 commit into
piccolo-orm:masterfrom
SahilRajputdotexe:feat/cte-support

Conversation

@SahilRajputdotexe

Copy link
Copy Markdown

Closes #1439

This adds support for WITH clauses (Common Table Expressions) on Select, Update, Delete and Insert queries.

You build a CTE from a name and a body, which can be a query or a QueryString, and pass it to with_. CTE.recursive makes a WITH RECURSIVE expression from a base and a recursive part, and materialized=True/False adds the MATERIALIZED / NOT MATERIALIZED hint. CTE.ref() returns a CTERef for the declared column_names, so the columns can be referred to by name. Mistakes like an invalid name, a duplicate name or a column count that doesn't match raise CTEError.

reports = CTE.recursive(
    "reports",
    base=QueryString('SELECT "id", 0 FROM "employee" WHERE "id" = {}', 2),
    recursive=QueryString(
        'SELECT "employee"."id", "reports"."depth" + 1 FROM "employee" '
        'JOIN "reports" ON "employee"."manager_id" = "reports"."id"'
    ),
    column_names=["id", "depth"],
)

await Employee.select(Employee.name).where(
    Employee.id.is_in(QueryString('SELECT "id" FROM "reports"'))
).with_(reports)

The CTE is referred to from the main query through raw SQL like above. I didn't try to add joins against a CTE, to keep this small.

I added a docs page under query clauses, and tests/query/test_cte.py, which checks the generated SQL and runs select, update, delete and insert against the test database. isort, black, flake8, mypy and slotscheck are clean, and I ran the new tests with SQLite locally and the Postgres and CockroachDB jobs on my fork.

Adds `CTE`, `CTERef`, `CTEColumn` and `CTEError` to `piccolo.query`, and a
`with_` method on `Select`, `Update`, `Delete` and `Insert` which prepends
a `WITH` (or `WITH RECURSIVE`) clause to the query.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support CTEs (WITH clause) in queries

1 participant