jawj / zapatos

Zero-abstraction Postgres for TypeScript: a non-ORM database library
https://jawj.github.io/zapatos/
Other
1.3k stars 46 forks source link

Type error when using `SELECT FOR UPDATE` with schemas outside the default search path #118

Open codetheweb opened 2 years ago

codetheweb commented 2 years ago

Currently, the of parameter of the lock option accepts a Table string. This doesn't type check properly when using a schema outside the default search path, as the Zapatos type expects myschema.mytable to be provided to of but the correct syntax is mytable (will throw with FOR NO KEY UPDATE must specify unqualified relation names if myschema.mytable is provided).

In other words, this generates the correct query but throws a type error:

await db.selectOne(
  "myschema.mytable", 
  { id: "sample-id" }, 
  {
    lock: {
      for: "NO KEY UPDATE",
      of "mytable"
    }
  }
).run(pool)

This isn't urgent as we can just manually cast mytable as Table for now. :)

jawj commented 2 years ago

Thanks @codetheweb. Have reproduced.

Two options come to mind: we could make things more complex by introducing an UnprefixedTables type, and using that for the of option of lock; or we could simplify things by typing the of option simply as string.

I think I might lean towards the latter option, if only because it's also possible to specify a table alias for of, which is ruled out by the more complex solution (although I guess you'd still have that option to manually cast to UnprefixedTable). For example:

db.select("UK.constituencies", db.all, { alias: "uc", lock: { for: "UPDATE", of: "uc" } })

What do you think?

codetheweb commented 2 years ago

Good point, I think typing it as string makes sense.

jawj commented 2 years ago

Great. In fact I had a rethink, realising it's quite simple to take off the schema with a template string type. This is on master now, plus it also lets you use the alias from the alias option.

I'm away this week, but I'll release a new version when I'm back.