Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Support PostgreSql UnNest Array to rows #5673

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
May 15, 2025

Conversation

griffio
Copy link
Contributor

@griffio griffio commented Feb 27, 2025

Support Unnest Function - expand an array to a set of rows

fixes #5346

🪹 🏗️ Work
🚧 🪺 In Progress

  • Add "unnest" to PostgreSql.bnf
  • Add mixins to help with column resolving as there are new aliases used by "unnest" in FROM
  • Update PostresqResolver to handle converting Array to T - this was not supported by IntermediateType
  • Add TableFunctionRowType to allow new concept of nested type to row type - not an actual table
  • Add fixture and integration tests

Prototype use project https://github.com/griffio/sqldelight-postgres-unnest

  • PostgreSQL allows a function (e.g unnest) to be written directly as a member of the FROM list. Allows multiple arrays to be unnested
  • SELECT unnest() allows a single array to be unnested

Examples:

Allows "Array DML" - e.g bulk inserts, updates and deletes

CREATE TABLE Business(
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    zipcodes TEXT[] NOT NULL,
    headcounts INTEGER[] NOT NULL
);

CREATE TABLE Users (
   name TEXT NOT NULL,
   age INTEGER NOT NULL
);

select:
SELECT name, location.headcount, location.zipcode
FROM Business, UNNEST(zipcodes, headcounts) AS location(zipcode, headcount);

counts:
SELECT name, UNNEST(headcounts) AS headcount
FROM Business
ORDER BY headcount DESC;

array:
SELECT unnest('{1,2}'::INTEGER);

insertUsers:
INSERT INTO Users (name, age)
SELECT * FROM UNNEST(?::TEXT[], ?::INTEGER[])  AS u(name, age); 
// currently must explicitly add alias columns due to wildcard expansion in SqlDelight

updateUsers:
UPDATE Users
SET age = updates.updated_age
FROM UNNEST(?::TEXT[], ?::INTEGER[]) AS updates(name, updated_age)
WHERE Users.name = updates.name;

deleteUsers:
DELETE FROM Users
WHERE (name, age) IN (
  SELECT *
  FROM UNNEST(?::TEXT[], ?::INTEGER[]) AS u(name, age)
);

selectLocations:
SELECT DISTINCT b.*
FROM Business b
JOIN LATERAL UNNEST(b.zipcodes) AS loc(zipcode) ON loc.zipcode ILIKE '%' || :query || '%';

selectBusinessExists:
SELECT *
FROM business
WHERE EXISTS (
    SELECT 1
    FROM unnest(locations) AS loc 
    WHERE lower(loc) LIKE '%' || LOWER(:query::TEXT) || '%'
);
  • TODO
    • Add current limitations and problems
      • PostgreSql allows functions declared after FROM e.g. FROM upper('a') or FROM unnest(...)
        • This is not supported in SqlDelight and is the actual issue

@griffio griffio force-pushed the add-5346-postgresql-unnest branch from 1afcdb6 to fb72bf6 Compare March 19, 2025 19:32
@griffio griffio force-pushed the add-5346-postgresql-unnest branch from fb72bf6 to c75e6b3 Compare May 15, 2025 13:03
griffio added 10 commits May 15, 2025 14:40
Add unnest to PostgreSql.bnf
Add mixins to help with column resolving
Update PostresqResolver to handle converting Array<T> to T
Add TableFunctionRowType to allow new concept of Nested type to Row type
Try and support WHERE clause
Add where exists
For where clause
Update TableFunctionTableAliasMixin.kt
Add test for LATER UNNEST
fix `The Kotlin type of the argument cannot be inferred, use CAST instead`

LOWER and UPPER are no longer for TEXT but can be used with ranges so the bind param cannot be inferred
@griffio griffio force-pushed the add-5346-postgresql-unnest branch from c75e6b3 to 25d7493 Compare May 15, 2025 13:40
@griffio griffio marked this pull request as ready for review May 15, 2025 13:44
Copy link
Collaborator

@AlecKazakova AlecKazakova left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

amazing, thank you

@AlecKazakova AlecKazakova merged commit 17deef2 into sqldelight:master May 15, 2025
11 checks passed
@griffio griffio deleted the add-5346-postgresql-unnest branch May 15, 2025 17:51
@Angel-Ponce
Copy link

What version should to be installed to use this feature?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

postgresql: unable to use unnest(...) in subquery
3 participants