From dfe8259ef53a432f1c02607e6ffee662dd4fd8a9 Mon Sep 17 00:00:00 2001 From: Temnov Aleksey Date: Mon, 21 Sep 2020 09:34:34 +0300 Subject: [PATCH] fix: count() method for multiple primary keys for cockroachdb (#6745) * fix: count() method for multiple primary keys for cockroachdb Cockroachdb does not support concat() for different types at the moment. To fix this problem, each primary key is cast to the text type. * fix: add doublequote * fix: add doublequote * test: update and move tests for count() method for multiple primary keys * fix: count() method for multiple primary keys for oracle Oracle does not support CONCAT() for more than 2 arguments at the moment. To solve this problem, operator || is used instead of CONCAT(). --- src/query-builder/SelectQueryBuilder.ts | 11 ++++++++++ .../query-builder/count/entity/Test.ts | 13 +++++++++++ .../count/query-builder-count.ts | 22 +++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 test/functional/query-builder/count/entity/Test.ts create mode 100644 test/functional/query-builder/count/query-builder-count.ts diff --git a/src/query-builder/SelectQueryBuilder.ts b/src/query-builder/SelectQueryBuilder.ts index 821be3186c..11cb61b0a4 100644 --- a/src/query-builder/SelectQueryBuilder.ts +++ b/src/query-builder/SelectQueryBuilder.ts @@ -36,6 +36,7 @@ import {SelectQueryBuilderOption} from "./SelectQueryBuilderOption"; import {ObjectUtils} from "../util/ObjectUtils"; import {DriverUtils} from "../driver/DriverUtils"; import {AuroraDataApiDriver} from "../driver/aurora-data-api/AuroraDataApiDriver"; +import {CockroachDriver} from "../driver/cockroachdb/CockroachDriver"; /** * Allows to build complex sql queries in a fashion way and execute those queries. @@ -1787,6 +1788,16 @@ export class SelectQueryBuilder extends QueryBuilder implements return `${distinctAlias}.${propertyName}`; }).join(" || ") + ")) as \"cnt\""; + } else if (this.connection.driver instanceof CockroachDriver) { + countSql = `COUNT(DISTINCT(CONCAT(` + metadata.primaryColumns.map((primaryColumn, index) => { + const propertyName = this.escape(primaryColumn.databaseName); + return `${distinctAlias}.${propertyName}::text`; + }).join(", ") + "))) as \"cnt\""; + } else if (this.connection.driver instanceof OracleDriver) { + countSql = `COUNT(DISTINCT(` + metadata.primaryColumns.map((primaryColumn, index) => { + const propertyName = this.escape(primaryColumn.databaseName); + return `${distinctAlias}.${propertyName}`; + }).join(" || ") + ")) as \"cnt\""; } else { countSql = `COUNT(DISTINCT(CONCAT(` + metadata.primaryColumns.map((primaryColumn, index) => { const propertyName = this.escape(primaryColumn.databaseName); diff --git a/test/functional/query-builder/count/entity/Test.ts b/test/functional/query-builder/count/entity/Test.ts new file mode 100644 index 0000000000..360fce0ac0 --- /dev/null +++ b/test/functional/query-builder/count/entity/Test.ts @@ -0,0 +1,13 @@ +import {Entity, PrimaryColumn} from "../../../../../src"; + +@Entity("tests") +export class Test { + @PrimaryColumn() + varcharField: string; + + @PrimaryColumn("uuid") + uuidField: string; + + @PrimaryColumn() + intField: number; +} diff --git a/test/functional/query-builder/count/query-builder-count.ts b/test/functional/query-builder/count/query-builder-count.ts new file mode 100644 index 0000000000..39990f9d38 --- /dev/null +++ b/test/functional/query-builder/count/query-builder-count.ts @@ -0,0 +1,22 @@ +import {closeTestingConnections, createTestingConnections, reloadTestingDatabases} from "../../../utils/test-utils"; +import {Connection} from "../../../../src/connection/Connection"; +import {expect} from "chai"; +import {Test} from "./entity/Test"; + +describe("query builder > count", () => { + + let connections: Connection[]; + before(async () => connections = await createTestingConnections({ + entities: [Test], + schemaCreate: true, + dropSchema: true, + })); + beforeEach(() => reloadTestingDatabases(connections)); + after(() => closeTestingConnections(connections)); + + it("Count query should be completed successfully", () => Promise.all(connections.map(async connection => { + const count = await connection.getRepository(Test).count(); + expect(count).to.be.equal(0); + }))); + +});