Skip to content
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

Allow partial pipelining within a transaction #951

Open
astralarya opened this issue Sep 23, 2024 · 4 comments
Open

Allow partial pipelining within a transaction #951

astralarya opened this issue Sep 23, 2024 · 4 comments

Comments

@astralarya
Copy link

Allow pipelining the some requests in a transaction without requiring that all the requests are pipelined. This would allow selecting to get the id of a row, then issuing multiple statements based on the id of the row in a pipelined fashion.

For example:

await sql.begin(async sql => {
  const [movie] = await sql`
    SELECT * FROM Movie
    WHERE name = 'Star Wars'
  `;
  return [
    sql`
      INSERT INTO MovieActor
      -- some statement using ${movie.id}
    `,
    sql`
      INSERT INTO MovieReleases
      -- some statement using ${movie.id}
    `,
     // etc
  ]
})
@astralarya
Copy link
Author

astralarya commented Oct 3, 2024

Alternatively, maybe there could be a specific sql.pipeline() function, which would accept an array of sql statements to pipeline. This would allow opening a transaction and running some non-pipelined statements before and after a block of pipelined statements.

@porsager
Copy link
Owner

porsager commented Oct 3, 2024

I think your example is great, and ought to work :) Also for doing it in the middle of other queries this should be supported:

await sql.begin(async sql => {
  const [movie] = await sql`
    SELECT * FROM Movie
    WHERE name = 'Star Wars'
  `
  
  await Promise.all([
    sql`
      INSERT INTO MovieActor
      -- some statement using ${movie.id}
    `,
    sql`
      INSERT INTO MovieReleases
      -- some statement using ${movie.id}
    `,
     // etc
  ])
  
  await sql` ... something else `
})

I might have some time to toy with this soon, but if you want to take a stab at it, feel free :)

@porsager
Copy link
Owner

porsager commented Oct 3, 2024

Until then, are you sure your use case can't work with CTE's ?

@astralarya
Copy link
Author

I think Promise.all doesn't guarantee any sequencing, while pipelining with libpq does. This doesn't matter in many cases, but it can occasionally. For example, you could do an INSERT, then another INSERT that uses some aggregate that includes the first INSERT, etc.

CTEs can work in most situations, but it would be nice to have the option to pipeline statements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants