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: support for Common Table Expressions #8534

Merged
merged 2 commits into from Mar 23, 2022

Conversation

Ginden
Copy link
Collaborator

@Ginden Ginden commented Jan 15, 2022

Resolves #1116 #5149 #5484

Description of change

This pull request adds support for common table expressions in QueryBuilder.

Pull-Request Checklist

  • Code is up-to-date with the master branch
  • npm run lint passes with this change
  • npm run test passes with this change
  • This pull request links relevant issues as Fixes #0000
  • There are new or updated unit tests validating the change
  • Documentation has been updated to reflect this change
  • The new commits follow conventions explained in CONTRIBUTING.md

src/driver/Driver.ts Outdated Show resolved Hide resolved
@pleerock
Copy link
Member

Why does it marked for 0.3.0? If there are no breaking changes we can introduce it in 0.2.x.

@Ginden
Copy link
Collaborator Author

Ginden commented Feb 15, 2022

Why does it marked for 0.3.0? If there are no breaking changes we can introduce it in 0.2.x.

I marked it as 0.3.0 because original issue #1116 was marked as 0.3.0.

I can't see any breaking changes.

@pleerock
Copy link
Member

ah okay, then we can unmark it and release in 0.2.x. Also we probably need to specify in the documentation what databases support this feature. And do you have in plans add other databases support?

@Ginden Ginden force-pushed the feature/cte-support branch 2 times, most recently from 5790039 to 678cae5 Compare February 17, 2022 17:58
@Ginden
Copy link
Collaborator Author

Ginden commented Feb 17, 2022

Also we probably need to specify in the documentation what databases support this feature. And do you have in plans add other databases support?

Common table expressions are supported in all major databases... But MySQL supports them since 8.0, but TypeORM tests against MySQL 5.7. MySQL 5.7 goes EOL in 2023.

DML in CTE is supported only in Postgres I think, I updated docs.

@pleerock
Copy link
Member

Common table expressions are supported in all major databases... But MySQL supports them since 8.0, but TypeORM tests against MySQL 5.7. MySQL 5.7 goes EOL in 2023.

we can:

  • drop mysql 5.7 from tests
    or
  • add another mysql 8.0 to test, add check in the test to skip test execution in 5.7

@Ginden
Copy link
Collaborator Author

Ginden commented Feb 18, 2022

@pleerock Overall, I think it's reasonable to provide some kind of version check into Driver. Many features are not supported in older versions of databases and users should get early error instead of syntax errors.

@pleerock
Copy link
Member

yes, would be good to have.

@AlexMesser
Copy link
Collaborator

AlexMesser commented Feb 19, 2022

@Ginden we already have a version checks like this, but used internally in QueryRunner. We can make getVersion() function part of the QueryRunner public API. We can also add a version property to all drivers and set it before the schema is synchronized.

@Ginden
Copy link
Collaborator Author

Ginden commented Feb 24, 2022

I will try to have a look at this. Maybe it makes sense to do simple

connection.query(`WITH cte_test AS (SELECT 1 AS bar) SELECT * FROM cte_test`);

instead of hard-coding checks.

Or disable support for CTEs by default for certain (only MySQL?) database drivers and specify forceEnableCte in MySqlConnectionOptions?

@pleerock Which approach should I choose?

@AlexMesser Linked check made me think that TypeORM should explicitly say which database versions it supports. I think support for EOL databases should be explicitly dropped.

@pleerock
Copy link
Member

@Ginden why can't we go with version checks as @AlexMesser suggested?

@Ginden
Copy link
Collaborator Author

Ginden commented Feb 26, 2022

@pleerock Done!

@pleerock
Copy link
Member

Tests are failing...

@Ginden
Copy link
Collaborator Author

Ginden commented Feb 26, 2022

Hm, these tests fail only if MySQL 8.0 is enabled in tests. I added mysql8 to docker-compose.yml (with forced mysql2 driver due to this unresolved issue in mysql package).

After disabling mysql8, tests pass locally.

I will have a look at this, whether it's issue with TypeORM or mysql2 or MySQL 8.0.

EDIT:

  • I was able to pinpoint one issue - legacySpatialSupport wasn't disabled for MySQL 8.0.
  • tinyint don't have width on MySQL 8.0

@Ginden
Copy link
Collaborator Author

Ginden commented Feb 26, 2022

Full list of issues with enabling MySQL 8.0 in tests:

Also:


1) ConnectionOptionsReader
   properly loads config from yaml:
 Error: EEXIST: file already exists, mkdir '/typeorm/build/compiled/test/functional/connection-options-reader/configs/yaml'


2) database schema > column width
   all types should be created with correct width:
 AssertionError: expected undefined to equal 10
  at /typeorm/test/functional/database-schema/column-width/mysql/column-width.ts:25:61

3) database schema > column width
   should update data type display width:
 AssertionError: expected undefined to equal 5
  at /typeorm/test/functional/database-schema/column-width/mysql/column-width.ts:48:61

4) entity-schema > columns > mysql
   should create columns with different options:

  AssertionError: expected 'concat(`FirstName`,_utf8mb4\\\' \\\',`LastName`)' to equal 'concat(`FirstName`,\' \',`LastName`)'
  + expected - actual

  -concat(`FirstName`,_utf8mb4\' \',`LastName`)
  +concat(`FirstName`,' ',`LastName`)
  
  at /typeorm/test/functional/entity-schema/columns/mysql/columns-mysql.ts:26:77

5) transaction > method wrapped into transaction decorator
   should execute all operations in the method in a transaction:
 AssertionError: expected undefined not to be undefined
  at /typeorm/test/functional/transaction/transaction-decorator/transaction-decorator.ts:35:37

