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

feat: implement generated columns for postgres 12 driver #6469

Merged
merged 29 commits into from Nov 14, 2021

Conversation

TheNoim
Copy link
Contributor

@TheNoim TheNoim commented Jul 26, 2020

The implementation has the potential to make full-text search much faster when using Postgres. You can simply pre-generate all tsvector's.

Example:

export class Post {

    @PrimaryColumn()
    id: number;

    @Column({ unique: true })
    version: number;

    @Column({ default: "My post" })
    name: string;

    @Column()
    text: string;

    @Column()
    tag: string;

    @Column({ generatedType: "STORED", asExpression: "to_tsvector('english', text)" })
    tsv: string[];
}

Note:

My implementation is a bit different from the MySQL implementation. For me, it was important that a generated column only gets dropped and added again if the as expression changes. Maybe I should implement the same mechanic for the MySQL driver.

@TheNoim
Copy link
Contributor Author

TheNoim commented Jul 26, 2020

Ok, this is a problem. The tests are running on Postgres 9. However, this is a Postgres 12 feature.

@TheNoim
Copy link
Contributor Author

TheNoim commented Aug 13, 2020

Resolved the merge conflicts and adjusted the ci to also test Postgres 12.

The implementation has the potential to make full text search much faster when using postgres. You can simply pre-generate all tsvector's
Generated columns are only available on postgres version 12+
Currently, there are only tests for postgres 9. This adds postgres 12 as test target
MariaDB will fail with a generated column type
Latest changes in master introduce replication mode. This commit adjust the the pull request typeorm#6469 to this change
Latest changes in master broke the postgres 12 test setup
@TheNoim
Copy link
Contributor Author

TheNoim commented Oct 10, 2020

Rebased and resolved conflicts.

@imnotjames imnotjames self-requested a review October 10, 2020 21:31
src/driver/postgres/PostgresDriver.ts Outdated Show resolved Hide resolved
src/driver/postgres/PostgresDriver.ts Outdated Show resolved Hide resolved
.circleci/config.yml Show resolved Hide resolved
src/schema-builder/RdbmsSchemaBuilder.ts Outdated Show resolved Hide resolved
src/schema-builder/RdbmsSchemaBuilder.ts Outdated Show resolved Hide resolved
.circleci/config.yml Show resolved Hide resolved
src/driver/postgres/PostgresQueryRunner.ts Outdated Show resolved Hide resolved
src/driver/postgres/PostgresQueryRunner.ts Outdated Show resolved Hide resolved
src/driver/postgres/PostgresQueryRunner.ts Show resolved Hide resolved
…TypeormGeneratedMetadataTable function

imnotjames notice this in his review of the pull request
This return of Promise.resolve() has no effect. We can leave it out
Instead of parsing the version string with parseFloat, use the typeorm VersionUtils
@TheNoim TheNoim mentioned this pull request Mar 30, 2021
48 tasks
@TheNoim
Copy link
Contributor Author

TheNoim commented May 21, 2021

It would be cool if this pr gets some love too, after so many prs got merged this week.

@pleerock
Copy link
Member

pleerock commented Nov 9, 2021

Sorry your PR is on the last page of the list, that's why I never reach it, since I always start from the first page 😆 Let's figure out what to do - merge or close it, I'm going to review it.

@TheNoim
Copy link
Contributor Author

TheNoim commented Nov 10, 2021

Sorry your PR is on the last page of the list, that's why I never reach it, since I always start from the first page 😆 Let's figure out what to do - merge or close it, I'm going to review it.

This is still open: https://github.com/typeorm/typeorm/pull/6469/files#r584112670

Copy link
Member

@pleerock pleerock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All comments from previous review should be resolved before this can be merged.

src/driver/postgres/PostgresQueryRunner.ts Outdated Show resolved Hide resolved
src/driver/postgres/PostgresQueryRunner.ts Outdated Show resolved Hide resolved
test/functional/query-runner/add-column.ts Show resolved Hide resolved
@pleerock
Copy link
Member

Tests are failing btw

@TheNoim
Copy link
Contributor Author

TheNoim commented Nov 11, 2021

Tests are failing btw

Yes, I see it. Will try to solve it as soon as possible.

@dunklesToast
Copy link

Since tests are passing now, can this land soon?

@AlexMesser
Copy link
Collaborator

AlexMesser commented Nov 14, 2021

  • added a new MetadataTableType enum to make metadata table types more stricter and predictable
