Unwanted db.execute() behavior; trying to pass in an array instead of a record or its singular
When trying to pass an array (ex.
number[]
, bigint[]
, string[]
) that contains only one element into sql``
, it will be transformed into their non-list type (ex. number
, bigint
, string
respectively).
When I put two elements in, it then turns into a Postgres record, which is not what I want. What I expect is that the array stays an array.
22 Replies
My incredibly rough reproduction that may or may not even work:
1. Create a function in PostgreSQL with a parameter that takes in an array.
2. Run the following (at least for the array -> singlar):
3. It should have failed; check logs in your console output.
Environment is the following:
- Node.js 18.17.1
- ARM64
- pnpm 8.7.6
- PostgreSQL 15
You can get the weird
record
behavior by just adding another uuid
into the array.
Note that the UUIDs are technically invalid (they're ULIDs), but this shouldn't matter, assuming Drizzle nor Postgres does any UUID validation. I'm also using the same one for sake of example, but that also shouldn't matter, presumably.
I could be doing this thing all wrong (I'm very much new to PostgreSQL and SQL in general), but for the complexity of whatever function I've just done, I think this is how I'm supposed to do it. I'm creating a Postgres function, writing my SELECT query, and conditional logic in it, then do my inserts depending on that, and then RETURN QUERY for whatever.
I don't think DrizzleORM has an equivalent to do this in one transaction, nor if I should even attempt to do that at all in DrizzleORM.
I'm looking more into the docs; I'm wondering if I just have to use sql.raw
perhaps for this one parameter, and somehow connect them all together? Or would that be considered unsafe? Would the typecast save me from raw SQL injection?This could be a workaround:
I thought the weird behavior was only when the array only had one element
I think there are issues with how an array is handled right now in drizzle, give me a sec, I show you a workaround
ah got it;
1. there's two issues, that feel connected. it'd either be one element, or it'd be a record, instead of an array
2. square brackets don't seem to be valid syntax?
i'd presume it'd be
{}
instead, unless im mistaken, at least judging by my raw SQL query that for sure worksCan you show me your raw sql query?
This query is whatever I have right now in pgAdmin, and it works
just sanity-checked it; this function's been the bane of my existance for a few days 😝
would be unsurprised if it suddenly broke
You would like those values to be dynamic? Or are they hardcoded like that?
yeah, i'd like the values to be dynamic
currently, i pull these values from the client from a Discord button + a client fetch of a user's UUID
for certain future plans, im worried about malicious user input inside that button somehow
I got you, there are workaround, give me a couple secs
Oh, forgot to mention, you might want to use the
mapWith()
method for choiceIds to have types
is the
.mapWith
required? i'm currently hitting PostgresError: syntax error at or near "{"
and im not sure if that's related, as I have to change your example to match what query I actually need to do (which is a direct sql one, to call a postgres function)
Also to sanity check; is this the expected output (at least without .mapWidth
)?
if it is required, any leads on how I'd figure that fnToMap
out for Postgres.js? I'm looking at their GitHub right now, and nothing particularly stands out to me. Tried using choice.id
from my schemaNo, I believe I've made a mistake, I'm doing it from memory, I don't have anything pg setup to test
ah, i should specify; im using postgres.js, not pg
or so i believe
But the idea is to create a
SQL[]
, and then join it with the sql.join
method
That way you can sanitize your input
This a very constrained example/issue. If you send a reproduction repo I could assist furtherGitHub
GitHub - some1chan/drizzle-repro
Contribute to some1chan/drizzle-repro development by creating an account on GitHub.
hope this helps!
let me know if you run into any issues with running the repro
This is the important bit:
This is workaround after workaround lol
The important part is that the sanitation is done with
oh wow, that's quite some code
seems to work on my end, thank you!
update: need to sanity check a few things
update: forgot to remove a line, which broke the query. oops!
also just to clarify on Drizzle's stability; would I be able to expect this code to be stable, or should I really do some test cases (especially for the
queryChunks[1]!
)? or should I just not be using Drizzle in prod at all, and I'm doing something really riskyI don't see the sql operator changing any time soon
We have to do all this, just because drizzle doesn't support the syntax around arrays passed to functions
Would you like to submit an issue for this? on the way we could implement the syntax for
'{sanitizedString, sanitizedString}'
?
Other than that, I don't see a problem with this code
cc @a_sherman, any thoughts?Will do! i'll probably add mention of also the singular issue too, as I'd believe this would be related
GitHub
[FEATURE]: Allow passing in an array into functions · Issue #1289 ·...
Describe what you want Currently, the default behavior of Drizzle will turn arrays into either its singular element, or a record. This behavior is unintuitive, when you're trying to pass in an ...
query chunks and SQL will work this way always, so if it's working, it will work later as well
and this one is helpful!
thanks for a GH issue, we will try to fix this one
that's why we have SQL operators to not block you while we are improving those parts
and great explanations in the ticket, very helpful