@mikro-orm/sql 7.1.13-dev.5 → 7.1.13-dev.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/sql",
3
- "version": "7.1.13-dev.5",
3
+ "version": "7.1.13-dev.7",
4
4
  "description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
5
5
  "keywords": [
6
6
  "data-mapper",
@@ -53,7 +53,7 @@
53
53
  "@mikro-orm/core": "^7.1.12"
54
54
  },
55
55
  "peerDependencies": {
56
- "@mikro-orm/core": "7.1.13-dev.5"
56
+ "@mikro-orm/core": "7.1.13-dev.7"
57
57
  },
58
58
  "engines": {
59
59
  "node": ">= 22.17.0"
@@ -994,6 +994,13 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
994
994
  processPopulateHint(): void;
995
995
  private processPopulateWhere;
996
996
  private mergeOnConditions;
997
+ /**
998
+ * `$or` branches can be moved to a join's `on` clause only when they all target that same join
999
+ * and stay flat — a partial `$or` in the `on` clause would drop rows matching a sibling branch,
1000
+ * and nested operators cannot be preserved inside a distributed disjunction, as `mergeOnConditions`
1001
+ * would flatten them into `and` conjuncts.
1002
+ */
1003
+ private canDistributeOrBranches;
997
1004
  /**
998
1005
  * When adding an inner join on a left joined relation, we need to nest them,
999
1006
  * otherwise the inner join could discard rows of the root table.
@@ -2038,6 +2038,10 @@ export class QueryBuilder {
2038
2038
  for (const k of Object.keys(cond)) {
2039
2039
  if (Utils.isOperator(k)) {
2040
2040
  if (Array.isArray(cond[k])) {
2041
+ // a partial `$or` on a join drops rows matching a sibling branch, but entity filters have no other sink, so they must pass
2042
+ if (k === '$or' && !filter && !this.canDistributeOrBranches(cond[k], joins)) {
2043
+ continue;
2044
+ }
2041
2045
  cond[k].forEach((c) => this.mergeOnConditions(joins, c, filter, k));
2042
2046
  }
2043
2047
  /* v8 ignore next */
@@ -2071,6 +2075,29 @@ export class QueryBuilder {
2071
2075
  }
2072
2076
  }
2073
2077
  }
2078
+ /**
2079
+ * `$or` branches can be moved to a join's `on` clause only when they all target that same join
2080
+ * and stay flat — a partial `$or` in the `on` clause would drop rows matching a sibling branch,
2081
+ * and nested operators cannot be preserved inside a distributed disjunction, as `mergeOnConditions`
2082
+ * would flatten them into `and` conjuncts.
2083
+ */
2084
+ canDistributeOrBranches(branches, joins) {
2085
+ const aliases = new Set();
2086
+ const collectAliases = (cond) => {
2087
+ for (const k of Object.keys(cond)) {
2088
+ if (Utils.isOperator(k)) {
2089
+ Utils.asArray(cond[k]).forEach((c) => collectAliases(c));
2090
+ }
2091
+ else {
2092
+ aliases.add(this.helper.splitField(k)[0]);
2093
+ }
2094
+ }
2095
+ };
2096
+ branches.forEach(collectAliases);
2097
+ const targeted = joins.filter(j => aliases.has(j.alias));
2098
+ const flat = branches.every(branch => Object.keys(branch).every(k => !Utils.isOperator(k)));
2099
+ return aliases.size === 1 && targeted.length === 1 && flat;
2100
+ }
2074
2101
  /**
2075
2102
  * When adding an inner join on a left joined relation, we need to nest them,
2076
2103
  * otherwise the inner join could discard rows of the root table.