pglite icon indicating copy to clipboard operation
pglite copied to clipboard

QueryFailedError: Invalid input for boolean type

Open capaj opened this issue 3 months ago • 1 comments

Summary

When executing an UPDATE that sets a boolean column using TypeORM parameters (either Repository.update(...) or QueryBuilder.update().set({...})), pglite throws “Invalid input for boolean type”. The same code works on real PostgreSQL. Emitting SQL boolean literals (TRUE/FALSE) or casting parameters to boolean fixes it.

Library: typeorm-pglite

Environment

  • OS: Linux
  • Node: 20.x
  • TypeORM: 0.3.x
  • typeorm-pglite: latest (main)
  • DB: pglite (in-memory). On real PostgreSQL, this does not reproduce.

Minimal reproduction

  1. Define an entity with a boolean column, e.g. isReady:
@Entity('Submission')
export class Submission {
  @PrimaryGeneratedColumn('uuid')
  id!: string;

  @Column({ type: 'boolean', default: false })
  isReady!: boolean;
}
  1. Initialize a TypeORM DataSource using the pglite driver, run migrations, insert one row.

  2. Update the boolean using TypeORM parameters (works on PostgreSQL, fails on pglite):

await dataSource.getRepository(Submission).update({ id }, { isReady: true });
// or
await dataSource
  .getRepository(Submission)
  .createQueryBuilder()
  .update(Submission)
  .set({ isReady: true })
  .where('id = :id', { id })
  .execute();

Expected behavior

Update succeeds; isReady becomes true (matches PostgreSQL behavior).

Actual behavior (pglite)

Throws:

QueryFailedError: Invalid input for boolean type

Notes / Analysis

  • This appears to be a parameter binding/coercion issue for booleans in pglite. PostgreSQL accepts boolean parameters and common coercions (true/false, 1/0, 't'/'f'), but pglite rejects the parameterized value as provided by TypeORM in UPDATE/SET.
  • The issue is specific to booleans set via parameters in UPDATE. Using SQL boolean literals or explicit casts works.

Workarounds

  • Use boolean literals:
await repo
  .createQueryBuilder()
  .update(Submission)
  .set({ isReady: () => (someBool ? 'TRUE' : 'FALSE') })
  .where('id = :id', { id })
  .execute();
  • Or cast a parameter to boolean (keeps parameterization):
await repo
  .createQueryBuilder()
  .update(Submission)
  .set({ isReady: () => ':val::boolean' })
  .where('id = :id', { id })
  .setParameters({ id, val: someBool })
  .execute();

Both work in pglite and PostgreSQL.

Suggested fix

Adjust boolean parameter handling in pglite’s driver layer so TypeORM-bound params for boolean columns are accepted during UPDATE/SET, matching PostgreSQL semantics. Concretely:

  • Ensure bound parameters of JS boolean are serialized to a format pglite recognizes as boolean (e.g., literal true/false or 't'/'f') rather than a representation that triggers “Invalid input for boolean type”.

Additional context

  • Real PostgreSQL accepts the original Repository.update({...}) and QueryBuilder.update().set({...}) with boolean params without error.
  • The workaround above unblocks tests and production code that must run under pglite.

capaj avatar Sep 10 '25 06:09 capaj

Hey @capaj

Did you end up with implementing any of workaround? I am facing the same issue

abuaboud avatar Nov 22 '25 01:11 abuaboud