export enum MetadataTableType {
    VIEW = "VIEW",
    MATERIALIZED_VIEW = "MATERIALIZED_VIEW",
    GENERATED_COLUMN = "GENERATED_COLUMN"
}
  • implemented insertTypeormMetadataSql() and deleteTypeormMetadataSql() functions in BaseQueryRunner to unify metadata insertion and deletion across all drivers and metadata types
  • some code refactoring

@AlexMesser AlexMesser merged commit 91080be into typeorm:master Nov 14, 2021
@AlexMesser
Copy link
Collaborator

thank you for contribution!

@TheNoim
Copy link
Contributor Author

TheNoim commented Nov 14, 2021

I am so happy this finally landed on master <3

HeartPattern pushed a commit to HeartPattern/typeorm that referenced this pull request Nov 29, 2021
* feat: implement generated columns for postgres 12 driver

The implementation has the potential to make full text search much faster when using postgres. You can simply pre-generate all tsvector's

* test: add tests for generated columns in postgres 12

* docs: document generated columns for postgres 12

* fix: check postgres version for generated columns

Generated columns are only available on postgres version 12+

* test: add postgres 12 to tests

Currently, there are only tests for postgres 9. This adds postgres 12 as test target

* test: remove generated column from model

MariaDB will fail with a generated column type

* test: use non alpine container for postgres 12

* test: skip generated columns test on mariadb

* fix: detect generated column change

* fix: circle ci postgres version

* fix: add replication mode to isGeneratedColumnsSupported() function

Latest changes in master introduce replication mode. This commit adjust the the pull request typeorm#6469 to this change

* fix: ci testing for postgres 12

Latest changes in master broke the postgres 12 test setup

* style: remove SqlServerConnectionOptions generic parameter for createTypeormGeneratedMetadataTable function

imnotjames notice this in his review of the pull request

* style: remove unnecessary return of Promise.resolve()
This return of Promise.resolve() has no effect. We can leave it out

* style: fix whitespace issue for config.yml

* refactor: use VersionUtils

Instead of parsing the version string with parseFloat, use the typeorm VersionUtils

* fix: fix failing build

After merging the upstream into the pr fork, the build stopped working. The reason why the build fails, is because in the upstream one import is missing and one variable was removed

* refactor: replace promise.all() with for loop

* refactor: make requested changes

* fix: update table name

* fix: server version query and escape table column in queries

* code refactoring

* fixed lint issue

* removed "enabledDrivers" from test

Co-authored-by: Dmitry Zotov <dmzt08@gmail.com>
HeartPattern pushed a commit to HeartPattern/typeorm that referenced this pull request Nov 29, 2021
* feat: implement generated columns for postgres 12 driver

The implementation has the potential to make full text search much faster when using postgres. You can simply pre-generate all tsvector's

* test: add tests for generated columns in postgres 12

* docs: document generated columns for postgres 12

* fix: check postgres version for generated columns

Generated columns are only available on postgres version 12+

* test: add postgres 12 to tests

Currently, there are only tests for postgres 9. This adds postgres 12 as test target

* test: remove generated column from model

MariaDB will fail with a generated column type

* test: use non alpine container for postgres 12

* test: skip generated columns test on mariadb

* fix: detect generated column change

* fix: circle ci postgres version

* fix: add replication mode to isGeneratedColumnsSupported() function

Latest changes in master introduce replication mode. This commit adjust the the pull request typeorm#6469 to this change

* fix: ci testing for postgres 12

Latest changes in master broke the postgres 12 test setup

* style: remove SqlServerConnectionOptions generic parameter for createTypeormGeneratedMetadataTable function

imnotjames notice this in his review of the pull request

* style: remove unnecessary return of Promise.resolve()
This return of Promise.resolve() has no effect. We can leave it out

* style: fix whitespace issue for config.yml

* refactor: use VersionUtils

Instead of parsing the version string with parseFloat, use the typeorm VersionUtils

* fix: fix failing build

After merging the upstream into the pr fork, the build stopped working. The reason why the build fails, is because in the upstream one import is missing and one variable was removed

* refactor: replace promise.all() with for loop

* refactor: make requested changes

* fix: update table name

* fix: server version query and escape table column in queries

* code refactoring

* fixed lint issue

* removed "enabledDrivers" from test

Co-authored-by: Dmitry Zotov <dmzt08@gmail.com>
@Migushthe2nd
Copy link

Migushthe2nd commented Dec 5, 2021

