pqb 0.26.0 → 0.26.1

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.d.ts CHANGED
@@ -863,6 +863,35 @@ declare class Join {
863
863
  *
864
864
  * When no matching record is found, it will skip records of the main table.
865
865
  *
866
+ * When joining the same table with the same condition more than once, duplicated joins will be ignored:
867
+ *
868
+ * ```ts
869
+ * // joining a relation
870
+ * db.post.join('comments').join('comments');
871
+ *
872
+ * // joining a table with a condition
873
+ * db.post
874
+ * .join('comments', 'comments.postId', 'post.id')
875
+ * .join('comments', 'comments.postId', 'post.id');
876
+ * ```
877
+ *
878
+ * Both queries will produce SQL with only 1 join
879
+ *
880
+ * ```sql
881
+ * SELECT * FROM post JOIN comments ON comments.postId = post.id
882
+ * ```
883
+ *
884
+ * However, this is only possible if the join has no dynamic values:
885
+ *
886
+ * ```ts
887
+ * db.post
888
+ * .join('comments', (q) => q.where({ rating: { gt: 5 } }))
889
+ * .join('comments', (q) => q.where({ rating: { gt: 5 } }));
890
+ * ```
891
+ *
892
+ * Both joins above have the same `{ gt: 5 }`, but still, the `5` is a dynamic value and in this case joins will be duplicated,
893
+ * resulting in a database error.
894
+ *
866
895
  * ### join relation
867
896
  *
868
897
  * When relations are defined between the tables, you can join them by a relation name.
package/dist/index.js CHANGED
@@ -656,6 +656,7 @@ const columnCode = (type, t, code, data = type.data, skip) => {
656
656
  return code.length === 1 && typeof code[0] === "string" ? code[0] : code;
657
657
  };
658
658
 
659
+ const joinStatementsSet = /* @__PURE__ */ new Set();
659
660
  function simpleColumnToSQL(ctx, key, column, quotedAs) {
660
661
  if (!column)
661
662
  return `"${key}"`;
@@ -991,6 +992,7 @@ const processWhere = (ands, ctx, table, query, data, quotedAs) => {
991
992
  });
992
993
  } else if (key === "EXISTS") {
993
994
  const joinItems = Array.isArray(value[0]) ? value : [value];
995
+ joinStatementsSet.clear();
994
996
  for (const args of joinItems) {
995
997
  const { target, conditions } = processJoinItem(
996
998
  ctx,
@@ -999,7 +1001,11 @@ const processWhere = (ands, ctx, table, query, data, quotedAs) => {
999
1001
  args,
1000
1002
  quotedAs
1001
1003
  );
1002
- ands.push(`EXISTS (SELECT 1 FROM ${target} WHERE ${conditions})`);
1004
+ const sql = `EXISTS (SELECT 1 FROM ${target} WHERE ${conditions})`;
1005
+ if (!joinStatementsSet.has(sql)) {
1006
+ joinStatementsSet.add(sql);
1007
+ ands.push(sql);
1008
+ }
1003
1009
  }
1004
1010
  } else if (key === "SEARCH") {
1005
1011
  const search = value;
@@ -1316,15 +1322,15 @@ const getObjectOrRawConditions = (ctx, query, data, quotedAs, joinAs, joinShape)
1316
1322
  };
1317
1323
  const pushJoinSql = (ctx, table, query, quotedAs) => {
1318
1324
  var _a;
1325
+ joinStatementsSet.clear();
1319
1326
  for (const item of query.join) {
1327
+ let sql;
1320
1328
  if (Array.isArray(item)) {
1321
1329
  const q = item[1];
1322
1330
  const { aliasValue } = ctx;
1323
1331
  ctx.aliasValue = true;
1324
1332
  const as = item[2];
1325
- ctx.sql.push(
1326
- `${item[0]} LATERAL (${q.toSQL(ctx).text}) "${((_a = query.joinOverrides) == null ? void 0 : _a[as]) || as}" ON true`
1327
- );
1333
+ sql = `${item[0]} LATERAL (${q.toSQL(ctx).text}) "${((_a = query.joinOverrides) == null ? void 0 : _a[as]) || as}" ON true`;
1328
1334
  ctx.aliasValue = aliasValue;
1329
1335
  } else {
1330
1336
  const { target, conditions } = processJoinItem(
@@ -1334,9 +1340,11 @@ const pushJoinSql = (ctx, table, query, quotedAs) => {
1334
1340
  item,
1335
1341
  quotedAs
1336
1342
  );
1337
- ctx.sql.push(item.type, target);
1338
- if (conditions)
1339
- ctx.sql.push("ON", conditions);
1343
+ sql = conditions ? `${item.type} ${target} ON ${conditions}` : `${item.type} ${target} ON true`;
1344
+ }
1345
+ if (!joinStatementsSet.has(sql)) {
1346
+ joinStatementsSet.add(sql);
1347
+ ctx.sql.push(sql);
1340
1348
  }
1341
1349
  }
1342
1350
  };
@@ -2921,9 +2929,15 @@ const pushDeleteSql = (ctx, table, query, quotedAs) => {
2921
2929
  let conditions;
2922
2930
  if ((_a = query.join) == null ? void 0 : _a.length) {
2923
2931
  const items = [];
2932
+ joinStatementsSet.clear();
2924
2933
  for (const item of query.join) {
2925
2934
  if (!Array.isArray(item)) {
2926
- items.push(processJoinItem(ctx, table, query, item, quotedAs));
2935
+ const join = processJoinItem(ctx, table, query, item, quotedAs);
2936
+ const key = `${join.target}${join.conditions}`;
2937
+ if (!joinStatementsSet.has(key)) {
2938
+ joinStatementsSet.add(key);
2939
+ items.push(join);
2940
+ }
2927
2941
  }
2928
2942
  }
2929
2943
  if (items.length) {
@@ -7357,6 +7371,35 @@ class Join {
7357
7371
  *
7358
7372
  * When no matching record is found, it will skip records of the main table.
7359
7373
  *
7374
+ * When joining the same table with the same condition more than once, duplicated joins will be ignored:
7375
+ *
7376
+ * ```ts
7377
+ * // joining a relation
7378
+ * db.post.join('comments').join('comments');
7379
+ *
7380
+ * // joining a table with a condition
7381
+ * db.post
7382
+ * .join('comments', 'comments.postId', 'post.id')
7383
+ * .join('comments', 'comments.postId', 'post.id');
7384
+ * ```
7385
+ *
7386
+ * Both queries will produce SQL with only 1 join
7387
+ *
7388
+ * ```sql
7389
+ * SELECT * FROM post JOIN comments ON comments.postId = post.id
7390
+ * ```
7391
+ *
7392
+ * However, this is only possible if the join has no dynamic values:
7393
+ *
7394
+ * ```ts
7395
+ * db.post
7396
+ * .join('comments', (q) => q.where({ rating: { gt: 5 } }))
7397
+ * .join('comments', (q) => q.where({ rating: { gt: 5 } }));
7398
+ * ```
7399
+ *
7400
+ * Both joins above have the same `{ gt: 5 }`, but still, the `5` is a dynamic value and in this case joins will be duplicated,
7401
+ * resulting in a database error.
7402
+ *
7360
7403
  * ### join relation
7361
7404
  *
7362
7405
  * When relations are defined between the tables, you can join them by a relation name.