6) transaction > method wrapped into transaction decorator
   should inject repository and custom repository into method decorated with @Transaction:
 AssertionError: expected undefined not to be undefined
  at /typeorm/test/functional/transaction/transaction-decorator/transaction-decorator.ts:135:37

7) transaction > method wrapped into transaction decorator
   should execute all operations in the method in a transaction with a specified isolation:
 AssertionError: expected undefined not to be undefined
  at /typeorm/test/functional/transaction/transaction-decorator/transaction-decorator.ts:156:37

8) github issues > #1377 Add support for `GENERATED ALWAYS AS` in MySQL
   should correctly create table with generated columns:

  AssertionError: expected 'concat(`firstName`,_utf8mb4\\\' \\\',`lastName`)' to equal 'concat(`firstName`,\' \',`lastName`)'
  + expected - actual

  -concat(`firstName`,_utf8mb4\' \',`lastName`)
  +concat(`firstName`,' ',`lastName`)
  
  at /typeorm/test/github-issues/1377/issue-1377.ts:22:77

9) github issues > #3702 MySQL Spatial Type Support : GeomFromText function is not supported
   when legacySpatialSupport: true
     should use GeomFromText:
 AssertionError: expected 'INSERT INTO `letter_box`(`id`, `coord`) VALUES (DEFAULT, ST_GeomFromText(?, 4326))' to not include 'ST_GeomFromText'
  at /typeorm/test/github-issues/3702/issue-3702.ts:31:29

10) github issues > #3702 MySQL Spatial Type Support : GeomFromText function is not supported
   when legacySpatialSupport: true
     should use AsText:
 AssertionError: expected 'SELECT `letterBox`.`id` AS `letterBox_id`, ST_AsText(`letterBox`.`coord`) AS `letterBox_coord` FROM `letter_box` `letterBox`' to not include 'ST_AsText'
  at /typeorm/test/github-issues/3702/issue-3702.ts:53:29

11) github issues > #6266 Many identical selects after insert bunch of items
   should execute a single SELECT to get inserted default and generated values of multiple entities:
 TypeError: Attempted to wrap select which is already wrapped
  at checkWrappedMethod (node_modules/sinon/lib/sinon/util/core/wrap-method.js:40:21)
  at wrapMethod (node_modules/sinon/lib/sinon/util/core/wrap-method.js:88:13)
  at Function.spy (node_modules/sinon/lib/sinon/spy.js:156:16)
  at Sandbox.spy (node_modules/sinon/lib/sinon/sandbox.js:328:35)
  at /typeorm/test/github-issues/6266/issue-6266.ts:43:41
  at step (node_modules/tslib/tslib.js:143:27)
  at Object.next (node_modules/tslib/tslib.js:124:57)
  at /typeorm/node_modules/tslib/tslib.js:117:75
  at new Promise (<anonymous>)
  at __awaiter (node_modules/tslib/tslib.js:113:16)
  at /typeorm/test/github-issues/6266/issue-6266.ts:42:46
  at Array.map (<anonymous>)
  at Context.<anonymous> (test/github-issues/6266/issue-6266.ts:42:25)
  at runMicrotasks (<anonymous>)
  at processTicksAndRejections (node:internal/process/task_queues:96:5)
--------------
Error: Stack Trace for original
  at wrapMethod (node_modules/sinon/lib/sinon/util/core/wrap-method.js:116:26)
  at Function.spy (node_modules/sinon/lib/sinon/spy.js:156:16)
  at Sandbox.spy (node_modules/sinon/lib/sinon/sandbox.js:328:35)
  at /typeorm/test/github-issues/6266/issue-6266.ts:43:41
  at step (node_modules/tslib/tslib.js:143:27)
  at Object.next (node_modules/tslib/tslib.js:124:57)
  at /typeorm/node_modules/tslib/tslib.js:117:75
  at new Promise (<anonymous>)
  at __awaiter (node_modules/tslib/tslib.js:113:16)
  at /typeorm/test/github-issues/6266/issue-6266.ts:42:46
  at Array.map (<anonymous>)
  at Context.<anonymous> (test/github-issues/6266/issue-6266.ts:42:25)
  at runMicrotasks (<anonymous>)
  at processTicksAndRejections (node:internal/process/task_queues:96:5)

I created #8713 to track these.

@Ginden
Copy link
Collaborator Author

Ginden commented Mar 1, 2022

I'm not sure why Postgres 12 test fails with:

  1. github issues > @CavidM @pleerock This seems to cause an error for connection configs with replication. Please note the lack of the database property on the root object. #4753 MySQL Replication Config broken

Oracle needs fixing though.

@Ginden
Copy link
Collaborator Author

Ginden commented Mar 8, 2022

@pleerock I need assistance with this one - tests pass for "query builder > cte", but they fail when attempting to test MySQL replication.

Tests pass locally on my machine connected to Docker, so I suppose it's something related to CircleCI specific configuration.

@Ginden Ginden removed this from the 0.3.0 milestone Mar 21, 2022
@pleerock
Copy link
Member

oups it got automatically closed

@pleerock pleerock reopened this Mar 22, 2022
}
if (
!this.connection.driver.cteCapabilities.writable &&
!(cte.queryBuilder instanceof SelectQueryBuilder)
Copy link
Member

Choose a reason for hiding this comment

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

replace it with InstanceChecker.isSelectQueryBuilder. From 0.3.0 we avoid using instanceof because it doesn't play well in the monorepo projects with multiple instances of TypeORM across different node_modules.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

@pleerock
Copy link
Member

looks good 👍

@pleerock pleerock merged commit 7cc1848 into typeorm:master Mar 23, 2022
@pleerock
Copy link
Member

thank you a lot

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.

Common Table Expressions
3 participants