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