adelsz / pgtyped

pgTyped - Typesafe SQL in TypeScript
https://pgtyped.dev
MIT License
2.92k stars 95 forks source link

A way to specify which types are given to `VALUES` #517

Open timvandam opened 1 year ago

timvandam commented 1 year ago

Is your feature request related to a problem? Please describe. When using a parameter with VALUES (e.g. VALUES :myParam) I would like to be able to specify the types of all the values. Currently, it defaults to strings, with seemingly no way to change this. This forces me to provide strings and to cast these strings to integers in my query

Describe the solution you'd like Some syntax to (optionally) specify this For instance, @param myParam -> ((num1, num2)...) could become @param myParam -> ((num1: INTEGER, num2: INTEGER)...)

Additional context The query I would like to write:

/*
    @name bulkUpdateCardOwnership
    @param ownershipChanges -> ((cardId!: INTEGER, userId!: INTEGER)...)
*/
UPDATE "depositedCards"
SET "userId" = "tmp"."userId"
FROM (VALUES :ownershipChanges) AS "tmp" ("cardId", "userId")
WHERE "depositedCards"."id" = "tmp"."cardId";

Two work arounds: 1) using strings and casting to integers

/*
    @name bulkUpdateCardOwnership
    @param ownershipChanges -> ((cardId!, userId!)...)
*/
UPDATE "depositedCards"
SET "userId" = ("tmp"."userId" :: INTEGER)
FROM (VALUES :ownershipChanges) AS "tmp" ("cardId", "userId")
WHERE "depositedCards"."id" = ("tmp"."cardId" :: INTEGER);

Generates:

/** 'BulkUpdateCardOwnership' parameters type */
export interface IBulkUpdateCardOwnershipParams {
  ownershipChanges: readonly ({
    cardId: string,
    userId: string
  })[];
}

2) adding sample numeric values, and remove them with an offset (it now seems to recognize that the values are integers

/*
    @name bulkUpdateCardOwnership
    @param ownershipChanges -> ((cardId!, userId!)...)
*/
UPDATE "depositedCards"
SET "userId" = "tmp"."userId"
FROM (VALUES (0, 0), :ownershipChanges OFFSET 1) AS "tmp" ("cardId", "userId")
WHERE "depositedCards"."id" = "tmp"."cardId";

Generates:

/** 'BulkUpdateCardOwnership' parameters type */
export interface IBulkUpdateCardOwnershipParams {
  ownershipChanges: readonly ({
    cardId: number,
    userId: number
  })[];
}
timvandam commented 1 year ago

This issue is also pointed out in #498

timvandam commented 1 year ago

Also identical to #450. Feel free to close since that issue is closed too