-
Notifications
You must be signed in to change notification settings - Fork 282
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
Support json_agg(column_ref)
.
#1280
Comments
Good idea! We express left joined tables in the We have no way to tell if a column is nullable in We could express left joined tables in {
person: Person,
leftJoined: Pet | null
} But that's a big type overhaul and most likely a breaking change. |
Another example of how this could be used is when using subqueries instead of joins. Here's something I found out about it: This query (though correct in TypeScript) fails when executing: const result = await db
.selectFrom("person")
.select((eb) => [
eb.fn.jsonAgg(eb
.selectFrom("pet")
.whereRef("pet.owner_id", "=", "person.id")
.select("pet.name"))
.as("person_pets"),
])
.executeTakeFirstOrThrow() The error message is:
But if you have another select on the outer query, you'd even get an error for that you'd have to group on each of the selected columns, which is confusing 🙈 This query can run on postgres, but is invalid as of TypeScript - hence this ticket: const result = await db
.selectFrom("person")
.select((eb) => [
eb
.selectFrom("pet")
.whereRef("pet.owner_id", "=", "person.id")
.select(eb => eb.fn.jsonAgg("pet.name"))
.as("person_pets"),
])
.executeTakeFirstOrThrow() If there's anything I can help with to get this done, please write, and I'll be happy to pick it up and see whether I can get it to PR-state! |
Hey 👋 It's yours. Swing by Discord if you've got any questions. DMs (to me) also welcome. |
If you need a work-around, you can cast the types as following (the type import { RawBuilder, ExtractTypeFromStringReference } from 'kysely'
const result = await db
.selectFrom("person")
.select((eb) => [
eb
.selectFrom("pet")
.whereRef("pet.owner_id", "=", "person.id")
.select(eb => eb.fn.jsonAgg("pet.name" as unknown as "pet") as unknown as RawBuilder<ExtractTypeFromStringReference<DB,"pet","name">[] | null>)
.as("person_pets"),
])
.executeTakeFirstOrThrow() import { RawBuilder, ExtractTypeFromStringReference } from 'kysely'
const result = await db
.selectFrom('person')
.innerJoin('pet', 'pet.owner_id', 'person.id')
.select((eb) =>
(eb.fn.jsonAgg("pet.name" as unknown as "pet") as unknown as RawBuilder<ExtractTypeFromStringReference<DB,"pet","name">[] | null>).as('person_pets')
)
.executeTakeFirstOrThrow() In case you don't want the aggregated property to be a union with import { sql, RawBuilder, ExtractTypeFromStringReference } from 'kysely'
const result = await db
.selectFrom('person')
.innerJoin('pet', 'pet.owner_id', 'person.id')
.select((eb) =>
eb.fn.coalesce(
(eb.fn.jsonAgg("pet.name" as unknown as "pet") as unknown as RawBuilder<ExtractTypeFromStringReference<Database,"pet","name">[] | null>),
sql<never[]>`'[]'`,
).as('person_pets')
)
.groupBy("person.id")
.executeTakeFirstOrThrow() This is not because of some typings in Kysely, but |
Hey 👋
Currently
eb.fn.jsonAgg
supports table names and expressions as inputs. In such cases, the return type is a JSON object array.json_agg
also supports passing a column reference. In such cases, the return type is a literal array.We should support this.
The return type would be
{ person_pets: string[] }
.The text was updated successfully, but these errors were encountered: