@mikro-orm/sql 7.1.0-dev.36 → 7.1.0-dev.38

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.
@@ -118,6 +118,13 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
118
118
  mergeJoinedResult<T extends object>(rawResults: EntityData<T>[], meta: EntityMetadata<T>, joinedProps: PopulateOptions<T>[]): EntityData<T>[];
119
119
  protected shouldHaveColumn<T, U>(meta: EntityMetadata<T>, prop: EntityProperty<U>, populate: readonly PopulateOptions<U>[], fields?: readonly InternalField<U>[], exclude?: readonly InternalField<U>[]): boolean;
120
120
  protected getFieldsForJoinedLoad<T extends object>(qb: AnyQueryBuilder<T>, meta: EntityMetadata<T>, options: FieldsForJoinedLoadOptions<T>): InternalField<T>[];
121
+ /**
122
+ * Walks the TPT inheritance chain of `leafMeta` and INNER JOINs each parent table.
123
+ * Registers the parent aliases in `qb.state.tptAlias` so column resolution finds them
124
+ * when filter conditions reference parent-table columns.
125
+ * @internal
126
+ */
127
+ protected addTPTParentJoinsForRelation<T extends object>(qb: AnyQueryBuilder<T>, leafMeta: EntityMetadata, leafAlias: string, basePath: string): void;
121
128
  /**
122
129
  * Adds LEFT JOINs and fields for TPT polymorphic loading when populating a relation to a TPT base class.
123
130
  * @internal
@@ -1727,6 +1727,13 @@ export class AbstractSqlDriver extends DatabaseDriver {
1727
1727
  const targetPath = `${pathPrefix}${basePath}[${targetMeta.className}]`;
1728
1728
  const schema = targetMeta.schema === '*' ? (options?.schema ?? this.config.get('schema')) : targetMeta.schema;
1729
1729
  qb.addPolymorphicJoin(prop, targetMeta, options.parentTableAlias, tableAlias, JoinType.leftJoin, targetPath, schema);
1730
+ // For polymorphic targets that are TPT child entities, INNER JOIN parent tables so that
1731
+ // filter conditions referencing parent-table columns resolve to the correct alias. The
1732
+ // INNER JOINs get nested inside the polymorphic LEFT JOIN by processNestedJoins, which
1733
+ // keeps the resulting query valid for rows pointing to other polymorphic targets.
1734
+ if (targetMeta.inheritanceType === 'tpt' && targetMeta.tptParent) {
1735
+ this.addTPTParentJoinsForRelation(qb, targetMeta, tableAlias, targetPath);
1736
+ }
1730
1737
  // For polymorphic targets that are TPT base classes, also LEFT JOIN
1731
1738
  // all descendant tables so child-specific fields can be selected.
1732
1739
  if (targetMeta.inheritanceType === 'tpt' && targetMeta.tptChildren?.length && !ref) {
@@ -1775,17 +1782,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
1775
1782
  qb.join(field, tableAlias, {}, joinType, path, schema);
1776
1783
  // For relations to TPT child entities, INNER JOIN parent tables (GH #7469)
1777
1784
  if (meta2.inheritanceType === 'tpt' && meta2.tptParent) {
1778
- let childAlias = tableAlias;
1779
- let childMeta = meta2;
1780
- while (childMeta.tptParent) {
1781
- const parentMeta = childMeta.tptParent;
1782
- const parentAlias = qb.getNextAlias(parentMeta.className);
1783
- qb.createAlias(parentMeta.class, parentAlias);
1784
- qb.state.tptAlias[`${tableAlias}:${parentMeta.className}`] = parentAlias;
1785
- qb.addPropertyJoin(childMeta.tptParentProp, childAlias, parentAlias, JoinType.innerJoin, `${path}.[tpt]${childMeta.className}`);
1786
- childAlias = parentAlias;
1787
- childMeta = parentMeta;
1788
- }
1785
+ this.addTPTParentJoinsForRelation(qb, meta2, tableAlias, path);
1789
1786
  }
1790
1787
  // For relations to TPT base classes, add LEFT JOINs for all child tables (polymorphic loading)
1791
1788
  if (meta2.inheritanceType === 'tpt' && meta2.tptChildren?.length && !ref) {
@@ -1833,6 +1830,25 @@ export class AbstractSqlDriver extends DatabaseDriver {
1833
1830
  }
1834
1831
  return fields;
1835
1832
  }
1833
+ /**
1834
+ * Walks the TPT inheritance chain of `leafMeta` and INNER JOINs each parent table.
1835
+ * Registers the parent aliases in `qb.state.tptAlias` so column resolution finds them
1836
+ * when filter conditions reference parent-table columns.
1837
+ * @internal
1838
+ */
1839
+ addTPTParentJoinsForRelation(qb, leafMeta, leafAlias, basePath) {
1840
+ let childAlias = leafAlias;
1841
+ let childMeta = leafMeta;
1842
+ while (childMeta.tptParent) {
1843
+ const parentMeta = childMeta.tptParent;
1844
+ const parentAlias = qb.getNextAlias(parentMeta.className);
1845
+ qb.createAlias(parentMeta.class, parentAlias);
1846
+ qb.state.tptAlias[`${leafAlias}:${parentMeta.className}`] = parentAlias;
1847
+ qb.addPropertyJoin(childMeta.tptParentProp, childAlias, parentAlias, JoinType.innerJoin, `${basePath}.[tpt]${childMeta.className}`);
1848
+ childAlias = parentAlias;
1849
+ childMeta = parentMeta;
1850
+ }
1851
+ }
1836
1852
  /**
1837
1853
  * Adds LEFT JOINs and fields for TPT polymorphic loading when populating a relation to a TPT base class.
1838
1854
  * @internal
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/sql",
3
- "version": "7.1.0-dev.36",
3
+ "version": "7.1.0-dev.38",
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",
@@ -50,10 +50,10 @@
50
50
  "kysely": "0.29.0"
51
51
  },
52
52
  "devDependencies": {
53
- "@mikro-orm/core": "^7.0.15"
53
+ "@mikro-orm/core": "^7.0.16"
54
54
  },
55
55
  "peerDependencies": {
56
- "@mikro-orm/core": "7.1.0-dev.36"
56
+ "@mikro-orm/core": "7.1.0-dev.38"
57
57
  },
58
58
  "engines": {
59
59
  "node": ">= 22.17.0"
@@ -1777,13 +1777,13 @@ export class QueryBuilder {
1777
1777
  }
1778
1778
  const types = Object.values(meta.root.discriminatorMap).map(cls => this.metadata.get(cls));
1779
1779
  const children = [];
1780
- const lookUpChildren = (ret, type) => {
1781
- const children = types.filter(meta2 => meta2.extends === type);
1782
- children.forEach(m => lookUpChildren(ret, m.class));
1780
+ const lookUpChildren = (ret, parent) => {
1781
+ const children = types.filter(meta2 => meta2.extends && this.metadata.find(meta2.extends) === parent);
1782
+ children.forEach(m => lookUpChildren(ret, m));
1783
1783
  ret.push(...children.filter(c => c.discriminatorValue));
1784
1784
  return children;
1785
1785
  };
1786
- lookUpChildren(children, meta.class);
1786
+ lookUpChildren(children, meta);
1787
1787
  this.andWhere({
1788
1788
  [meta.root.discriminatorColumn]: children.length > 0
1789
1789
  ? { $in: [meta.discriminatorValue, ...children.map(c => c.discriminatorValue)] }