question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Feature request: Join on Postgres JSONB functions

See original GitHub issue

Feature Description

I have an array of IDs in a Postgres JSONB field that I need to join the secondary table on. Due to PG limitations such as inability to pass set-returning functions to Joins, I need to create a temporary table by Joining jsonb_array_elements_text.

TypeORM expects the first parameter of a Join method to be a table name. Passing in a JSONB method causes that to be wrapped in quotes, which expectedly fails. See below for code snippets.

The Problem

    queryBuilder
      .innerJoin("jsonb_array_elements_text(tableA.fields->'scIds')", "scid", "true")
      .addSelect("tableB.fields->>'number'", "container_number")
      .innerJoin(
        TableB,
        "tableB",
        "scid::uuid = tableB.id"
      )
      .orderBy("container_number", "ASC");

The desired SQL output is

SELECT ...
FROM "public"."tableA" "tableA" 
INNER JOIN jsonb_array_elements_text(tableA.fields->'scIds') scids on true 
INNER JOIN "public"."tableB" on scids::uuid = tableB.id
WHERE ... (conditions)

TypeORM expects a model name on Join methods which puts quotes around jsonb_array_elements_text and splits on ., resulting in:

INNER JOIN  "jsonb_array_elements_text(tableA"."fields->'scIds')"

The Solution

Two potential feature adds:

  1. Detect json* in the first Join arg and don’t wrap it in quotes.
  2. Add new methods such as rawInnerJoin and rawLeftJoin that use the first arg as-is without parsing.

Considered Alternatives

We crafted a subquery on the IDs array but it is VERY slow (8-10 seconds vs sub-second).

Relevant Database Driver(s)

DB Type Relevant
aurora-data-api no
aurora-data-api-pg no
better-sqlite3 no
cockroachdb no
cordova no
expo no
mongodb no
mysql no
nativescript no
oracle no
postgres yes
react-native no
sap no
sqlite no
sqlite-abstract no
sqljs no
sqlserver no

Are you willing to resolve this issue by submitting a Pull Request?

  • ✖️ Yes, I have the time, and I know how to start.
  • ✅ Yes, I have the time, but I don’t know how to start. I would need guidance.
  • ✖️ No, I don’t have the time, but I can support (using donations) development.
  • ✖️ No, I don’t have the time and I’m okay to wait for the community / maintainers to resolve this issue.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:9

github_iconTop GitHub Comments

1reaction
Gindencommented, Jan 10, 2022

@peacechen I used CTE for short snippet purposes.

Query built using query builder can look like (I didn’t test it):

    queryBuilder
      .addSelect("tableB.fields->>'number'", "container_number")
      .innerJoin(
        TableB,
        "tableB",
        "tableB.id IN (SELECT v::uuid FROM json_array_elements_text(tableA"."fields->'scIds') t(v))"
      )
      .orderBy("container_number", "ASC");

Also, there is following overload for innerJoin method:

    innerJoin(subQueryFactory: (qb: SelectQueryBuilder<any>) => SelectQueryBuilder<any>, alias: string, condition?: string, parameters?: ObjectLiteral): this;

So you can join against subquery.

0reactions
Gindencommented, Apr 16, 2022

I’m closing this issue - it seems to be out of scope for ORM to implement this unusual pattern, and there are workarounds.

Read more comments on GitHub >

github_iconTop Results From Across the Web

9.4: JSON Functions and Operators - PostgreSQL
Builds a JSON object out of a text array. The array must have either exactly one dimension with an even number of members,...
Read more >
PostgreSQL joining using JSONB
The way you have it, you'd first cast json / jsonb to text and then back to json . The clean way to...
Read more >
Working with Postgres JSON Query | Made Easy - Learn | Hevo
This article will help you discover several operators and functions to query JSON data in PostgreSQL, as well as how to work out...
Read more >
JSON in PostgreSQL: how to use it right - CYBERTEC
This article describes what can go wrong when using the much-loved JSON capabilities of PostgreSQL and gives guidelines how to do it right....
Read more >
Querying JSON (JSONB) data types in PostgreSQL - SILOTA
One of the unusual features of the PostgreSQL database is the ability to store and process JSON documents. In the past, data analysts...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found