@mikro-orm/sql 7.1.12-dev.2 → 7.1.12-dev.20

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.
@@ -75,8 +75,7 @@ export class SqlEntityManager extends EntityManager {
75
75
  */
76
76
  async countBy(entityName, groupBy, options = {}) {
77
77
  const em = this.getContext(false);
78
- options = { ...options };
79
- em.prepareOptions(options);
78
+ options = em.prepareOptions(options);
80
79
  const meta = em.getMetadata().find(entityName);
81
80
  const fields = Utils.asArray(groupBy);
82
81
  const { where: rawWhere, ...countOptions } = options;
@@ -69,6 +69,8 @@ export declare class PostgreSqlSchemaHelper extends SchemaHelper {
69
69
  createTrigger(table: DatabaseTable, trigger: SqlTriggerDef): string;
70
70
  /** Generates SQL to drop a PostgreSQL trigger and its associated function. */
71
71
  dropTrigger(table: DatabaseTable, trigger: SqlTriggerDef): string;
72
+ /** Flattens `;\n` inside the dollar-quoted blocks of a raw DDL expression, which are not statement boundaries. */
73
+ private flattenDollarQuotedBodies;
72
74
  createRoutine(routine: SqlRoutineDef): string;
73
75
  dropRoutine(routine: SqlRoutineDef): string;
74
76
  getAllRoutines(connection: AbstractSqlConnection, schemas?: string[]): Promise<SqlRoutineDef[]>;
@@ -3,6 +3,8 @@ import { SchemaHelper, stripStatementNewlines } from '../../schema/SchemaHelper.
3
3
  import { normalizePartitionBound, normalizePartitionDefinition } from '../../schema/partitioning.js';
4
4
  /** PostGIS system views that should be automatically ignored */
5
5
  const POSTGIS_VIEWS = ['geography_columns', 'geometry_columns'];
6
+ /** Dollar-quote delimiter, e.g. `$$` or `$body$`, captured so `split` keeps it. */
7
+ const DOLLAR_QUOTE_TAG = /(\$(?:[A-Za-z_]\w*)?\$)/;
6
8
  export class PostgreSqlSchemaHelper extends SchemaHelper {
7
9
  static DEFAULT_VALUES = {
8
10
  'now()': ['now()', 'current_timestamp'],
@@ -505,7 +507,7 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
505
507
  /** Generates SQL to create a PostgreSQL trigger and its associated function. */
506
508
  createTrigger(table, trigger) {
507
509
  if (trigger.expression) {
508
- return trigger.expression;
510
+ return this.flattenDollarQuotedBodies(trigger.expression);
509
511
  }
510
512
  const timing = trigger.timing.toUpperCase();
511
513
  const events = trigger.events.map(e => e.toUpperCase()).join(' OR ');
@@ -523,9 +525,24 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
523
525
  const fnName = this.getSchemaQualifiedTriggerFnName(table, trigger);
524
526
  return `drop trigger if exists ${triggerName} on ${table.getQuotedName()};\ndrop function if exists ${fnName}()`;
525
527
  }
528
+ /** Flattens `;\n` inside the dollar-quoted blocks of a raw DDL expression, which are not statement boundaries. */
529
+ flattenDollarQuotedBodies(ddl) {
530
+ let openTag = '';
531
+ return ddl
532
+ .split(DOLLAR_QUOTE_TAG)
533
+ .map((part, i) => {
534
+ // the capture group puts the delimiters on the odd indexes
535
+ if (i % 2 === 1) {
536
+ openTag = openTag === part ? '' : openTag || part;
537
+ return part;
538
+ }
539
+ return openTag ? stripStatementNewlines(part) : part;
540
+ })
541
+ .join('');
542
+ }
526
543
  createRoutine(routine) {
527
544
  if (routine.expression) {
528
- return routine.expression;
545
+ return this.flattenDollarQuotedBodies(routine.expression);
529
546
  }
530
547
  const qualifiedName = this.qualifiedRoutineName(routine);
531
548
  const params = this.formatRoutineParams(routine);
@@ -489,7 +489,7 @@ export class SqliteSchemaHelper extends SchemaHelper {
489
489
  * Foreign key references can only point to tables in the same database.
490
490
  */
491
491
  getReferencedTableName(referencedTableName, schema) {
492
- const [schemaName, tableName] = this.splitTableName(referencedTableName);
492
+ const [, tableName] = this.splitTableName(referencedTableName);
493
493
  // Strip any schema prefix - SQLite REFERENCES clause doesn't support it
494
494
  return tableName;
495
495
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/sql",
3
- "version": "7.1.12-dev.2",
3
+ "version": "7.1.12-dev.20",
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",
@@ -47,13 +47,13 @@
47
47
  "copy": "node ../../scripts/copy.mjs"
48
48
  },
49
49
  "dependencies": {
50
- "kysely": "0.29.4"
50
+ "kysely": "0.29.5"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@mikro-orm/core": "^7.1.11"
54
54
  },
55
55
  "peerDependencies": {
56
- "@mikro-orm/core": "7.1.12-dev.2"
56
+ "@mikro-orm/core": "7.1.12-dev.20"
57
57
  },
58
58
  "engines": {
59
59
  "node": ">= 22.17.0"
@@ -113,7 +113,8 @@ export class ObjectCriteriaNode extends CriteriaNode {
113
113
  }
114
114
  else if (isRawField) {
115
115
  const rawField = RawQueryFragment.getKnownFragment(field);
116
- o[raw(rawField.sql.replaceAll(ALIAS_REPLACEMENT, alias), rawField.params)] = payload;
116
+ qb.ensureTPTJoins();
117
+ o[raw(qb.helper.replaceAliases(rawField.sql, alias), rawField.params)] = payload;
117
118
  }
118
119
  else if (!childNode.validate && !childNode.prop && !field.includes('.') && !operator) {
119
120
  // wrap unknown fields in raw() to prevent alias prefixing (e.g. raw SQL aliases in HAVING)
@@ -152,11 +152,10 @@ type ContextFilterKeys<Context> = {
152
152
  type RawFilterKeys<RawAliases extends string> = {
153
153
  [K in RawAliases]?: AliasedFilterValue;
154
154
  };
155
- type NestedFilterCondition<Entity, RootAlias extends string, Context, RawAliases extends string> = ObjectQuery<Entity> & (IsNever<RootAlias> extends true ? {} : string extends RootAlias ? {} : RootAliasFilterKeys<RootAlias, Entity>) & ([Context] extends [never] ? {} : ContextFilterKeys<Context>) & (IsNever<RawAliases> extends true ? {} : string extends RawAliases ? {} : RawFilterKeys<RawAliases>);
156
155
  type GroupOperators<RootAlias extends string, Context, Entity, RawAliases extends string> = {
157
- $and?: NestedFilterCondition<Entity, RootAlias, Context, RawAliases>[];
158
- $or?: NestedFilterCondition<Entity, RootAlias, Context, RawAliases>[];
159
- $not?: NestedFilterCondition<Entity, RootAlias, Context, RawAliases>;
156
+ $and?: QBFilterQuery<Entity, RootAlias, Context, RawAliases>[];
157
+ $or?: QBFilterQuery<Entity, RootAlias, Context, RawAliases>[];
158
+ $not?: QBFilterQuery<Entity, RootAlias, Context, RawAliases>;
160
159
  };
161
160
  export type AliasedFilterCondition<RootAlias extends string, Context, Entity, RawAliases extends string = never> = (IsNever<RootAlias> extends true ? {} : string extends RootAlias ? {} : RootAliasFilterKeys<RootAlias, Entity>) & ([Context] extends [never] ? {} : ContextFilterKeys<Context>) & (IsNever<RawAliases> extends true ? {} : string extends RawAliases ? {} : RawFilterKeys<RawAliases>) & GroupOperators<RootAlias, Context, Entity, RawAliases>;
162
161
  export type QBFilterQuery<Entity, RootAlias extends string = never, Context = never, RawAliases extends string = never> = FilterObject<Entity> & AliasedFilterCondition<RootAlias, Context, Entity, RawAliases>;
@@ -440,7 +439,7 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
440
439
  */
441
440
  join<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(field: Field, alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, type?: JoinType, path?: string, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field> & {}, ModifyContext<Entity, Context, Field, Alias>, RawAliases, Fields, CTEs>;
442
441
  /**
443
- * Adds a JOIN clause to the query for a subquery.
442
+ * Adds a JOIN clause to the query for a subquery. Use `sql.ref('...')` to join a table or CTE by name.
444
443
  */
445
444
  join<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, type?: JoinType, path?: string, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, Fields, CTEs>;
446
445
  /**
@@ -448,7 +447,7 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
448
447
  */
449
448
  innerJoin<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(field: Field, alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field> & {}, ModifyContext<Entity, Context, Field, Alias>, RawAliases, Fields, CTEs>;
450
449
  /**
451
- * Adds an INNER JOIN clause to the query for a subquery.
450
+ * Adds an INNER JOIN clause to the query for a subquery. Use `sql.ref('...')` to join a table or CTE by name.
452
451
  */
453
452
  innerJoin<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, Fields, CTEs>;
454
453
  innerJoinLateral<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, Fields, CTEs>;
@@ -457,7 +456,7 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
457
456
  */
458
457
  leftJoin<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(field: Field, alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field> & {}, ModifyContext<Entity, Context, Field, Alias>, RawAliases, Fields, CTEs>;
459
458
  /**
460
- * Adds a LEFT JOIN clause to the query for a subquery.
459
+ * Adds a LEFT JOIN clause to the query for a subquery. Use `sql.ref('...')` to join a table or CTE by name.
461
460
  */
462
461
  leftJoin<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, Fields, CTEs>;
463
462
  leftJoinLateral<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, Fields, CTEs>;
@@ -1410,19 +1410,19 @@ export class QueryBuilder {
1410
1410
  prop.targetMeta = field.mainAlias.meta;
1411
1411
  field = field.getNativeQuery();
1412
1412
  }
1413
- if (isRaw(field)) {
1414
- field = this.platform.formatQuery(field.sql, field.params);
1415
- }
1416
1413
  const key = `${this.alias}.${prop.name}#${alias}`;
1417
- this.#state.joins[key] = {
1418
- prop,
1419
- alias,
1420
- type,
1421
- cond,
1422
- schema,
1423
- subquery: field.toString(),
1424
- ownerAlias: this.alias,
1425
- };
1414
+ const join = { prop, alias, type, cond, schema, ownerAlias: this.alias };
1415
+ // `sql.ref('...')` is a bare table/CTE reference, join it by name instead of wrapping it as a sub-query
1416
+ if (isRaw(field) && field.sql === '??' && field.params.length === 1) {
1417
+ join.table = String(field.params[0]);
1418
+ }
1419
+ else {
1420
+ if (isRaw(field)) {
1421
+ field = this.platform.formatQuery(field.sql, field.params);
1422
+ }
1423
+ join.subquery = field.toString();
1424
+ }
1425
+ this.#state.joins[key] = join;
1426
1426
  return { prop, key };
1427
1427
  }
1428
1428
  if (!subquery && type.includes('lateral')) {
@@ -14,6 +14,11 @@ export declare class QueryBuilderHelper {
14
14
  * Returns the main alias if not a TPT property or if the property belongs to the main entity.
15
15
  */
16
16
  getTPTAliasForProperty(propName: string, defaultAlias: string): string;
17
+ /**
18
+ * Replaces `ALIAS_REPLACEMENT` placeholders, resolving column-qualified ones via
19
+ * `getTPTAliasForProperty()` so TPT inherited columns map to their owning table.
20
+ */
21
+ replaceAliases(sql: string, alias?: string): string;
17
22
  mapper(field: string | Raw | RawQueryFragmentSymbol, type?: QueryType): string;
18
23
  mapper(field: string | Raw | RawQueryFragmentSymbol, type?: QueryType, value?: any, alias?: string | null, schema?: string): string;
19
24
  processData(data: Dictionary, convertCustomTypes: boolean, multi?: boolean): any;
@@ -1,5 +1,7 @@
1
1
  import { ALIAS_REPLACEMENT, ALIAS_REPLACEMENT_RE, ArrayType, JsonType, inspect, isRaw, LockMode, OptimisticLockError, QueryOperator, QueryOrderNumeric, raw, Raw, QueryHelper, ReferenceKind, Utils, ValidationError, } from '@mikro-orm/core';
2
2
  import { EMBEDDABLE_ARRAY_OPS, JoinType, QueryType } from './enums.js';
3
+ /** Captures the column name that follows the alias placeholder. */
4
+ const QUALIFYING_ALIAS_RE = new RegExp(ALIAS_REPLACEMENT_RE + '(?=["\'`\\]]*\\.["\'`\\[]?([\\w$]+))', 'g');
3
5
  /**
4
6
  * @internal
5
7
  */
@@ -49,6 +51,15 @@ export class QueryBuilderHelper {
49
51
  // Property not found in hierarchy, return default alias
50
52
  return defaultAlias;
51
53
  }
54
+ /**
55
+ * Replaces `ALIAS_REPLACEMENT` placeholders, resolving column-qualified ones via
56
+ * `getTPTAliasForProperty()` so TPT inherited columns map to their owning table.
57
+ */
58
+ replaceAliases(sql, alias = this.#alias) {
59
+ return sql
60
+ .replace(QUALIFYING_ALIAS_RE, (_, column) => this.getTPTAliasForProperty(column, alias))
61
+ .replaceAll(ALIAS_REPLACEMENT, alias);
62
+ }
52
63
  mapper(field, type = QueryType.SELECT, value, alias, schema) {
53
64
  if (isRaw(field)) {
54
65
  return raw(field.sql, field.params);
@@ -97,7 +108,6 @@ export class QueryBuilderHelper {
97
108
  // Only apply TPT resolution when `a` is an actual table alias (in aliasMap),
98
109
  // not when it's an embedded property name like 'profile1.identity.links'
99
110
  const isTableAlias = !!this.#aliasMap[a];
100
- const baseAlias = isTableAlias ? a : this.#alias;
101
111
  const resolvedAlias = isTableAlias ? this.getTPTAliasForProperty(prop?.name ?? f, a) : this.#alias;
102
112
  const aliasPrefix = isTableNameAliasRequired ? resolvedAlias + '.' : '';
103
113
  const fkIdx2 = prop?.fieldNames.findIndex(name => name === f) ?? -1;
@@ -249,7 +259,13 @@ export class QueryBuilderHelper {
249
259
  }[join.type] ?? join.type;
250
260
  const conditions = [];
251
261
  const params = [];
252
- schema = join.schema === '*' ? schema : (join.schema ?? schemaOverride);
262
+ if (join.prop.name === '__subquery__') {
263
+ // bare table/CTE references (`sql.ref()` joins) keep their literal name, only an explicit schema applies
264
+ schema = join.schema === '*' ? undefined : join.schema;
265
+ }
266
+ else {
267
+ schema = join.schema === '*' ? schema : (join.schema ?? schemaOverride);
268
+ }
253
269
  if (schema && schema !== this.#platform.getDefaultSchemaName()) {
254
270
  table = `${schema}.${table}`;
255
271
  }
@@ -465,7 +481,7 @@ export class QueryBuilderHelper {
465
481
  const op = cond[key] === null ? 'is' : '=';
466
482
  if (Raw.isKnownFragmentSymbol(key)) {
467
483
  const raw = Raw.getKnownFragment(key);
468
- const sql = raw.sql.replaceAll(ALIAS_REPLACEMENT, this.#alias);
484
+ const sql = this.replaceAliases(raw.sql);
469
485
  const value = Utils.asArray(cond[key]);
470
486
  params.push(...raw.params);
471
487
  if (value.length > 0) {
@@ -576,7 +592,7 @@ export class QueryBuilderHelper {
576
592
  if (opValueIsRaw || typeof opValue?.toRaw === 'function') {
577
593
  const query = opValueIsRaw ? opValue : opValue.toRaw();
578
594
  const mappedKey = this.mapper(key, type, query, null);
579
- let sql = query.sql.replaceAll(ALIAS_REPLACEMENT, this.#alias);
595
+ let sql = this.replaceAliases(query.sql);
580
596
  if (['$in', '$nin'].includes(op)) {
581
597
  sql = `(${sql})`;
582
598
  }
@@ -1030,8 +1030,12 @@ export class DatabaseTable {
1030
1030
  // mysql stores decimal defaults padded to scale (`0` → `0.00`); collapse to canonical numeric form
1031
1031
  // so the metadata-side (`0`) and introspection-side (`0.00`) snapshots agree
1032
1032
  let defaultValue = c.default ?? null;
1033
- if (defaultValue != null && c.mappedType instanceof DecimalType && Number.isFinite(+defaultValue)) {
1034
- defaultValue = this.#platform.formatDecimal(defaultValue, c.scale).toString();
1033
+ if (defaultValue != null && c.mappedType instanceof DecimalType) {
1034
+ // string defaults like `default: '0.00'` are quoted in metadata, so strip the quotes first
1035
+ const unquoted = defaultValue.replace(/^'(.*)'$/, '$1');
1036
+ if (Number.isFinite(+unquoted)) {
1037
+ defaultValue = this.#platform.formatDecimal(unquoted, c.scale).toString();
1038
+ }
1035
1039
  }
1036
1040
  const normalized = {
1037
1041
  name: c.name,
@@ -89,6 +89,7 @@ export declare class SchemaComparator {
89
89
  private diffViewExpression;
90
90
  private diffTrigger;
91
91
  parseJsonDefault(defaultValue?: string | null): Dictionary | string | null;
92
+ private parseDecimalDefault;
92
93
  hasSameDefaultValue(from: Column, to: Column): boolean;
93
94
  private mapColumnToProperty;
94
95
  private log;
@@ -993,6 +993,10 @@ export class SchemaComparator {
993
993
  const val = defaultValue.replace(/^(_\w+\\)?'(.*?)\\?'$/, '$2').replace(/^\(?'(.*?)'\)?$/, '$1');
994
994
  return parseJsonSafe(val);
995
995
  }
996
+ parseDecimalDefault(defaultValue) {
997
+ const value = +('' + defaultValue).replace(/^'(.+)'$/, '$1');
998
+ return Number.isFinite(value) ? value : null;
999
+ }
996
1000
  hasSameDefaultValue(from, to) {
997
1001
  if (from.default == null ||
998
1002
  from.default.toString().toLowerCase() === 'null' ||
@@ -1018,10 +1022,15 @@ export class SchemaComparator {
1018
1022
  const defaultValueTo = to.default.toLowerCase().replace('current_timestamp', 'now').replace(/\(\)$/, '');
1019
1023
  return defaultValueFrom === defaultValueTo;
1020
1024
  }
1021
- // mysql stores decimal defaults padded to scale (`0` → `0.00`); compare numerically so the
1022
- // entity-side raw literal and the introspected padded form don't churn the no-op migration
1023
- if (to.mappedType instanceof DecimalType && Number.isFinite(+from.default) && Number.isFinite(+to.default)) {
1024
- return (this.#platform.formatDecimal(from.default, to.scale) === this.#platform.formatDecimal(to.default, to.scale));
1025
+ // mysql pads decimal defaults to scale (`0` → `0.00`) and postgres reports them unquoted
1026
+ // while metadata keeps them quoted; compare numerically so neither churns a no-op migration
1027
+ if (to.mappedType instanceof DecimalType) {
1028
+ const defaultValueFrom = this.parseDecimalDefault(from.default);
1029
+ const defaultValueTo = this.parseDecimalDefault(to.default);
1030
+ if (defaultValueFrom != null && defaultValueTo != null) {
1031
+ return (this.#platform.formatDecimal(defaultValueFrom, to.scale) ===
1032
+ this.#platform.formatDecimal(defaultValueTo, to.scale));
1033
+ }
1025
1034
  }
1026
1035
  if (from.default && to.default) {
1027
1036
  return from.default.toString().toLowerCase() === to.default.toString().toLowerCase();
@@ -308,22 +308,6 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator {
308
308
  for (const newTable of Object.values(schemaDiff.newTables)) {
309
309
  this.append(ret, this.helper.createTable(newTable, true), true);
310
310
  }
311
- if (this.helper.supportsSchemaConstraints()) {
312
- for (const newTable of Object.values(schemaDiff.newTables)) {
313
- const sql = [];
314
- if (this.options.createForeignKeyConstraints) {
315
- const fks = Object.values(newTable.getForeignKeys()).map(fk => this.helper.createForeignKey(newTable, fk));
316
- this.append(sql, fks);
317
- }
318
- for (const check of newTable.getChecks()) {
319
- this.append(sql, this.helper.createCheck(newTable, check));
320
- }
321
- for (const trigger of newTable.getTriggers()) {
322
- this.append(sql, this.helper.createTrigger(newTable, trigger));
323
- }
324
- this.append(ret, sql, true);
325
- }
326
- }
327
311
  if (options.dropTables && !options.safe) {
328
312
  for (const table of Object.values(schemaDiff.removedTables)) {
329
313
  // Drop triggers before the table so driver-specific cleanup runs (e.g. PostgreSQL function removal)
@@ -353,6 +337,23 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator {
353
337
  for (const changedTable of alteredTables) {
354
338
  this.append(ret, this.helper.getPostAlterTable(changedTable, options.safe), true);
355
339
  }
340
+ // after the alters, so a new table's FK can reference a unique constraint an existing table gains in the same diff
341
+ if (this.helper.supportsSchemaConstraints()) {
342
+ for (const newTable of Object.values(schemaDiff.newTables)) {
343
+ const sql = [];
344
+ if (this.options.createForeignKeyConstraints) {
345
+ const fks = Object.values(newTable.getForeignKeys()).map(fk => this.helper.createForeignKey(newTable, fk));
346
+ this.append(sql, fks);
347
+ }
348
+ for (const check of newTable.getChecks()) {
349
+ this.append(sql, this.helper.createCheck(newTable, check));
350
+ }
351
+ for (const trigger of newTable.getTriggers()) {
352
+ this.append(sql, this.helper.createTrigger(newTable, trigger));
353
+ }
354
+ this.append(ret, sql, true);
355
+ }
356
+ }
356
357
  if (!options.safe && this.platform.supportsNativeEnums()) {
357
358
  for (const removedNativeEnum of schemaDiff.removedNativeEnums) {
358
359
  this.append(ret, this.helper.getDropNativeEnumSQL(removedNativeEnum.name, removedNativeEnum.schema));
package/typings.d.ts CHANGED
@@ -277,6 +277,8 @@ export interface IQueryBuilder<T> {
277
277
  with(name: string, query: AnyQueryBuilder | NativeQueryBuilder | RawQueryFragment, options?: CteOptions): this;
278
278
  withRecursive(name: string, query: AnyQueryBuilder | NativeQueryBuilder | RawQueryFragment, options?: CteOptions): this;
279
279
  scheduleFilterCheck(path: string): void;
280
+ /** @internal */
281
+ ensureTPTJoins(): void;
280
282
  withSchema(schema: string): this;
281
283
  }
282
284
  export interface ICriteriaNodeProcessOptions {