postgres icon indicating copy to clipboard operation
postgres copied to clipboard

feat: sql.join

Open DanielFGray opened this issue 1 year ago • 8 comments

closes #807, to add sql.join:

let dynamicFilters = [
  sql`somecol = ${somevalue}`,
  sql`col2 = ${v2}`
];
const dynamicColumns = [sql('somecol'), sql('col2')];
await sql`
  select ${sql.join(sql`, `, dynamicColumns)} from t
  where ${sql.join(sql` and `, dynamicFilters)};
`;

i'm not 100% sure the types are right, and I couldn't get the tests to run, so those probably need some work

DanielFGray avatar Jun 27 '24 15:06 DanielFGray

if you have a weird workaround you can try this fix in your own projects

npm i github:danielfgray/postgres.js

@Destreyf @davepar your feedback would be appreciated!

DanielFGray avatar Jun 27 '24 15:06 DanielFGray

I also really want to enable currying to allow things like

const and = sql.join(sql` and `)
and(sql`...`, ...fragments)

which could be as simple as

- function join(sep, xs) {
+ function join(sep, ...xs) {
+   if (!xs) return join.bind(null, sep)
    return xs.flatMap((x, i) => {

but this would probably also need further bike-shedding

I also wonder if the API could be further improved to simply allow

const and = sql.join` and `
const params = and(f1, f2, f3)
// would work the same as
const params = sql.join` and `(f1, f2, f3)

I'm not sure that postgres.js goals are to be a whole query builder, but it seems like we can add a lot of expressivity with a few tweaks to a simple feature

but currying is likely to increase the complexity of the TS types and perhaps make the API more complex and difficult to document :balance_scale:

DanielFGray avatar Jun 27 '24 16:06 DanielFGray

neat feature, hope this makes it in +rep

phosmium avatar Jun 27 '24 20:06 phosmium

I agree though that it should not be called "join" to avoid confusion with SQL's JOIN statements. In my opinion, "sql.concat" is a better choice.

dhardtke avatar Jul 14 '24 15:07 dhardtke

solid addition 👍

maumercado avatar Jul 17 '24 16:07 maumercado

I agree though that it should not be called "join" to avoid confusion with SQL's JOIN statements. In my opinion, "sql.concat" is a better choice.

I've gone back and forth on this in my head, and while there's definitely potential for ambiguity, join here is behaving the same as it does on arrays

It would be even more surprising behavior to me to have something called concat behaving as Array#join, and if a user is confused on what sql.join does the docs would explain. I also think actually seeing the code in context would pretty well indicate it has nothing to do with the SQL clause

So all this is to say, semantically, I think join is the best name for this feature

DanielFGray avatar Jul 19 '24 02:07 DanielFGray

What's required to get this in? I also struggled discovering how to do this expecting the library to provide a mechanism.

jantoine1 avatar Jan 15 '25 22:01 jantoine1

What's required to get this in? I also struggled discovering how to do this expecting the library to provide a mechanism.

getting the tests to pass is probably the main blocker

DanielFGray avatar Jan 16 '25 12:01 DanielFGray

I'd like the api to be like this:


sql` and `.join(...)

porsager avatar Oct 14 '25 13:10 porsager

I consider this PR a success then, even if my implementation/API aren't used

DanielFGray avatar Oct 17 '25 23:10 DanielFGray

May I ask @DanielFGray why you closed your PR? I had hopes that after your recent change to the API to match @porsager's request it might get merged soon..

dhardtke avatar Oct 22 '25 18:10 dhardtke

May I ask why you closed your PR?

@dhardtke the work in the PR itself is pretty trivial, and I don't currently have the time/energy to work on refactoring it, so I'll step aside rather than impede progress.

DanielFGray avatar Oct 24 '25 14:10 DanielFGray