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

Relations do not render primary key column values correctly when transformers present #8690

Closed
blueskymonster opened this issue Feb 23, 2022 · 0 comments · Fixed by #8691
Closed

Comments

@blueskymonster
Copy link
Contributor

Issue Description

When an primary key column has one or more transformers specified, relations fail to render their sql properly because the do not run the entity value through the transformer.

Expected Behavior

When a relation is loaded, the transformed value present in the entity should be run through the transformer to function(s) before it is passed into the SQL.

As an example, here's a contrived transformer that takes integer database columns and turns them into strings in typescript that have double quotes around them. While obviously not a reasonable use case, there are plenty of reasons why someone may want to transform an Id column in other ways.

const WrappedIntTransformer = {
  from: (value: number) => `"${value}"`,
  to: (value: string | undefined | null) => value ? parseInt(value.slice(1, value.length - 1)) : null,
}

@Entity()
export class User {
  @PrimaryColumn({ type: "int", transformer: WrappedIntTransformer, nullable: false })
  id: string;

  @OneToMany(() => Photo, (photo) => photo.user)
  photos: Promise<Photo[]>;
}

@Entity()
export class Photo {
  @PrimaryColumn({ type: "int", transformer: WrappedIntTransformer, nullable: false })
  id: string;

  @Column({ type: "text" })
  url: string;

  @Column({ type: "int", transformer: WrappedIntTransformer, nullable: false })
  userId: string;

  @ManyToOne(() => User, (user) => user.photos)
  @JoinColumn({ name: "userId", referencedColumnName: "id" })
  user: Promise<User>;
}

Then I expect to be able to call await user.photos and get something like this:

query: SELECT "photos"."id" AS "photos_id", "photos"."url" AS "photos_url", "photos"."userId" AS "photos_userId" FROM "photo" "photos" WHERE "photos"."userId" IN (?) -- PARAMETERS: [1]

Actual Behavior

When a relation is loaded, the transformed value present in the entity is used directly in the SQL without being "untransformed".

In the above example, running await user.photos actually generates this:

query: SELECT "photos"."id" AS "photos_id", "photos"."url" AS "photos_url", "photos"."userId" AS "photos_userId" FROM "photo" "photos" WHERE "photos"."userId" IN (?) -- PARAMETERS: ["\"1\""]

The value for user.id has not been un-transformed before shipping it back to sql.

Steps to Reproduce

  1. Clone my example repo
  2. npm install
  3. npm start
  4. Notice the final printed query with its incorrect parameters.

My Environment

Dependency Version
Operating System debian
Node.js version 12.21.0
Typescript version 4.5.5
TypeORM version 0.2.43

Additional Context

I believe I have identified how to fix the issue. Simply adding a second parameter true to all calls of getEntityValue in RelationLoader.ts. i.e. getEntityValue(entity, true) instead of getEntityValue(entity).

Relevant Database Driver(s)

I have manually confirmed this against postgresql and sqlite, but from my shallow understanding of the codebase, I think this likely affects all databases.

Are you willing to resolve this issue by submitting a Pull Request?

I will be opening a PR shortly. 😄

  • ✅ Yes, I have the time, and I know how to start.
  • ✖️ Yes, I have the time, but I don't know how to start. I would need guidance.
  • ✖️ No, I don’t have the time, but I can support (using donations) development.
  • ✖️ No, I don’t have the time and I’m okay to wait for the community / maintainers to resolve this issue.
pleerock pushed a commit that referenced this issue Feb 23, 2022
Use column transforms when rendering queries during relation loading. Previously, transforms were ignored by the relation loader, causing unexpected values to be put into sql queries.

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

Successfully merging a pull request may close this issue.

1 participant