pqb 0.26.0 → 0.26.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -989,6 +989,7 @@ const processWhere = (ands, ctx, table, query, data, quotedAs) => {
989
989
  });
990
990
  } else if (key === "EXISTS") {
991
991
  const joinItems = Array.isArray(value[0]) ? value : [value];
992
+ const joinSet = joinItems.length > 1 ? /* @__PURE__ */ new Set() : null;
992
993
  for (const args of joinItems) {
993
994
  const { target, conditions } = processJoinItem(
994
995
  ctx,
@@ -997,7 +998,13 @@ const processWhere = (ands, ctx, table, query, data, quotedAs) => {
997
998
  args,
998
999
  quotedAs
999
1000
  );
1000
- ands.push(`EXISTS (SELECT 1 FROM ${target} WHERE ${conditions})`);
1001
+ const sql = `EXISTS (SELECT 1 FROM ${target} WHERE ${conditions})`;
1002
+ if (joinSet) {
1003
+ if (joinSet.has(sql))
1004
+ continue;
1005
+ joinSet.add(sql);
1006
+ }
1007
+ ands.push(sql);
1001
1008
  }
1002
1009
  } else if (key === "SEARCH") {
1003
1010
  const search = value;
@@ -1314,15 +1321,15 @@ const getObjectOrRawConditions = (ctx, query, data, quotedAs, joinAs, joinShape)
1314
1321
  };
1315
1322
  const pushJoinSql = (ctx, table, query, quotedAs) => {
1316
1323
  var _a;
1324
+ const joinSet = query.join.length > 1 ? /* @__PURE__ */ new Set() : null;
1317
1325
  for (const item of query.join) {
1326
+ let sql;
1318
1327
  if (Array.isArray(item)) {
1319
1328
  const q = item[1];
1320
1329
  const { aliasValue } = ctx;
1321
1330
  ctx.aliasValue = true;
1322
1331
  const as = item[2];
1323
- ctx.sql.push(
1324
- `${item[0]} LATERAL (${q.toSQL(ctx).text}) "${((_a = query.joinOverrides) == null ? void 0 : _a[as]) || as}" ON true`
1325
- );
1332
+ sql = `${item[0]} LATERAL (${q.toSQL(ctx).text}) "${((_a = query.joinOverrides) == null ? void 0 : _a[as]) || as}" ON true`;
1326
1333
  ctx.aliasValue = aliasValue;
1327
1334
  } else {
1328
1335
  const { target, conditions } = processJoinItem(
@@ -1332,10 +1339,14 @@ const pushJoinSql = (ctx, table, query, quotedAs) => {
1332
1339
  item,
1333
1340
  quotedAs
1334
1341
  );
1335
- ctx.sql.push(item.type, target);
1336
- if (conditions)
1337
- ctx.sql.push("ON", conditions);
1342
+ sql = conditions ? `${item.type} ${target} ON ${conditions}` : `${item.type} ${target} ON true`;
1343
+ }
1344
+ if (joinSet) {
1345
+ if (joinSet.has(sql))
1346
+ continue;
1347
+ joinSet.add(sql);
1338
1348
  }
1349
+ ctx.sql.push(sql);
1339
1350
  }
1340
1351
  };
1341
1352
  const skipQueryKeysForSubQuery = {
@@ -2919,9 +2930,17 @@ const pushDeleteSql = (ctx, table, query, quotedAs) => {
2919
2930
  let conditions;
2920
2931
  if ((_a = query.join) == null ? void 0 : _a.length) {
2921
2932
  const items = [];
2933
+ const joinSet = query.join.length > 1 ? /* @__PURE__ */ new Set() : null;
2922
2934
  for (const item of query.join) {
2923
2935
  if (!Array.isArray(item)) {
2924
- items.push(processJoinItem(ctx, table, query, item, quotedAs));
2936
+ const join = processJoinItem(ctx, table, query, item, quotedAs);
2937
+ const key = `${join.target}${join.conditions}`;
2938
+ if (joinSet) {
2939
+ if (joinSet.has(key))
2940
+ continue;
2941
+ joinSet.add(key);
2942
+ }
2943
+ items.push(join);
2925
2944
  }
2926
2945
  }
2927
2946
  if (items.length) {
@@ -7355,6 +7374,35 @@ class Join {
7355
7374
  *
7356
7375
  * When no matching record is found, it will skip records of the main table.
7357
7376
  *
7377
+ * When joining the same table with the same condition more than once, duplicated joins will be ignored:
7378
+ *
7379
+ * ```ts
7380
+ * // joining a relation
7381
+ * db.post.join('comments').join('comments');
7382
+ *
7383
+ * // joining a table with a condition
7384
+ * db.post
7385
+ * .join('comments', 'comments.postId', 'post.id')
7386
+ * .join('comments', 'comments.postId', 'post.id');
7387
+ * ```
7388
+ *
7389
+ * Both queries will produce SQL with only 1 join
7390
+ *
7391
+ * ```sql
7392
+ * SELECT * FROM post JOIN comments ON comments.postId = post.id
7393
+ * ```
7394
+ *
7395
+ * However, this is only possible if the join has no dynamic values:
7396
+ *
7397
+ * ```ts
7398
+ * db.post
7399
+ * .join('comments', (q) => q.where({ rating: { gt: 5 } }))
7400
+ * .join('comments', (q) => q.where({ rating: { gt: 5 } }));
7401
+ * ```
7402
+ *
7403
+ * Both joins above have the same `{ gt: 5 }`, but still, the `5` is a dynamic value and in this case joins will be duplicated,
7404
+ * resulting in a database error.
7405
+ *
7358
7406
  * ### join relation
7359
7407
  *
7360
7408
  * When relations are defined between the tables, you can join them by a relation name.