From d6329a7f3b898234180b39b3e5e2aa2c235d9f3b Mon Sep 17 00:00:00 2001
From: soham-bentley <177123878+soham-bentley@users.noreply.github.com>
Date: Mon, 7 Oct 2024 19:33:37 +0530
Subject: [PATCH 01/12] Tests added for IdSet Virtual Table
---
core/backend/src/test/ecdb/ECSqlQuery.test.ts | 19 ++++++
.../backend/src/test/ecdb/ECSqlReader.test.ts | 20 +++++++
.../src/test/ecdb/ECSqlStatement.test.ts | 59 +++++++++++++++++++
3 files changed, 98 insertions(+)
diff --git a/core/backend/src/test/ecdb/ECSqlQuery.test.ts b/core/backend/src/test/ecdb/ECSqlQuery.test.ts
index 8b78162dbc2d..c5d26d4bad19 100644
--- a/core/backend/src/test/ecdb/ECSqlQuery.test.ts
+++ b/core/backend/src/test/ecdb/ECSqlQuery.test.ts
@@ -451,6 +451,25 @@ describe("ECSql Query", () => {
assert.isTrue(reader.stats.backendCpuTime > 0);
assert.isTrue(reader.stats.backendMemUsed > 100);
});
+ it("concurrent query use idset in IdSet virtual table", async () => {
+ const ids: string[] = [];
+ for await (const row of imodel1.createQueryReader("SELECT ECInstanceId FROM BisCore.Element LIMIT 23")) {
+ ids.push(row[0]);
+ }
+ const reader = imodel1.createQueryReader("SELECT * FROM BisCore.element, ECVLib.IdSet(?) WHERE id = ECInstanceId", QueryBinder.from([ids]));
+ let props = await reader.getMetaData();
+ assert.equal(props.length, 12); // 11 for BisCore.element and 1 for IdSet
+ let rows = 0;
+ while (await reader.step()) {
+ rows++;
+ }
+ assert.equal(rows, 23);
+ props = await reader.getMetaData();
+ assert.equal(props.length, 12); // 11 for BisCore.element and 1 for IdSet
+ assert.equal(reader.stats.backendRowsReturned, 23);
+ assert.isTrue(reader.stats.backendCpuTime > 0);
+ assert.isTrue(reader.stats.backendMemUsed > 100);
+ });
it("concurrent query get meta data", async () => {
const reader = imodel1.createQueryReader("SELECT * FROM BisCore.element");
let props = await reader.getMetaData();
diff --git a/core/backend/src/test/ecdb/ECSqlReader.test.ts b/core/backend/src/test/ecdb/ECSqlReader.test.ts
index 6e0f85ec6634..c8454ef90571 100644
--- a/core/backend/src/test/ecdb/ECSqlReader.test.ts
+++ b/core/backend/src/test/ecdb/ECSqlReader.test.ts
@@ -27,6 +27,26 @@ describe("ECSqlReader", (() => {
describe("bind Id64 enumerable", async () => {
const outDir = KnownTestLocations.outputDir;
+ it("ecsql reader simple", async () => {
+ await using(ECDbTestHelper.createECDb(outDir, "test.ecdb",
+ `
+
+
+
+ `), async (ecdb: ECDb) => {
+ assert.isTrue(ecdb.isOpen);
+ ecdb.saveChanges();
+ const params = new QueryBinder();
+ params.bindIdSet(1, ["0x32"]);
+ const optionBuilder = new QueryOptionsBuilder();
+ optionBuilder.setRowFormat(QueryRowFormat.UseJsPropertyNames);
+ reader = ecdb.createQueryReader("SELECT ECInstanceId, Name FROM meta.ECClassDef, ECVLib.IdSet(?) WHERE id = ECInstanceId", params, optionBuilder.getOptions());
+ const rows = await reader.toArray();
+ assert.equal(rows[0].id, "0x32");
+ assert.equal(rows.length, 1);
+ });
+ });
+
it("ecsql reader simple", async () => {
await using(ECDbTestHelper.createECDb(outDir, "test.ecdb",
`
diff --git a/core/backend/src/test/ecdb/ECSqlStatement.test.ts b/core/backend/src/test/ecdb/ECSqlStatement.test.ts
index 77f03065b8ad..e394fc4a7c4d 100644
--- a/core/backend/src/test/ecdb/ECSqlStatement.test.ts
+++ b/core/backend/src/test/ecdb/ECSqlStatement.test.ts
@@ -1841,6 +1841,65 @@ describe("ECSqlStatement", () => {
});
});
+ it.only("should bind IdSets to IdSet Virtual Table", async () => {
+ await using(ECDbTestHelper.createECDb(outDir, "bindids.ecdb"), async (ecdb: ECDb) => {
+ assert.isTrue(ecdb.isOpen);
+
+ const idNumbers: number[] = [4444, 4545, 1234, 6758, 1312];
+ ecdb.withPreparedStatement("INSERT INTO ecdbf.ExternalFileInfo(ECInstanceId,Name) VALUES(?,?)", (stmt: ECSqlStatement) => {
+ idNumbers.forEach((idNum: number) => {
+ const expectedId = Id64.fromLocalAndBriefcaseIds(idNum, 0);
+ stmt.bindId(1, expectedId);
+ stmt.bindString(2, `${idNum}.txt`);
+ const r: ECSqlInsertResult = stmt.stepForInsert();
+ assert.equal(r.status, DbResult.BE_SQLITE_DONE);
+ assert.isDefined(r.id);
+ assert.equal(r.id!, expectedId);
+ ecdb.saveChanges();
+
+ ecdb.withStatement(`SELECT ECInstanceId, ECClassId, Name FROM ecdbf.ExternalFileInfo WHERE ECInstanceId=${expectedId}`, (confstmt: ECSqlStatement) => {
+ assert.equal(confstmt.step(), DbResult.BE_SQLITE_ROW);
+ const row = confstmt.getRow();
+ assert.equal(row.id, expectedId);
+ assert.equal(row.className, "ECDbFileInfo.ExternalFileInfo");
+ assert.equal(row.name, `${Id64.getLocalId(expectedId).toString()}.txt`);
+ });
+ stmt.reset();
+ stmt.clearBindings();
+ });
+ });
+
+ ecdb.withPreparedStatement("SELECT ECInstanceId, ECClassId, Name from ecdbf.ExternalFileInfo, ECVLib.IdSet(?) WHERE id = ECInstanceId", (stmt: ECSqlStatement) => {
+ let idSet: Id64String[] = [];
+ stmt.bindIdSet(1, idSet);
+ let result = stmt.step();
+ assert.equal(result, DbResult.BE_SQLITE_DONE);
+ stmt.reset();
+ stmt.clearBindings();
+
+ idSet = [Id64.fromLocalAndBriefcaseIds(idNumbers[2], 0)];
+ stmt.bindIdSet(1, idSet);
+ result = stmt.step();
+ assert.equal(result, DbResult.BE_SQLITE_ROW);
+ let row = stmt.getRow();
+ assert.equal(row.name, `${idNumbers[2]}.txt`);
+ stmt.reset();
+ stmt.clearBindings();
+
+ idSet.push(idNumbers[0].toString());
+ stmt.bindIdSet(1, idSet);
+ result = stmt.step();
+ assert.equal(result, DbResult.BE_SQLITE_ROW);
+ row = stmt.getRow();
+ assert.equal(row.name, `${idNumbers[2]}.txt`);
+ result = stmt.step();
+ assert.equal(result, DbResult.BE_SQLITE_ROW);
+ row = stmt.getRow();
+ assert.equal(row.name, `${idNumbers[0]}.txt`);
+ });
+ });
+ });
+
/* This test doesn't do anything specific with the binder life time but just runs a few scenarios
with and without statement cache to test that stuff works fine */
it("check ECSqlBinder life time", async () => {
From fdea7a8c76a9e680f79d8d49b31312d3ab61e281 Mon Sep 17 00:00:00 2001
From: soham-bentley <177123878+soham-bentley@users.noreply.github.com>
Date: Tue, 8 Oct 2024 19:18:55 +0530
Subject: [PATCH 02/12] only removed
---
core/backend/src/test/ecdb/ECSqlStatement.test.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/core/backend/src/test/ecdb/ECSqlStatement.test.ts b/core/backend/src/test/ecdb/ECSqlStatement.test.ts
index e394fc4a7c4d..e033a6cb3c26 100644
--- a/core/backend/src/test/ecdb/ECSqlStatement.test.ts
+++ b/core/backend/src/test/ecdb/ECSqlStatement.test.ts
@@ -1841,7 +1841,7 @@ describe("ECSqlStatement", () => {
});
});
- it.only("should bind IdSets to IdSet Virtual Table", async () => {
+ it("should bind IdSets to IdSet Virtual Table", async () => {
await using(ECDbTestHelper.createECDb(outDir, "bindids.ecdb"), async (ecdb: ECDb) => {
assert.isTrue(ecdb.isOpen);
From ffcf8518863d7c25f04b180d43b32ff54fb79866 Mon Sep 17 00:00:00 2001
From: soham-bentley <177123878+soham-bentley@users.noreply.github.com>
Date: Mon, 14 Oct 2024 18:30:10 +0530
Subject: [PATCH 03/12] More tests added
---
core/backend/src/test/ecdb/ECSqlQuery.test.ts | 46 +++++++++++++-
.../src/test/ecdb/ECSqlStatement.test.ts | 61 ++++++++++++++++++-
2 files changed, 105 insertions(+), 2 deletions(-)
diff --git a/core/backend/src/test/ecdb/ECSqlQuery.test.ts b/core/backend/src/test/ecdb/ECSqlQuery.test.ts
index d9b3cb514705..5816563120fb 100644
--- a/core/backend/src/test/ecdb/ECSqlQuery.test.ts
+++ b/core/backend/src/test/ecdb/ECSqlQuery.test.ts
@@ -678,7 +678,7 @@ describe("ECSql Query", () => {
assert.isTrue(reader.stats.backendCpuTime > 0);
assert.isTrue(reader.stats.backendMemUsed > 100);
});
- it("concurrent query use idset in IdSet virtual table", async () => {
+ it("concurrent query bind idset in IdSet virtual table", async () => {
const ids: string[] = [];
for await (const row of imodel1.createQueryReader("SELECT ECInstanceId FROM BisCore.Element LIMIT 23")) {
ids.push(row[0]);
@@ -697,6 +697,50 @@ describe("ECSql Query", () => {
assert.isTrue(reader.stats.backendCpuTime > 0);
assert.isTrue(reader.stats.backendMemUsed > 100);
});
+ it("concurrent query bind single id in IdSet virtual table", async () => {
+ let ids: string = "";
+ for await (const row of imodel1.createQueryReader("SELECT ECInstanceId FROM BisCore.Element LIMIT 23")) {
+ ids = row[0]; // getting only the first id
+ break;
+ }
+ const reader = imodel1.createQueryReader("SELECT * FROM BisCore.element, ECVLib.IdSet(?) WHERE id = ECInstanceId", QueryBinder.from([ids]));
+ let props = await reader.getMetaData();
+ assert.equal(props.length, 12); // 11 for BisCore.element and 1 for IdSet
+ let rows = 0; // backend will fail to bind so no rows will be returned
+ while (await reader.step()) {
+ rows++;
+ }
+ assert.equal(rows, 0);
+ props = await reader.getMetaData();
+ assert.equal(props.length, 12); // 11 for BisCore.element and 1 for IdSet
+ assert.equal(reader.stats.backendRowsReturned, 0);
+ assert.isTrue(reader.stats.backendCpuTime > 0);
+ });
+ it("concurrent query bind idset with invalid values in IdSet virtual table", async () => {
+ const ids: string[] = ["0x1","ABC","YZ"];
+
+ const reader = imodel1.createQueryReader("SELECT * FROM BisCore.element, ECVLib.IdSet(?) WHERE id = ECInstanceId", QueryBinder.from([ids]));
+ let props = await reader.getMetaData();
+ assert.equal(props.length, 12); // 11 for BisCore.element and 1 for IdSet
+ let rows = 0; // backend will bind successfully but some of the values are not valid for IdSet VT so those values will be ignored
+ while (await reader.step()) {
+ rows++;
+ }
+ assert.equal(rows, 1);
+ props = await reader.getMetaData();
+ assert.equal(props.length, 12); // 11 for BisCore.element and 1 for IdSet
+ assert.equal(reader.stats.backendRowsReturned, 1);
+ assert.isTrue(reader.stats.backendCpuTime > 0);
+ });
+ it.only("concurrent query bind idset with invalid values in IdSet virtual table", async () => {
+ const ids: string[] = ["ABC", "0x1","YZ"]; // as first value is not an Id so QueryBinder.from will throw error of "unsupported type"
+
+ try{
+ const reader = imodel1.createQueryReader("SELECT * FROM BisCore.element, ECVLib.IdSet(?) WHERE id = ECInstanceId", QueryBinder.from([ids]));
+ }catch(err: any){
+ assert.equal(err.message, "unsupported type");
+ }
+ });
it("concurrent query get meta data", async () => {
const reader = imodel1.createQueryReader("SELECT * FROM BisCore.element");
let props = await reader.getMetaData();
diff --git a/core/backend/src/test/ecdb/ECSqlStatement.test.ts b/core/backend/src/test/ecdb/ECSqlStatement.test.ts
index 92451e82d3a5..542efab4fc93 100644
--- a/core/backend/src/test/ecdb/ECSqlStatement.test.ts
+++ b/core/backend/src/test/ecdb/ECSqlStatement.test.ts
@@ -2,7 +2,7 @@
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
-import { assert } from "chai";
+import { assert, expect } from "chai";
import { DbResult, Guid, GuidString, Id64, Id64String, using } from "@itwin/core-bentley";
import { NavigationValue, QueryBinder, QueryOptions, QueryOptionsBuilder, QueryRowFormat } from "@itwin/core-common";
import { Point2d, Point3d, Range3d, XAndY, XYAndZ } from "@itwin/core-geometry";
@@ -12,6 +12,7 @@ import { KnownTestLocations } from "../KnownTestLocations";
import { SequentialLogMatcher } from "../SequentialLogMatcher";
import { ECDbTestHelper } from "./ECDbTestHelper";
import { ConcurrentQuery } from "../../ConcurrentQuery";
+import { Exception } from "@opentelemetry/api";
/* eslint-disable @typescript-eslint/naming-convention */
const selectSingleRow = new QueryOptionsBuilder().setLimit({ count: 1, offset: -1 }).setRowFormat(QueryRowFormat.UseJsPropertyNames).getOptions();
@@ -1900,6 +1901,64 @@ describe("ECSqlStatement", () => {
});
});
+ it("should bind IdSets to IdSet Virtual Table", async () => {
+ await using(ECDbTestHelper.createECDb(outDir, "bindids.ecdb"), async (ecdb: ECDb) => {
+ assert.isTrue(ecdb.isOpen);
+
+ const idNumbers: number[] = [4444, 4545, 1234, 6758, 1312];
+ ecdb.withPreparedStatement("INSERT INTO ecdbf.ExternalFileInfo(ECInstanceId,Name) VALUES(?,?)", (stmt: ECSqlStatement) => {
+ idNumbers.forEach((idNum: number) => {
+ const expectedId = Id64.fromLocalAndBriefcaseIds(idNum, 0);
+ stmt.bindId(1, expectedId);
+ stmt.bindString(2, `${idNum}.txt`);
+ const r: ECSqlInsertResult = stmt.stepForInsert();
+ assert.equal(r.status, DbResult.BE_SQLITE_DONE);
+ assert.isDefined(r.id);
+ assert.equal(r.id!, expectedId);
+ ecdb.saveChanges();
+
+ ecdb.withStatement(`SELECT ECInstanceId, ECClassId, Name FROM ecdbf.ExternalFileInfo WHERE ECInstanceId=${expectedId}`, (confstmt: ECSqlStatement) => {
+ assert.equal(confstmt.step(), DbResult.BE_SQLITE_ROW);
+ const row = confstmt.getRow();
+ assert.equal(row.id, expectedId);
+ assert.equal(row.className, "ECDbFileInfo.ExternalFileInfo");
+ assert.equal(row.name, `${Id64.getLocalId(expectedId).toString()}.txt`);
+ });
+ stmt.reset();
+ stmt.clearBindings();
+ });
+ });
+
+ ecdb.withPreparedStatement("SELECT ECInstanceId, ECClassId, Name from ecdbf.ExternalFileInfo, ECVLib.IdSet(?) WHERE id = ECInstanceId", (stmt: ECSqlStatement) => {
+ let idSet: Id64String[] = [];
+ stmt.bindIdSet(1, idSet);
+ let result = stmt.step();
+ assert.equal(result, DbResult.BE_SQLITE_DONE);
+ stmt.reset();
+ stmt.clearBindings();
+
+ idSet = ["0X1","ABC"];
+ try{
+ stmt.bindIdSet(1, idSet);
+ }catch(err: any){
+ assert.equal(err.message, "Error binding id set");
+ }
+ result = stmt.step();
+ assert.equal(result, DbResult.BE_SQLITE_DONE);
+ stmt.reset();
+ stmt.clearBindings();
+
+ try{
+ stmt.bindId(1, idNumbers[0].toString());
+ }catch(err: any){
+ assert.equal(err.message, "Error binding Id");
+ }
+ result = stmt.step();
+ assert.equal(result, DbResult.BE_SQLITE_DONE);
+ });
+ });
+ });
+
/* This test doesn't do anything specific with the binder life time but just runs a few scenarios
with and without statement cache to test that stuff works fine */
it("check ECSqlBinder life time", async () => {
From 67419dc55fd00fdc1424b0e1f4a9ccbaf0dbaa3f Mon Sep 17 00:00:00 2001
From: soham-bentley <177123878+soham-bentley@users.noreply.github.com>
Date: Mon, 14 Oct 2024 18:42:11 +0530
Subject: [PATCH 04/12] changeset and lint errors solved
---
.../Soham-AddingTestsForIdSetVT_2024-10-14-13-05.json | 10 ++++++++++
core/backend/src/test/ecdb/ECSqlQuery.test.ts | 2 +-
core/backend/src/test/ecdb/ECSqlStatement.test.ts | 3 +--
3 files changed, 12 insertions(+), 3 deletions(-)
create mode 100644 common/changes/@itwin/core-backend/Soham-AddingTestsForIdSetVT_2024-10-14-13-05.json
diff --git a/common/changes/@itwin/core-backend/Soham-AddingTestsForIdSetVT_2024-10-14-13-05.json b/common/changes/@itwin/core-backend/Soham-AddingTestsForIdSetVT_2024-10-14-13-05.json
new file mode 100644
index 000000000000..c7a188dd4db7
--- /dev/null
+++ b/common/changes/@itwin/core-backend/Soham-AddingTestsForIdSetVT_2024-10-14-13-05.json
@@ -0,0 +1,10 @@
+{
+ "changes": [
+ {
+ "packageName": "@itwin/core-backend",
+ "comment": "Added test cases for IdSet Virtual table",
+ "type": "none"
+ }
+ ],
+ "packageName": "@itwin/core-backend"
+}
\ No newline at end of file
diff --git a/core/backend/src/test/ecdb/ECSqlQuery.test.ts b/core/backend/src/test/ecdb/ECSqlQuery.test.ts
index 5816563120fb..8393c4fb933c 100644
--- a/core/backend/src/test/ecdb/ECSqlQuery.test.ts
+++ b/core/backend/src/test/ecdb/ECSqlQuery.test.ts
@@ -736,7 +736,7 @@ describe("ECSql Query", () => {
const ids: string[] = ["ABC", "0x1","YZ"]; // as first value is not an Id so QueryBinder.from will throw error of "unsupported type"
try{
- const reader = imodel1.createQueryReader("SELECT * FROM BisCore.element, ECVLib.IdSet(?) WHERE id = ECInstanceId", QueryBinder.from([ids]));
+ imodel1.createQueryReader("SELECT * FROM BisCore.element, ECVLib.IdSet(?) WHERE id = ECInstanceId", QueryBinder.from([ids]));
}catch(err: any){
assert.equal(err.message, "unsupported type");
}
diff --git a/core/backend/src/test/ecdb/ECSqlStatement.test.ts b/core/backend/src/test/ecdb/ECSqlStatement.test.ts
index 542efab4fc93..53c8fa055174 100644
--- a/core/backend/src/test/ecdb/ECSqlStatement.test.ts
+++ b/core/backend/src/test/ecdb/ECSqlStatement.test.ts
@@ -2,7 +2,7 @@
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
-import { assert, expect } from "chai";
+import { assert } from "chai";
import { DbResult, Guid, GuidString, Id64, Id64String, using } from "@itwin/core-bentley";
import { NavigationValue, QueryBinder, QueryOptions, QueryOptionsBuilder, QueryRowFormat } from "@itwin/core-common";
import { Point2d, Point3d, Range3d, XAndY, XYAndZ } from "@itwin/core-geometry";
@@ -12,7 +12,6 @@ import { KnownTestLocations } from "../KnownTestLocations";
import { SequentialLogMatcher } from "../SequentialLogMatcher";
import { ECDbTestHelper } from "./ECDbTestHelper";
import { ConcurrentQuery } from "../../ConcurrentQuery";
-import { Exception } from "@opentelemetry/api";
/* eslint-disable @typescript-eslint/naming-convention */
const selectSingleRow = new QueryOptionsBuilder().setLimit({ count: 1, offset: -1 }).setRowFormat(QueryRowFormat.UseJsPropertyNames).getOptions();
From abe508f4738a8803bf5d89498843a0b454e900cd Mon Sep 17 00:00:00 2001
From: soham-bentley <177123878+soham-bentley@users.noreply.github.com>
Date: Fri, 18 Oct 2024 18:16:58 +0530
Subject: [PATCH 05/12] ".only" removed
---
core/backend/src/test/ecdb/ECSqlQuery.test.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/core/backend/src/test/ecdb/ECSqlQuery.test.ts b/core/backend/src/test/ecdb/ECSqlQuery.test.ts
index 8393c4fb933c..cee8e7a97583 100644
--- a/core/backend/src/test/ecdb/ECSqlQuery.test.ts
+++ b/core/backend/src/test/ecdb/ECSqlQuery.test.ts
@@ -732,7 +732,7 @@ describe("ECSql Query", () => {
assert.equal(reader.stats.backendRowsReturned, 1);
assert.isTrue(reader.stats.backendCpuTime > 0);
});
- it.only("concurrent query bind idset with invalid values in IdSet virtual table", async () => {
+ it("concurrent query bind idset with invalid values in IdSet virtual table", async () => {
const ids: string[] = ["ABC", "0x1","YZ"]; // as first value is not an Id so QueryBinder.from will throw error of "unsupported type"
try{
From 3024b0f1aa85685000c29c76bc686488f6bde2b1 Mon Sep 17 00:00:00 2001
From: soham-bentley <177123878+soham-bentley@users.noreply.github.com>
Date: Thu, 16 Jan 2025 13:54:15 +0530
Subject: [PATCH 06/12] More tests added
---
...ddingTestsForIdSetVT_2024-10-14-13-05.json | 2 +-
.../backend/src/test/ecdb/ECSqlReader.test.ts | 19 ++++
.../test/ecsql/queries/IdSetVTTests.ecsql.md | 95 +++++++++++++++++++
3 files changed, 115 insertions(+), 1 deletion(-)
create mode 100644 core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md
diff --git a/common/changes/@itwin/core-backend/Soham-AddingTestsForIdSetVT_2024-10-14-13-05.json b/common/changes/@itwin/core-backend/Soham-AddingTestsForIdSetVT_2024-10-14-13-05.json
index c7a188dd4db7..99b35bb89b62 100644
--- a/common/changes/@itwin/core-backend/Soham-AddingTestsForIdSetVT_2024-10-14-13-05.json
+++ b/common/changes/@itwin/core-backend/Soham-AddingTestsForIdSetVT_2024-10-14-13-05.json
@@ -2,7 +2,7 @@
"changes": [
{
"packageName": "@itwin/core-backend",
- "comment": "Added test cases for IdSet Virtual table",
+ "comment": "",
"type": "none"
}
],
diff --git a/core/backend/src/test/ecdb/ECSqlReader.test.ts b/core/backend/src/test/ecdb/ECSqlReader.test.ts
index c2174fa008d6..5eaf1c635a41 100644
--- a/core/backend/src/test/ecdb/ECSqlReader.test.ts
+++ b/core/backend/src/test/ecdb/ECSqlReader.test.ts
@@ -67,6 +67,25 @@ describe("ECSqlReader", (() => {
});
});
+ it("bindIdSet not working with integer Ids", async () => {
+ await using(ECDbTestHelper.createECDb(outDir, "test.ecdb",
+ `
+
+
+
+ `), async (ecdb: ECDb) => {
+ assert.isTrue(ecdb.isOpen);
+ ecdb.saveChanges();
+ const params = new QueryBinder();
+ params.bindIdSet(1, ["50"]);
+ const optionBuilder = new QueryOptionsBuilder();
+ optionBuilder.setRowFormat(QueryRowFormat.UseJsPropertyNames);
+ reader = ecdb.createQueryReader("SELECT ECInstanceId, Name FROM meta.ECClassDef WHERE InVirtualSet(?, ECInstanceId)", params, optionBuilder.getOptions());
+ const rows = await reader.toArray();
+ assert.equal(rows.length, 0);
+ });
+ });
+
it("ecsql reader simple using query reader", async () => {
await using(ECDbTestHelper.createECDb(outDir, "test.ecdb",
`
diff --git a/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md b/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md
new file mode 100644
index 000000000000..15d610191712
--- /dev/null
+++ b/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md
@@ -0,0 +1,95 @@
+Copyright © Bentley Systems, Incorporated. All rights reserved. See [LICENSE.md](../../../../LICENSE.md) for license terms and full copyright notice.
+
+# Testing with hard coded json string with hex ids
+
+- dataset: AllProperties.bim
+
+```sql
+SELECT i FROM aps.TestElement,ECVLib.IdSet('["0x15", "0x18", "0x19"]') where id = ECInstanceId
+```
+
+| className | accessString | generated | index | jsonName | name | extendedType | typeName | type | originPropertyName |
+| ------------------------ | ------------ | --------- | ----- | -------- | ---- | ------------ | -------- | ---- | ------------------ |
+| AllProperties:IPrimitive | i | false | 0 | i | i | undefined | int | Int | i |
+
+| i |
+| --- |
+| 101 |
+| 104 |
+| 105 |
+
+# Testing with hard coded json string with decimal ids
+
+- dataset: AllProperties.bim
+
+```sql
+SELECT i FROM aps.TestElement,ECVLib.IdSet('[21, 24, "25"]') where id = ECInstanceId
+```
+
+| className | accessString | generated | index | jsonName | name | extendedType | typeName | type | originPropertyName |
+| ------------------------ | ------------ | --------- | ----- | -------- | ---- | ------------ | -------- | ---- | ------------------ |
+| AllProperties:IPrimitive | i | false | 0 | i | i | undefined | int | Int | i |
+
+| i |
+| --- |
+| 101 |
+| 104 |
+| 105 |
+
+# Testing by binding with hex ids
+
+- dataset: AllProperties.bim
+- bindIdSet 1, [0x15, 0x18, 0x19]
+
+```sql
+SELECT i FROM aps.TestElement,ECVLib.IdSet(?) where id = ECInstanceId
+```
+
+| className | accessString | generated | index | jsonName | name | extendedType | typeName | type | originPropertyName |
+| ------------------------ | ------------ | --------- | ----- | -------- | ---- | ------------ | -------- | ---- | ------------------ |
+| AllProperties:IPrimitive | i | false | 0 | i | i | undefined | int | Int | i |
+
+| i |
+| --- |
+| 101 |
+| 104 |
+| 105 |
+
+# Testing by binding with decimal ids for ECSql Statement
+
+- dataset: AllProperties.bim
+- bindIdSet 1, [21, 24, 25]
+- mode: Statement
+
+```sql
+SELECT i FROM aps.TestElement,ECVLib.IdSet(?) where id = ECInstanceId
+```
+
+| className | accessString | generated | index | jsonName | name | extendedType | typeName | type | originPropertyName |
+| ------------------------ | ------------ | --------- | ----- | -------- | ---- | ------------ | -------- | ---- | ------------------ |
+| AllProperties:IPrimitive | i | false | 0 | i | i | undefined | int | Int | i |
+
+| i |
+| --- |
+| 101 |
+| 104 |
+| 105 |
+
+# Testing by binding with decimal ids for ConcurrentQuery
+
+`The purpose of this test is to show that bindIdSet when working with ConcurrentQuery only takes into account hex ids and not decimal ids`
+
+- dataset: AllProperties.bim
+- bindIdSet 1, [21, 24, 25]
+- mode: ConcurrentQuery
+
+```sql
+SELECT i FROM aps.TestElement,ECVLib.IdSet(?) where id = ECInstanceId
+```
+
+| className | accessString | generated | index | jsonName | name | extendedType | typeName | type | originPropertyName |
+| ------------------------ | ------------ | --------- | ----- | -------- | ---- | ------------ | -------- | ---- | ------------------ |
+| AllProperties:IPrimitive | i | false | 0 | i | i | undefined | int | Int | i |
+
+| i |
+| --- |
From 988ad1bbe0e05b4240d128004eee94bd0793fe72 Mon Sep 17 00:00:00 2001
From: soham-bentley <177123878+soham-bentley@users.noreply.github.com>
Date: Thu, 16 Jan 2025 18:58:44 +0530
Subject: [PATCH 07/12] Documentation added
---
docs/learning/ECSqlReference/IdSet.md | 47 +++++++++++++++++++++++++++
docs/learning/ECSqlReference/index.md | 1 +
2 files changed, 48 insertions(+)
create mode 100644 docs/learning/ECSqlReference/IdSet.md
diff --git a/docs/learning/ECSqlReference/IdSet.md b/docs/learning/ECSqlReference/IdSet.md
new file mode 100644
index 000000000000..0ea76dd8705a
--- /dev/null
+++ b/docs/learning/ECSqlReference/IdSet.md
@@ -0,0 +1,47 @@
+# IdSet Virtual Table
+
+`IdSet` is an ECSQl built in virtual table which takes in a valid JSON array string of hex or decimal ids and stores the ids as a virtual table. It can be used as an alternative to `InVirtualSet`.
+
+## Syntax
+
+```sql
+SELECT i FROM aps.TestElement, ECVLib.IdSet('["0x15", "0x18", "0x19"]') where id = ECInstanceId
+```
+
+OR
+
+```sql
+SELECT i FROM aps.TestElement, ECVLib.IdSet(?) where id = ECInstanceId
+```
+
+## Arguments accepted
+
+- `IdSet` accepts a valid string JSON array with valid string hex ids like `["0x15", "0x18", "0x19"]`
+- `IdSet` also accepts a valid string JSON array with valid decimal ids like `[21, 24, 25]`
+- `IdSet` also accepts a valid string JSON array with valid decimal ids being passed on as string like `["21", "24", "25"]`
+
+## BindIdSet support
+
+As `IdSet` is an alternative to `InVirtualSet()`, `bindIdSet` also works with `IfdSet` virtual table
+
+```sql
+SELECT i FROM aps.TestElement,ECVLib.IdSet(?) where id = ECInstanceId
+```
+
+- bindIdSet 1, [0x15, 0x18, 0x19]
+
+## Migrating from `InVirtualSet`
+
+The following ECSql query using `InVirtualSet`
+
+```sql
+SELECT i FROM aps.TestElement where InVirtualSet(?, ECInstanceId)
+```
+
+can be translated using `IdSet` as follows
+
+```sql
+SELECT i FROM aps.TestElement,ECVLib.IdSet(?) where id = ECInstanceId
+```
+
+[ECSql Syntax](./index.md)
diff --git a/docs/learning/ECSqlReference/index.md b/docs/learning/ECSqlReference/index.md
index 37ffa0488a9d..aa0a8740f9e0 100644
--- a/docs/learning/ECSqlReference/index.md
+++ b/docs/learning/ECSqlReference/index.md
@@ -46,3 +46,4 @@
- [ECSQL Keywords](./ECSqlKeywords.md)
- [Escaping keywords](./ECSqlKeywords.md#escaping-keywords)
- [Views](./Views.md)
+- [IdSet Virtual Table](./IdSet.md)
From 0f0e28dfbea4c1168a6f9edd809fc041b06a8cd7 Mon Sep 17 00:00:00 2001
From: soham-bentley <177123878+soham-bentley@users.noreply.github.com>
Date: Fri, 17 Jan 2025 18:01:53 +0530
Subject: [PATCH 08/12] More tests added
---
.../test/ecsql/queries/IdSetVTTests.ecsql.md | 174 ++++++++++++++++++
1 file changed, 174 insertions(+)
diff --git a/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md b/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md
index 15d610191712..5696b8c94f6a 100644
--- a/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md
+++ b/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md
@@ -93,3 +93,177 @@ SELECT i FROM aps.TestElement,ECVLib.IdSet(?) where id = ECInstanceId
| i |
| --- |
+
+# Testing IdSet following cte subquery
+
+- dataset: AllProperties.bim
+- bindIdSet 1, [0x15, 0x18, 0x19]
+
+```sql
+SELECT
+ b
+FROM
+ (
+ WITH
+ cte (a, b) AS (
+ SELECT ECInstanceId, i FROM aps.TestElement ) SELECT * FROM cte
+ ),
+ ECVLib.IdSet (?)
+WHERE
+ id = a
+```
+
+| className | accessString | generated | index | jsonName | name | extendedType | typeName | type |
+| --------- | ------------ | --------- | ----- | -------- | ---- | ------------ | -------- | ---- |
+| | b | true | 0 | b | b | undefined | int | Int |
+
+| b |
+| --- |
+| 101 |
+| 104 |
+| 105 |
+
+# Testing cte subquery following IdSet
+
+- dataset: AllProperties.bim
+- bindIdSet 1, [0x15, 0x18, 0x19]
+
+```sql
+SELECT
+ b
+FROM
+ECVLib.IdSet (?),
+ (
+ WITH
+ cte (a, b) AS (
+ SELECT ECInstanceId, i FROM aps.TestElement ) SELECT * FROM cte
+ )
+WHERE
+ id = a
+```
+
+| className | accessString | generated | index | jsonName | name | extendedType | typeName | type |
+| --------- | ------------ | --------- | ----- | -------- | ---- | ------------ | -------- | ---- |
+| | b | true | 0 | b | b | undefined | int | Int |
+
+| b |
+| --- |
+| 101 |
+| 104 |
+| 105 |
+
+# Testing nested CTE subquery following IdSet
+
+- dataset: AllProperties.bim
+- bindIdSet 1, [0x15, 0x18, 0x19]
+
+```sql
+SELECT
+ b
+FROM
+ECVLib.IdSet (?),
+( select * from (
+ WITH
+ cte (a, b) AS (
+ SELECT ECInstanceId, i FROM aps.TestElement ) SELECT * FROM cte
+ ))
+WHERE
+ id = a
+```
+
+| className | accessString | generated | index | jsonName | name | extendedType | typeName | type |
+| --------- | ------------ | --------- | ----- | -------- | ---- | ------------ | -------- | ---- |
+| | b | true | 0 | b | b | undefined | int | Int |
+
+| b |
+| --- |
+| 101 |
+| 104 |
+| 105 |
+
+# Testing IdSet following nested CTE subquery
+
+- dataset: AllProperties.bim
+- bindIdSet 1, [0x15, 0x18, 0x19]
+
+```sql
+SELECT
+ b
+FROM
+( select * from (
+ WITH
+ cte (a, b) AS (
+ SELECT ECInstanceId, i FROM aps.TestElement ) SELECT * FROM cte
+ )),
+ECVLib.IdSet (?)
+WHERE
+ id = a
+```
+
+| className | accessString | generated | index | jsonName | name | extendedType | typeName | type |
+| --------- | ------------ | --------- | ----- | -------- | ---- | ------------ | -------- | ---- |
+| | b | true | 0 | b | b | undefined | int | Int |
+
+| b |
+| --- |
+| 101 |
+| 104 |
+| 105 |
+
+# Testing IdSet following nested CTE without sub columns subquery
+
+- dataset: AllProperties.bim
+- bindIdSet 1, [0x15, 0x18, 0x19]
+
+```sql
+SELECT
+ i
+FROM
+( select * from (
+ WITH
+ cte AS (
+ SELECT ECInstanceId, i FROM aps.TestElement ) SELECT * FROM cte
+ )),
+ECVLib.IdSet (?)
+WHERE
+ id = ECInstanceId
+```
+
+| className | accessString | generated | index | jsonName | name | extendedType | typeName |
+| ------------------------ | ------------ | --------- | ----- | -------- | ---- | ------------ | -------- |
+| AllProperties:IPrimitive | i | false | 0 | i | i | undefined | int |
+
+| i |
+| --- |
+| 101 |
+| 104 |
+| 105 |
+
+# Testing CTE without sub columns subquery following IdSet
+
+- dataset: AllProperties.bim
+- bindIdSet 1, [0x15, 0x18, 0x19]
+
+```sql
+SELECT
+ i
+FROM
+ECVLib.IdSet (?),
+(
+ WITH
+ cte AS (
+ SELECT ECInstanceId, i FROM aps.TestElement ) SELECT * FROM cte
+ )
+WHERE
+ id = ECInstanceId
+```
+
+| className | accessString | generated | index | jsonName | name | extendedType | typeName |
+| ------------------------ | ------------ | --------- | ----- | -------- | ---- | ------------ | -------- |
+| AllProperties:IPrimitive | i | false | 0 | i | i | undefined | int |
+
+| i |
+| --- |
+| 101 |
+| 104 |
+| 105 |
From 97d88f295c2fc960616537ed4a9a6df275afa2d9 Mon Sep 17 00:00:00 2001
From: soham-bentley <177123878+soham-bentley@users.noreply.github.com>
Date: Fri, 17 Jan 2025 18:34:03 +0530
Subject: [PATCH 09/12] More tests added and documentation updated
---
.../test/ecsql/queries/IdSetVTTests.ecsql.md | 40 +++++++++++++++++++
docs/learning/ECSqlReference/IdSet.md | 2 +-
2 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md b/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md
index 5696b8c94f6a..fc92e2e98ec8 100644
--- a/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md
+++ b/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md
@@ -1,5 +1,45 @@
Copyright © Bentley Systems, Incorporated. All rights reserved. See [LICENSE.md](../../../../LICENSE.md) for license terms and full copyright notice.
+# Testing returned values of IdSet virtual table
+
+- dataset: AllProperties.bim
+
+```sql
+SELECT id from ECVLib.IdSet(?)
+```
+
+- bindIdSet 1, [0x15, 0x18, 0x19]
+
+| className | accessString | generated | index | jsonName | name | extendedType | typeName | type | originPropertyName |
+| --------- | ------------ | --------- | ----- | -------- | ---- | ------------ | -------- | ---- | ------------------ |
+| | id | false | 0 | id | id | Id | long | Id | id |
+
+| id |
+| ---- |
+| 0x15 |
+| 0x18 |
+| 0x19 |
+
+# Testing returned values of IdSet virtual table with alias
+
+- dataset: AllProperties.bim
+
+```sql
+SELECT id a from ECVLib.IdSet(?)
+```
+
+- bindIdSet 1, [0x15, 0x18, 0x19]
+
+| className | accessString | generated | index | jsonName | name | extendedType | typeName | type | originPropertyName |
+| --------- | ------------ | --------- | ----- | -------- | ---- | ------------ | -------- | ---- | ------------------ |
+| | a | true | 0 | a | a | Id | long | Id | id |
+
+| a |
+| ---- |
+| 0x15 |
+| 0x18 |
+| 0x19 |
+
# Testing with hard coded json string with hex ids
- dataset: AllProperties.bim
diff --git a/docs/learning/ECSqlReference/IdSet.md b/docs/learning/ECSqlReference/IdSet.md
index 0ea76dd8705a..df5488e5c80c 100644
--- a/docs/learning/ECSqlReference/IdSet.md
+++ b/docs/learning/ECSqlReference/IdSet.md
@@ -1,6 +1,6 @@
# IdSet Virtual Table
-`IdSet` is an ECSQl built in virtual table which takes in a valid JSON array string of hex or decimal ids and stores the ids as a virtual table. It can be used as an alternative to `InVirtualSet`.
+`IdSet` is an ECSQl built in virtual table which takes in a valid JSON array string of hex or decimal ids and stores the ids as a virtual table. It can be used as an alternative to `InVirtualSet`. The column retuned by `IdSet` virtual table will always be named `id` by default but can be aliased as per choice.
## Syntax
From 898dd59f8affebc90875372f15b1884d2bb7bf6a Mon Sep 17 00:00:00 2001
From: soham-bentley <177123878+soham-bentley@users.noreply.github.com>
Date: Sat, 18 Jan 2025 01:55:32 +0530
Subject: [PATCH 10/12] More tests added
---
.../test/ecsql/queries/IdSetVTTests.ecsql.md | 46 +++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md b/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md
index fc92e2e98ec8..a1cc5e79c812 100644
--- a/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md
+++ b/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md
@@ -76,6 +76,52 @@ SELECT i FROM aps.TestElement,ECVLib.IdSet('[21, 24, "25"]') where id = ECInstan
| 104 |
| 105 |
+# Testing JOINS with IdSet
+
+- dataset: AllProperties.bim
+- bindIdSet 1, [0x15, 0x18, 0x19]
+- only: true
+
+```sql
+SELECT e.i FROM aps.TestElement e INNER JOIN ECVLib.IdSet(?) v ON e.ECInstanceId = v.id
+```
+
+| className | accessString | generated | index | jsonName | name | extendedType | typeName | type | originPropertyName |
+| ------------------------ | ------------ | --------- | ----- | -------- | ---- | ------------ | -------- | ---- | ------------------ |
+| AllProperties:IPrimitive | i | false | 0 | i | i | undefined | int | Int | i |
+
+| i |
+| --- |
+| 101 |
+| 104 |
+| 105 |
+
+# Testing JOINS with IdSet and also select VirtualProp
+
+- dataset: AllProperties.bim
+- bindIdSet 1, [0x15, 0x18, 0x19]
+- only: true
+
+```sql
+SELECT
+ e.i,
+ v.id
+FROM
+ aps.TestElement e
+ INNER JOIN ECVLib.IdSet (?) v ON v.id = e.ECInstanceId
+```
+
+| className | accessString | generated | index | jsonName | name | extendedType | typeName | type | originPropertyName |
+| ------------------------ | ------------ | --------- | ----- | -------- | ---- | ------------ | -------- | ---- | ------------------ |
+| AllProperties:IPrimitive | i | false | 0 | i | i | undefined | int | Int | i |
+| | id | false | 1 | id | id | Id | long | Id | id |
+
+| i | id |
+| --- | ---- |
+| 101 | 0x15 |
+| 104 | 0x18 |
+| 105 | 0x19 |
+
# Testing by binding with hex ids
- dataset: AllProperties.bim
From b49d57c3975479374dddee8bc15e2477f1870ae7 Mon Sep 17 00:00:00 2001
From: soham-bentley <177123878+soham-bentley@users.noreply.github.com>
Date: Sat, 18 Jan 2025 01:57:31 +0530
Subject: [PATCH 11/12] only removed
---
core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md | 2 --
1 file changed, 2 deletions(-)
diff --git a/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md b/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md
index a1cc5e79c812..94e5342c1a71 100644
--- a/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md
+++ b/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md
@@ -80,7 +80,6 @@ SELECT i FROM aps.TestElement,ECVLib.IdSet('[21, 24, "25"]') where id = ECInstan
- dataset: AllProperties.bim
- bindIdSet 1, [0x15, 0x18, 0x19]
-- only: true
```sql
SELECT e.i FROM aps.TestElement e INNER JOIN ECVLib.IdSet(?) v ON e.ECInstanceId = v.id
@@ -100,7 +99,6 @@ SELECT e.i FROM aps.TestElement e INNER JOIN ECVLib.IdSet(?) v ON e.ECInstanceId
- dataset: AllProperties.bim
- bindIdSet 1, [0x15, 0x18, 0x19]
-- only: true
```sql
SELECT
From c0527242f57185f0ce86c0284b0cac6c75253482 Mon Sep 17 00:00:00 2001
From: soham-bentley <177123878+soham-bentley@users.noreply.github.com>
Date: Mon, 20 Jan 2025 14:11:04 +0530
Subject: [PATCH 12/12] More JOIN tests added
---
.../test/ecsql/queries/IdSetVTTests.ecsql.md | 89 ++++++++++++++++++-
1 file changed, 87 insertions(+), 2 deletions(-)
diff --git a/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md b/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md
index 94e5342c1a71..35013dcc3227 100644
--- a/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md
+++ b/core/backend/src/test/ecsql/queries/IdSetVTTests.ecsql.md
@@ -76,7 +76,7 @@ SELECT i FROM aps.TestElement,ECVLib.IdSet('[21, 24, "25"]') where id = ECInstan
| 104 |
| 105 |
-# Testing JOINS with IdSet
+# Testing INNER JOINS with IdSet
- dataset: AllProperties.bim
- bindIdSet 1, [0x15, 0x18, 0x19]
@@ -95,7 +95,7 @@ SELECT e.i FROM aps.TestElement e INNER JOIN ECVLib.IdSet(?) v ON e.ECInstanceId
| 104 |
| 105 |
-# Testing JOINS with IdSet and also select VirtualProp
+# Testing INNER JOINS with IdSet and also select VirtualProp
- dataset: AllProperties.bim
- bindIdSet 1, [0x15, 0x18, 0x19]
@@ -120,6 +120,91 @@ FROM
| 104 | 0x18 |
| 105 | 0x19 |
+# Testing LEFT OUTER JOIN on virtual table
+
+- dataset: AllProperties.bim
+
+```sql
+SELECT
+ e.ECInstanceId,
+ e.i,
+ v.id
+FROM
+ ECVLib.IdSet ('["0x15", "0x18", "0x19"]') v
+ LEFT OUTER JOIN aps.TestElement e ON e.ECInstanceId = v.id
+```
+
+| className | accessString | generated | index | jsonName | name | extendedType | typeName | type | originPropertyName |
+| ------------------------ | ------------ | --------- | ----- | -------- | ------------ | ------------ | -------- | ---- | ------------------ |
+| | ECInstanceId | false | 0 | id | ECInstanceId | Id | long | Id | ECInstanceId |
+| AllProperties:IPrimitive | i | false | 1 | i | i | undefined | int | Int | i |
+| | id | false | 2 | id_1 | id | Id | long | Id | id |
+
+| ECInstanceId | i | id |
+| ------------ | --- | ---- |
+| 0x15 | 101 | 0x15 |
+| 0x18 | 104 | 0x18 |
+| 0x19 | 105 | 0x19 |
+
+# Testing LEFT OUTER JOIN on test table
+
+- dataset: AllProperties.bim
+
+```sql
+SELECT
+ e.ECInstanceId,
+ e.i,
+ v.id
+FROM
+ aps.TestElement e
+ LEFT OUTER JOIN ECVLib.IdSet ('["0x15", "0x18", "0x19"]') v ON e.ECInstanceId = v.id
+```
+
+| className | accessString | generated | index | jsonName | name | extendedType | typeName | type | originPropertyName |
+| ------------------------ | ------------ | --------- | ----- | -------- | ------------ | ------------ | -------- | ---- | ------------------ |
+| | ECInstanceId | false | 0 | id | ECInstanceId | Id | long | Id | ECInstanceId |
+| AllProperties:IPrimitive | i | false | 1 | i | i | undefined | int | Int | i |
+| | id | false | 2 | id_1 | id | Id | long | Id | id |
+
+| ECInstanceId | i | id |
+| ------------ | --- | --------- |
+| 0x14 | 100 | undefined |
+| 0x15 | 101 | 0x15 |
+| 0x16 | 102 | undefined |
+| 0x17 | 103 | undefined |
+| 0x18 | 104 | 0x18 |
+| 0x19 | 105 | 0x19 |
+| 0x1a | 106 | undefined |
+| 0x1b | 107 | undefined |
+| 0x1c | 108 | undefined |
+| 0x1d | 109 | undefined |
+
+# Testing JOIN
+
+- dataset: AllProperties.bim
+
+```sql
+SELECT
+ e.ECInstanceId,
+ e.i,
+ v.id
+FROM
+ aps.TestElement e
+ JOIN ECVLib.IdSet ('["0x15", "0x18", "0x19"]') v ON e.ECInstanceId = v.id
+```
+
+| className | accessString | generated | index | jsonName | name | extendedType | typeName | type | originPropertyName |
+| ------------------------ | ------------ | --------- | ----- | -------- | ------------ | ------------ | -------- | ---- | ------------------ |
+| | ECInstanceId | false | 0 | id | ECInstanceId | Id | long | Id | ECInstanceId |
+| AllProperties:IPrimitive | i | false | 1 | i | i | undefined | int | Int | i |
+| | id | false | 2 | id_1 | id | Id | long | Id | id |
+
+| ECInstanceId | i | id |
+| ------------ | --- | ---- |
+| 0x15 | 101 | 0x15 |
+| 0x18 | 104 | 0x18 |
+| 0x19 | 105 | 0x19 |
+
# Testing by binding with hex ids
- dataset: AllProperties.bim