@TheNoim Schema synchronization seems to fail.

query failed: SELECT * FROM "typeorm_metadata"  WHERE "table" = 'theme_previews' AND "name" = 'image720Hash' AND "
schema" = 'typeorm' AND "database" = 'themezer_dev' AND "type" = 'GENERATED_COLUMN'
error: error: relation "typeorm_metadata" does not exist
    at Parser.parseErrorMessage (node_modules\pg-protocol\src\parser.ts:369:69)
    at Parser.handlePacket (node_modules\pg-protocol\src\parser.ts:188:21)
    at Parser.parse (node_modules\pg-protocol\src\parser.ts:103:30)
    at Socket.<anonymous> (node_modules\pg-protocol\src\index.ts:7:48)
    at Socket.emit (node:events:394:28)
    at addChunk (node:internal/streams/readable:312:12)
    at readableAddChunk (node:internal/streams/readable:287:9)
    at Socket.Readable.push (node:internal/streams/readable:226:10)
    at TCP.onStreamRead (node:internal/stream_base_commons:190:23) {
  length: 115,
  severity: 'ERROR',
  code: '42P01',
  detail: undefined,
  hint: undefined,
  position: '15',
  internalPosition: undefined,
  internalQuery: undefined,
  where: undefined,
  schema: undefined,
  table: undefined,
  column: undefined,
  dataType: undefined,
  constraint: undefined,
  file: 'parse_relation.c',
  line: '1381',
  routine: 'parserOpenTable'
}
query: ROLLBACK
query failed: SELECT * FROM "typeorm_metadata"  WHERE "table" = 'theme_previews' AND "name" = 'image360Hash' AND "
schema" = 'typeorm' AND "database" = 'themezer_dev' AND "type" = 'GENERATED_COLUMN'
error: error: current transaction is aborted, commands ignored until end of transaction block
...

On initial sync the columns seem to be generated correctly in the database and there is no issue. On second sync all generated columns fail. My decorator:
@PrimaryColumn({type: "varchar", generatedType: "STORED", asExpression: "sha256(\"image720File\")"})

Can you replicate this?

@TheNoim
Copy link
Contributor Author

TheNoim commented Dec 5, 2021

@TheNoim Schema synchronization seems to fail.

query failed: SELECT * FROM "typeorm_metadata"  WHERE "table" = 'theme_previews' AND "name" = 'image720Hash' AND "
schema" = 'typeorm' AND "database" = 'themezer_dev' AND "type" = 'GENERATED_COLUMN'
error: error: relation "typeorm_metadata" does not exist
    at Parser.parseErrorMessage (node_modules\pg-protocol\src\parser.ts:369:69)
    at Parser.handlePacket (node_modules\pg-protocol\src\parser.ts:188:21)
    at Parser.parse (node_modules\pg-protocol\src\parser.ts:103:30)
    at Socket.<anonymous> (node_modules\pg-protocol\src\index.ts:7:48)
    at Socket.emit (node:events:394:28)
    at addChunk (node:internal/streams/readable:312:12)
    at readableAddChunk (node:internal/streams/readable:287:9)
    at Socket.Readable.push (node:internal/streams/readable:226:10)
    at TCP.onStreamRead (node:internal/stream_base_commons:190:23) {
  length: 115,
  severity: 'ERROR',
  code: '42P01',
  detail: undefined,
  hint: undefined,
  position: '15',
  internalPosition: undefined,
  internalQuery: undefined,
  where: undefined,
  schema: undefined,
  table: undefined,
  column: undefined,
  dataType: undefined,
  constraint: undefined,
  file: 'parse_relation.c',
  line: '1381',
  routine: 'parserOpenTable'
}
query: ROLLBACK
query failed: SELECT * FROM "typeorm_metadata"  WHERE "table" = 'theme_previews' AND "name" = 'image360Hash' AND "
schema" = 'typeorm' AND "database" = 'themezer_dev' AND "type" = 'GENERATED_COLUMN'
error: error: current transaction is aborted, commands ignored until end of transaction block
...

On initial sync the columns seem to be generated correctly in the database and there is no issue. On second sync all generated columns fail. My decorator: @PrimaryColumn({type: "varchar", generatedType: "STORED", asExpression: "sha256(\"image720File\")"})

Can you replicate this?

I was hoping #4956 solves the issue. But it seems like it doesn't. Maybe I need to look into it a bit further.

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

Successfully merging this pull request may close these issues.

None yet

7 participants