@mikro-orm/sql 7.0.0-dev.296 → 7.0.0-dev.299

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.
@@ -1,7 +1,7 @@
1
1
  import { type AnyEntity, type Collection, type Configuration, type ConnectionType, type Constructor, type CountOptions, DatabaseDriver, type DeleteOptions, type Dictionary, type DriverMethodOptions, type EntityData, type EntityDictionary, type EntityField, EntityManagerType, type EntityMetadata, type EntityName, type EntityProperty, type FilterQuery, type FindOneOptions, type FindOptions, type FormulaTable, type LockOptions, type LoggingOptions, type NativeInsertUpdateManyOptions, type NativeInsertUpdateOptions, type ObjectQuery, type Options, type OrderDefinition, type PopulateOptions, type PopulatePath, type Primary, type QueryOrderMap, type QueryResult, type Raw, RawQueryFragment, type StreamOptions, type Transaction, type UpsertManyOptions, type UpsertOptions } from '@mikro-orm/core';
2
2
  import type { AbstractSqlConnection } from './AbstractSqlConnection.js';
3
3
  import type { AbstractSqlPlatform } from './AbstractSqlPlatform.js';
4
- import { QueryBuilder } from './query/QueryBuilder.js';
4
+ import { type AnyQueryBuilder } from './query/QueryBuilder.js';
5
5
  import { type NativeQueryBuilder } from './query/NativeQueryBuilder.js';
6
6
  import { QueryType } from './query/enums.js';
7
7
  import { SqlEntityManager } from './SqlEntityManager.js';
@@ -36,7 +36,7 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
36
36
  * Force balanced strategy to load to-many relations via separate queries.
37
37
  */
38
38
  private forceBalancedStrategy;
39
- mapResult<T extends object>(result: EntityData<T>, meta: EntityMetadata<T>, populate?: PopulateOptions<T>[], qb?: QueryBuilder<T, any, any, any>, map?: Dictionary): EntityData<T> | null;
39
+ mapResult<T extends object>(result: EntityData<T>, meta: EntityMetadata<T>, populate?: PopulateOptions<T>[], qb?: AnyQueryBuilder<T>, map?: Dictionary): EntityData<T> | null;
40
40
  /**
41
41
  * Maps aliased columns from TPT parent tables back to their original field names.
42
42
  * TPT parent columns are selected with aliases like `parent_alias__column_name`,
@@ -99,17 +99,17 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
99
99
  */
100
100
  mergeJoinedResult<T extends object>(rawResults: EntityData<T>[], meta: EntityMetadata<T>, joinedProps: PopulateOptions<T>[]): EntityData<T>[];
101
101
  protected shouldHaveColumn<T, U>(meta: EntityMetadata<T>, prop: EntityProperty<U>, populate: readonly PopulateOptions<U>[], fields?: readonly InternalField<U>[], exclude?: readonly InternalField<U>[]): boolean;
102
- protected getFieldsForJoinedLoad<T extends object>(qb: QueryBuilder<T, any, any, any>, meta: EntityMetadata<T>, options: FieldsForJoinedLoadOptions<T>): InternalField<T>[];
102
+ protected getFieldsForJoinedLoad<T extends object>(qb: AnyQueryBuilder<T>, meta: EntityMetadata<T>, options: FieldsForJoinedLoadOptions<T>): InternalField<T>[];
103
103
  /**
104
104
  * Adds LEFT JOINs and fields for TPT polymorphic loading when populating a relation to a TPT base class.
105
105
  * @internal
106
106
  */
107
- protected addTPTPolymorphicJoinsForRelation<T extends object>(qb: QueryBuilder<T, any, any, any>, meta: EntityMetadata<T>, baseAlias: string, fields: InternalField<T>[]): void;
107
+ protected addTPTPolymorphicJoinsForRelation<T extends object>(qb: AnyQueryBuilder<T>, meta: EntityMetadata<T>, baseAlias: string, fields: InternalField<T>[]): void;
108
108
  /**
109
109
  * Find the alias for a TPT child table in the query builder.
110
110
  * @internal
111
111
  */
112
- protected findTPTChildAlias<T extends object>(qb: QueryBuilder<T, any, any, any>, childMeta: EntityMetadata): string | undefined;
112
+ protected findTPTChildAlias<T extends object>(qb: AnyQueryBuilder<T>, childMeta: EntityMetadata): string | undefined;
113
113
  /**
114
114
  * Builds a CASE WHEN expression for TPT discriminator.
115
115
  * Determines concrete entity type based on which child table has a non-null PK.
@@ -122,13 +122,13 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
122
122
  * This method reads the discriminator to determine the concrete type and maps child-specific fields.
123
123
  * @internal
124
124
  */
125
- protected mapTPTChildFields<T extends object>(relationPojo: EntityData<T>, meta: EntityMetadata<T>, relationAlias: string, qb: QueryBuilder<T, any, any, any>, root: EntityData<T>): void;
125
+ protected mapTPTChildFields<T extends object>(relationPojo: EntityData<T>, meta: EntityMetadata<T>, relationAlias: string, qb: AnyQueryBuilder<T>, root: EntityData<T>): void;
126
126
  /**
127
127
  * @internal
128
128
  */
129
- mapPropToFieldNames<T extends object>(qb: QueryBuilder<T, any, any, any, any, any>, prop: EntityProperty<T>, tableAlias: string, meta: EntityMetadata<T>, schema?: string, explicitFields?: readonly InternalField<T>[]): InternalField<T>[];
129
+ mapPropToFieldNames<T extends object>(qb: AnyQueryBuilder<T>, prop: EntityProperty<T>, tableAlias: string, meta: EntityMetadata<T>, schema?: string, explicitFields?: readonly InternalField<T>[]): InternalField<T>[];
130
130
  /** @internal */
131
- createQueryBuilder<T extends object>(entityName: EntityName<T> | QueryBuilder<T, any, any, any>, ctx?: Transaction, preferredConnectionType?: ConnectionType, convertCustomTypes?: boolean, loggerContext?: LoggingOptions, alias?: string, em?: SqlEntityManager): QueryBuilder<T, any, any, any>;
131
+ createQueryBuilder<T extends object>(entityName: EntityName<T> | AnyQueryBuilder<T>, ctx?: Transaction, preferredConnectionType?: ConnectionType, convertCustomTypes?: boolean, loggerContext?: LoggingOptions, alias?: string, em?: SqlEntityManager): AnyQueryBuilder<T>;
132
132
  protected resolveConnectionType(args: {
133
133
  ctx?: Transaction;
134
134
  connectionType?: ConnectionType;
@@ -143,13 +143,13 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
143
143
  * Each branch is planned independently by the database, enabling per-table index usage.
144
144
  */
145
145
  protected applyUnionWhere<T extends object>(meta: EntityMetadata<T>, where: ObjectQuery<T>, options: FindOptions<T, any, any, any> | CountOptions<T> | NativeInsertUpdateOptions<T> | DeleteOptions<T>, forDml?: boolean): Promise<ObjectQuery<T>>;
146
- protected buildOrderBy<T extends object>(qb: QueryBuilder<T, any, any, any>, meta: EntityMetadata<T>, populate: PopulateOptions<T>[], options: Pick<FindOptions<any>, 'strategy' | 'orderBy' | 'populateOrderBy'>): QueryOrderMap<T>[];
147
- protected buildPopulateOrderBy<T extends object>(qb: QueryBuilder<T, any, any, any>, meta: EntityMetadata<T>, populateOrderBy: QueryOrderMap<T>[], parentPath: string, explicit: boolean, parentAlias?: string): QueryOrderMap<T>[];
148
- protected buildJoinedPropsOrderBy<T extends object>(qb: QueryBuilder<T, any, any, any>, meta: EntityMetadata<T>, populate: PopulateOptions<T>[], options?: Pick<FindOptions<any>, 'strategy' | 'orderBy' | 'populateOrderBy'>, parentPath?: string): QueryOrderMap<T>[];
146
+ protected buildOrderBy<T extends object>(qb: AnyQueryBuilder<T>, meta: EntityMetadata<T>, populate: PopulateOptions<T>[], options: Pick<FindOptions<any>, 'strategy' | 'orderBy' | 'populateOrderBy'>): QueryOrderMap<T>[];
147
+ protected buildPopulateOrderBy<T extends object>(qb: AnyQueryBuilder<T>, meta: EntityMetadata<T>, populateOrderBy: QueryOrderMap<T>[], parentPath: string, explicit: boolean, parentAlias?: string): QueryOrderMap<T>[];
148
+ protected buildJoinedPropsOrderBy<T extends object>(qb: AnyQueryBuilder<T>, meta: EntityMetadata<T>, populate: PopulateOptions<T>[], options?: Pick<FindOptions<any>, 'strategy' | 'orderBy' | 'populateOrderBy'>, parentPath?: string): QueryOrderMap<T>[];
149
149
  private buildToManyOrderBy;
150
150
  protected normalizeFields<T extends object>(fields: InternalField<T>[], prefix?: string): string[];
151
151
  protected processField<T extends object>(meta: EntityMetadata<T>, prop: EntityProperty<T> | undefined, field: string, ret: InternalField<T>[]): void;
152
- protected buildFields<T extends object>(meta: EntityMetadata<T>, populate: PopulateOptions<T>[], joinedProps: PopulateOptions<T>[], qb: QueryBuilder<T, any, any, any>, alias: string, options: Pick<FindOptions<T, any, any, any>, 'strategy' | 'fields' | 'exclude'>, schema?: string): InternalField<T>[];
152
+ protected buildFields<T extends object>(meta: EntityMetadata<T>, populate: PopulateOptions<T>[], joinedProps: PopulateOptions<T>[], qb: AnyQueryBuilder<T>, alias: string, options: Pick<FindOptions<T, any, any, any>, 'strategy' | 'fields' | 'exclude'>, schema?: string): InternalField<T>[];
153
153
  }
154
154
  interface FieldsForJoinedLoadOptions<T extends object> {
155
155
  explicitFields?: readonly InternalField<T>[];
@@ -20,7 +20,7 @@ export declare class SqlEntityManager<Driver extends AbstractSqlDriver = Abstrac
20
20
  /**
21
21
  * Shortcut for `createQueryBuilder()`
22
22
  */
23
- qb<Entity extends object, RootAlias extends string = never>(entityName: EntityName<Entity>, alias?: RootAlias, type?: ConnectionType, loggerContext?: LoggingOptions): QueryBuilder<Entity, RootAlias, never, never, never, "*">;
23
+ qb<Entity extends object, RootAlias extends string = never>(entityName: EntityName<Entity>, alias?: RootAlias, type?: ConnectionType, loggerContext?: LoggingOptions): QueryBuilder<Entity, RootAlias, never, never, never, "*", {}>;
24
24
  /**
25
25
  * Returns configured Kysely instance.
26
26
  */
@@ -11,4 +11,6 @@ export declare class MsSqlNativeQueryBuilder extends NativeQueryBuilder {
11
11
  protected compileSelect(): void;
12
12
  protected addLockClause(): void;
13
13
  protected compileTruncate(): void;
14
+ /** MSSQL has no RECURSIVE keyword — CTEs are implicitly recursive. */
15
+ protected getCteKeyword(_hasRecursive: boolean): string;
14
16
  }
@@ -19,6 +19,7 @@ export class MsSqlNativeQueryBuilder extends NativeQueryBuilder {
19
19
  if (this.options.comment) {
20
20
  this.parts.push(...this.options.comment.map(comment => `/* ${comment} */`));
21
21
  }
22
+ this.compileCtes();
22
23
  if (this.options.onConflict && !Utils.isEmpty(Utils.asArray(this.options.data)[0])) {
23
24
  this.compileUpsert();
24
25
  }
@@ -197,4 +198,8 @@ export class MsSqlNativeQueryBuilder extends NativeQueryBuilder {
197
198
  const sql = `delete from ${tableName}; declare @count int = case @@rowcount when 0 then 1 else 0 end; dbcc checkident ('${tableName.replace(/[[\]]/g, '')}', reseed, @count)`;
198
199
  this.parts.push(sql);
199
200
  }
201
+ /** MSSQL has no RECURSIVE keyword — CTEs are implicitly recursive. */
202
+ getCteKeyword(_hasRecursive) {
203
+ return 'with';
204
+ }
200
205
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/sql",
3
- "version": "7.0.0-dev.296",
3
+ "version": "7.0.0-dev.299",
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
  "type": "module",
6
6
  "exports": {
@@ -56,6 +56,6 @@
56
56
  "@mikro-orm/core": "^6.6.8"
57
57
  },
58
58
  "peerDependencies": {
59
- "@mikro-orm/core": "7.0.0-dev.296"
59
+ "@mikro-orm/core": "7.0.0-dev.299"
60
60
  }
61
61
  }
@@ -1,6 +1,17 @@
1
1
  import { type Dictionary, LockMode, type QueryFlag, RawQueryFragment, type Subquery } from '@mikro-orm/core';
2
2
  import { QueryType } from './enums.js';
3
3
  import type { AbstractSqlPlatform } from '../AbstractSqlPlatform.js';
4
+ export interface CteOptions {
5
+ columns?: string[];
6
+ /** PostgreSQL: MATERIALIZED / NOT MATERIALIZED */
7
+ materialized?: boolean;
8
+ }
9
+ interface CteClause extends CteOptions {
10
+ name: string;
11
+ sql: string;
12
+ params: unknown[];
13
+ recursive?: boolean;
14
+ }
4
15
  interface Options {
5
16
  tableName?: string | RawQueryFragment;
6
17
  indexHint?: string;
@@ -32,6 +43,7 @@ interface Options {
32
43
  hintComment?: string[];
33
44
  flags?: Set<QueryFlag>;
34
45
  wrap?: [prefix: string, suffix: string];
46
+ ctes?: CteClause[];
35
47
  }
36
48
  interface TableOptions {
37
49
  schema?: string;
@@ -65,6 +77,17 @@ export declare class NativeQueryBuilder implements Subquery {
65
77
  groupBy(groupBy: (string | RawQueryFragment)[]): this;
66
78
  join(sql: string, params: unknown[]): this;
67
79
  orderBy(orderBy: string): this;
80
+ /**
81
+ * The sub-query is compiled eagerly at call time — later mutations to the
82
+ * sub-query builder will not be reflected in this CTE.
83
+ */
84
+ with(name: string, query: NativeQueryBuilder | RawQueryFragment, options?: CteOptions): this;
85
+ /**
86
+ * Adds a recursive CTE (`WITH RECURSIVE` on PostgreSQL/MySQL/SQLite, plain `WITH` on MSSQL).
87
+ * The sub-query is compiled eagerly — later mutations will not be reflected.
88
+ */
89
+ withRecursive(name: string, query: NativeQueryBuilder | RawQueryFragment, options?: CteOptions): this;
90
+ private addCte;
68
91
  toString(): string;
69
92
  compile(): {
70
93
  sql: string;
@@ -103,6 +126,8 @@ export declare class NativeQueryBuilder implements Subquery {
103
126
  protected compileDelete(): void;
104
127
  protected compileTruncate(): void;
105
128
  protected addHintComment(): void;
129
+ protected compileCtes(): void;
130
+ protected getCteKeyword(hasRecursive: boolean): string;
106
131
  protected getTableName(): string;
107
132
  protected quote(id: string | RawQueryFragment | NativeQueryBuilder): string;
108
133
  }
@@ -59,6 +59,36 @@ export class NativeQueryBuilder {
59
59
  this.options.orderBy = orderBy;
60
60
  return this;
61
61
  }
62
+ /**
63
+ * The sub-query is compiled eagerly at call time — later mutations to the
64
+ * sub-query builder will not be reflected in this CTE.
65
+ */
66
+ with(name, query, options) {
67
+ return this.addCte(name, query, options);
68
+ }
69
+ /**
70
+ * Adds a recursive CTE (`WITH RECURSIVE` on PostgreSQL/MySQL/SQLite, plain `WITH` on MSSQL).
71
+ * The sub-query is compiled eagerly — later mutations will not be reflected.
72
+ */
73
+ withRecursive(name, query, options) {
74
+ return this.addCte(name, query, options, true);
75
+ }
76
+ addCte(name, query, options, recursive) {
77
+ this.options.ctes ??= [];
78
+ if (this.options.ctes.some(cte => cte.name === name)) {
79
+ throw new Error(`CTE with name '${name}' already exists`);
80
+ }
81
+ const { sql, params } = query instanceof NativeQueryBuilder ? query.compile() : { sql: query.sql, params: [...query.params] };
82
+ this.options.ctes.push({
83
+ name,
84
+ sql,
85
+ params,
86
+ recursive,
87
+ columns: options?.columns,
88
+ materialized: options?.materialized,
89
+ });
90
+ return this;
91
+ }
62
92
  toString() {
63
93
  const { sql, params } = this.compile();
64
94
  return this.platform.formatQuery(sql, params);
@@ -72,6 +102,7 @@ export class NativeQueryBuilder {
72
102
  if (this.options.comment) {
73
103
  this.parts.push(...this.options.comment.map(comment => `/* ${comment} */`));
74
104
  }
105
+ this.compileCtes();
75
106
  switch (this.type) {
76
107
  case QueryType.SELECT:
77
108
  case QueryType.COUNT:
@@ -387,6 +418,35 @@ export class NativeQueryBuilder {
387
418
  this.parts.push(`/*+ ${this.options.hintComment.join(' ')} */`);
388
419
  }
389
420
  }
421
+ compileCtes() {
422
+ const ctes = this.options.ctes;
423
+ if (!ctes || ctes.length === 0) {
424
+ return;
425
+ }
426
+ const hasRecursive = ctes.some(cte => cte.recursive);
427
+ const keyword = this.getCteKeyword(hasRecursive);
428
+ const cteParts = [];
429
+ for (const cte of ctes) {
430
+ let part = this.quote(cte.name);
431
+ if (cte.columns?.length) {
432
+ part += ` (${cte.columns.map(c => this.quote(c)).join(', ')})`;
433
+ }
434
+ part += ' as';
435
+ if (cte.materialized === true) {
436
+ part += ' materialized';
437
+ }
438
+ else if (cte.materialized === false) {
439
+ part += ' not materialized';
440
+ }
441
+ part += ` (${cte.sql})`;
442
+ this.params.push(...cte.params);
443
+ cteParts.push(part);
444
+ }
445
+ this.parts.push(`${keyword} ${cteParts.join(', ')}`);
446
+ }
447
+ getCteKeyword(hasRecursive) {
448
+ return hasRecursive ? 'with recursive' : 'with';
449
+ }
390
450
  getTableName() {
391
451
  if (!this.options.tableName) {
392
452
  throw new Error('No table name provided');
@@ -1,11 +1,11 @@
1
- import { type AnyEntity, type AutoPath, type Collection, type ConnectionType, type Dictionary, type EntityData, type EntityDTOFlat, type EntityDTOProp, type EntityKey, type EntityManager, type EntityMetadata, type EntityName, type EntityProperty, type ExpandProperty, type FilterObject, type FilterOptions, type FilterValue, type FlushMode, type GroupOperator, type Loaded, LockMode, type LoggingOptions, type MetadataStorage, type PrimaryProperty, type ObjectQuery, PopulateHint, type PopulateOptions, type PopulatePath, QueryFlag, type QueryOrderKeysFlat, type QueryOrderMap, type QueryResult, RawQueryFragment, type Raw, type RequiredEntityData, type Scalar, type SerializeDTO, type Subquery, type Transaction } from '@mikro-orm/core';
1
+ import { type AnyEntity, type AutoPath, type Collection, type ConnectionType, type Dictionary, type EntityData, type EntityDTOFlat, type EntityDTOProp, type EntityKey, type EntityManager, EntityMetadata, type EntityName, type EntityProperty, type ExpandProperty, type FilterObject, type FilterOptions, type FilterValue, type FlushMode, type GroupOperator, type Loaded, LockMode, type LoggingOptions, type MetadataStorage, type PrimaryProperty, type ObjectQuery, PopulateHint, type PopulateOptions, type PopulatePath, QueryFlag, type QueryOrderKeysFlat, type QueryOrderMap, type QueryResult, RawQueryFragment, type Raw, type RequiredEntityData, type Scalar, type SerializeDTO, type Subquery, type Transaction } from '@mikro-orm/core';
2
2
  import { JoinType, QueryType } from './enums.js';
3
3
  import type { AbstractSqlDriver } from '../AbstractSqlDriver.js';
4
4
  import { type Alias, type OnConflictClause, QueryBuilderHelper } from './QueryBuilderHelper.js';
5
5
  import type { SqlEntityManager } from '../SqlEntityManager.js';
6
6
  import type { ICriteriaNodeProcessOptions, InternalField, JoinOptions } from '../typings.js';
7
7
  import type { AbstractSqlPlatform } from '../AbstractSqlPlatform.js';
8
- import { NativeQueryBuilder } from './NativeQueryBuilder.js';
8
+ import { type CteOptions, NativeQueryBuilder } from './NativeQueryBuilder.js';
9
9
  export interface ExecuteOptions {
10
10
  mapResults?: boolean;
11
11
  mergeResults?: boolean;
@@ -158,7 +158,7 @@ export type QBFilterQuery<Entity, RootAlias extends string = never, Context = ne
158
158
  * const publisher = await qb.getSingleResult();
159
159
  * ```
160
160
  */
161
- export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias extends string = never, Hint extends string = never, Context extends object = never, RawAliases extends string = never, Fields extends string = '*'> implements Subquery {
161
+ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias extends string = never, Hint extends string = never, Context extends object = never, RawAliases extends string = never, Fields extends string = '*', CTEs extends Record<string, object> = {}> implements Subquery {
162
162
  protected readonly metadata: MetadataStorage;
163
163
  protected readonly driver: AbstractSqlDriver;
164
164
  protected readonly context?: Transaction | undefined;
@@ -224,6 +224,11 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
224
224
  sql: string;
225
225
  params: readonly unknown[];
226
226
  };
227
+ protected _ctes: (CteOptions & {
228
+ name: string;
229
+ query: NativeQueryBuilder | RawQueryFragment;
230
+ recursive?: boolean;
231
+ })[];
227
232
  protected readonly platform: AbstractSqlPlatform;
228
233
  private tptJoinsApplied;
229
234
  private readonly autoJoinedPaths;
@@ -251,7 +256,7 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
251
256
  * qb.select('*', true);
252
257
  * ```
253
258
  */
254
- select<const F extends readonly Field<Entity, RootAlias, Context>[]>(fields: F, distinct?: boolean): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases | ExtractRawAliases<F>, ExtractRootFields<F[number] & string, RootAlias, Context>>;
259
+ select<const F extends readonly Field<Entity, RootAlias, Context>[]>(fields: F, distinct?: boolean): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases | ExtractRawAliases<F>, ExtractRootFields<F[number] & string, RootAlias, Context>, CTEs>;
255
260
  /**
256
261
  * Creates a SELECT query, specifying the fields to retrieve.
257
262
  *
@@ -268,7 +273,7 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
268
273
  * qb.select('*', true);
269
274
  * ```
270
275
  */
271
- select<const P extends string>(fields: readonly NestedAutoPath<Entity, RootAlias, Context, P>[], distinct?: boolean): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, ExtractRootFields<P, RootAlias, Context>>;
276
+ select<const P extends string>(fields: readonly NestedAutoPath<Entity, RootAlias, Context, P>[], distinct?: boolean): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, ExtractRootFields<P, RootAlias, Context>, CTEs>;
272
277
  /**
273
278
  * Creates a SELECT query, specifying the fields to retrieve.
274
279
  *
@@ -279,7 +284,7 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
279
284
  * qb.select('address.city');
280
285
  * ```
281
286
  */
282
- select<const P extends string>(fields: NestedAutoPath<Entity, RootAlias, Context, P>, distinct?: boolean): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, ExtractRootFields<P, RootAlias, Context>>;
287
+ select<const P extends string>(fields: NestedAutoPath<Entity, RootAlias, Context, P>, distinct?: boolean): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, ExtractRootFields<P, RootAlias, Context>, CTEs>;
283
288
  /**
284
289
  * Creates a SELECT query, specifying the fields to retrieve.
285
290
  *
@@ -296,16 +301,16 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
296
301
  * qb.select('*', true);
297
302
  * ```
298
303
  */
299
- select<const F extends Field<Entity, RootAlias, Context>>(fields: F, distinct?: boolean): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases | ExtractRawAliases<readonly [F]>, ExtractRootFields<F & string, RootAlias, Context>>;
304
+ select<const F extends Field<Entity, RootAlias, Context>>(fields: F, distinct?: boolean): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases | ExtractRawAliases<readonly [F]>, ExtractRootFields<F & string, RootAlias, Context>, CTEs>;
300
305
  /**
301
306
  * Adds fields to an existing SELECT query.
302
307
  */
303
- addSelect<const F extends Field<Entity, RootAlias, Context> | readonly Field<Entity, RootAlias, Context>[]>(fields: F): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases | ExtractRawAliases<F extends readonly unknown[] ? F : [F]>, Fields | ExtractRootFields<F extends readonly (infer U)[] ? U & string : F & string, RootAlias, Context>>;
304
- distinct(): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields>;
308
+ addSelect<const F extends Field<Entity, RootAlias, Context> | readonly Field<Entity, RootAlias, Context>[]>(fields: F): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases | ExtractRawAliases<F extends readonly unknown[] ? F : [F]>, Fields | ExtractRootFields<F extends readonly (infer U)[] ? U & string : F & string, RootAlias, Context>, CTEs>;
309
+ distinct(): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
305
310
  /** postgres only */
306
- distinctOn<const F extends readonly Field<Entity, RootAlias, Context>[]>(fields: F): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields>;
311
+ distinctOn<const F extends readonly Field<Entity, RootAlias, Context>[]>(fields: F): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
307
312
  /** postgres only */
308
- distinctOn<F extends Field<Entity, RootAlias, Context>>(fields: F): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields>;
313
+ distinctOn<F extends Field<Entity, RootAlias, Context>>(fields: F): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
309
314
  /**
310
315
  * Creates an INSERT query with the given data.
311
316
  *
@@ -380,29 +385,29 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
380
385
  * .where({ 'a.name': 'John' });
381
386
  * ```
382
387
  */
383
- 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>;
388
+ 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, '*', CTEs>;
384
389
  /**
385
390
  * Adds a JOIN clause to the query for a subquery.
386
391
  */
387
- 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>;
392
+ 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, '*', CTEs>;
388
393
  /**
389
394
  * Adds an INNER JOIN clause to the query for an entity relation.
390
395
  */
391
- 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>;
396
+ 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, '*', CTEs>;
392
397
  /**
393
398
  * Adds an INNER JOIN clause to the query for a subquery.
394
399
  */
395
- innerJoin<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases>;
396
- innerJoinLateral<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases>;
400
+ innerJoin<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, '*', CTEs>;
401
+ innerJoinLateral<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, '*', CTEs>;
397
402
  /**
398
403
  * Adds a LEFT JOIN clause to the query for an entity relation.
399
404
  */
400
- 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>;
405
+ 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, '*', CTEs>;
401
406
  /**
402
407
  * Adds a LEFT JOIN clause to the query for a subquery.
403
408
  */
404
- leftJoin<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases>;
405
- leftJoinLateral<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases>;
409
+ leftJoin<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, '*', CTEs>;
410
+ leftJoinLateral<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, '*', CTEs>;
406
411
  /**
407
412
  * Adds a JOIN clause and automatically selects the joined entity's fields.
408
413
  * This is useful for eager loading related entities.
@@ -415,11 +420,11 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
415
420
  * .where({ 'a.name': 'John' });
416
421
  * ```
417
422
  */
418
- joinAndSelect<Field extends QBField<Entity, RootAlias, Context>, Alias extends string, const JoinFields extends readonly [JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>, ...JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>[]] | undefined = undefined>(field: Field | [Field, RawQueryFragment | QueryBuilder<any>], alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, type?: JoinType, path?: string, fields?: JoinFields, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field, true> & {}, ModifyContext<Entity, Context, Field, Alias, true>, RawAliases, ModifyFields<Fields, RootAlias, Context, Field, Alias, JoinFields>>;
419
- leftJoinAndSelect<Field extends QBField<Entity, RootAlias, Context>, Alias extends string, const JoinFields extends readonly [JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>, ...JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>[]] | undefined = undefined>(field: Field | [Field, RawQueryFragment | QueryBuilder<any>], alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, fields?: JoinFields, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field, true> & {}, ModifyContext<Entity, Context, Field, Alias, true>, RawAliases, ModifyFields<Fields, RootAlias, Context, Field, Alias, JoinFields>>;
420
- leftJoinLateralAndSelect<Field extends QBField<Entity, RootAlias, Context>, Alias extends string, const JoinFields extends readonly [JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>, ...JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>[]] | undefined = undefined>(field: [Field, RawQueryFragment | QueryBuilder<any>], alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, fields?: JoinFields, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field, true> & {}, ModifyContext<Entity, Context, Field, Alias, true>, RawAliases, ModifyFields<Fields, RootAlias, Context, Field, Alias, JoinFields>>;
421
- innerJoinAndSelect<Field extends QBField<Entity, RootAlias, Context>, Alias extends string, const JoinFields extends readonly [JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>, ...JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>[]] | undefined = undefined>(field: Field | [Field, RawQueryFragment | QueryBuilder<any>], alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, fields?: JoinFields, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field, true> & {}, ModifyContext<Entity, Context, Field, Alias, true>, RawAliases, ModifyFields<Fields, RootAlias, Context, Field, Alias, JoinFields>>;
422
- innerJoinLateralAndSelect<Field extends QBField<Entity, RootAlias, Context>, Alias extends string, const JoinFields extends readonly [JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>, ...JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>[]] | undefined = undefined>(field: [Field, RawQueryFragment | QueryBuilder<any>], alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, fields?: JoinFields, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field, true> & {}, ModifyContext<Entity, Context, Field, Alias, true>, RawAliases, ModifyFields<Fields, RootAlias, Context, Field, Alias, JoinFields>>;
423
+ joinAndSelect<Field extends QBField<Entity, RootAlias, Context>, Alias extends string, const JoinFields extends readonly [JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>, ...JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>[]] | undefined = undefined>(field: Field | [Field, RawQueryFragment | QueryBuilder<any>], alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, type?: JoinType, path?: string, fields?: JoinFields, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field, true> & {}, ModifyContext<Entity, Context, Field, Alias, true>, RawAliases, ModifyFields<Fields, RootAlias, Context, Field, Alias, JoinFields>, CTEs>;
424
+ leftJoinAndSelect<Field extends QBField<Entity, RootAlias, Context>, Alias extends string, const JoinFields extends readonly [JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>, ...JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>[]] | undefined = undefined>(field: Field | [Field, RawQueryFragment | QueryBuilder<any>], alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, fields?: JoinFields, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field, true> & {}, ModifyContext<Entity, Context, Field, Alias, true>, RawAliases, ModifyFields<Fields, RootAlias, Context, Field, Alias, JoinFields>, CTEs>;
425
+ leftJoinLateralAndSelect<Field extends QBField<Entity, RootAlias, Context>, Alias extends string, const JoinFields extends readonly [JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>, ...JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>[]] | undefined = undefined>(field: [Field, RawQueryFragment | QueryBuilder<any>], alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, fields?: JoinFields, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field, true> & {}, ModifyContext<Entity, Context, Field, Alias, true>, RawAliases, ModifyFields<Fields, RootAlias, Context, Field, Alias, JoinFields>, CTEs>;
426
+ innerJoinAndSelect<Field extends QBField<Entity, RootAlias, Context>, Alias extends string, const JoinFields extends readonly [JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>, ...JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>[]] | undefined = undefined>(field: Field | [Field, RawQueryFragment | QueryBuilder<any>], alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, fields?: JoinFields, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field, true> & {}, ModifyContext<Entity, Context, Field, Alias, true>, RawAliases, ModifyFields<Fields, RootAlias, Context, Field, Alias, JoinFields>, CTEs>;
427
+ innerJoinLateralAndSelect<Field extends QBField<Entity, RootAlias, Context>, Alias extends string, const JoinFields extends readonly [JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>, ...JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>[]] | undefined = undefined>(field: [Field, RawQueryFragment | QueryBuilder<any>], alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, fields?: JoinFields, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field, true> & {}, ModifyContext<Entity, Context, Field, Alias, true>, RawAliases, ModifyFields<Fields, RootAlias, Context, Field, Alias, JoinFields>, CTEs>;
423
428
  protected getFieldsForJoinedLoad(prop: EntityProperty<Entity>, alias: string, explicitFields?: readonly string[]): InternalField<Entity>[];
424
429
  /**
425
430
  * Apply filters to the QB where condition.
@@ -522,7 +527,7 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
522
527
  * qb.orderBy({ 'profile.bio': 'asc' }); // nested via dot notation
523
528
  * ```
524
529
  */
525
- orderBy(orderBy: ContextOrderByMap<Entity, RootAlias, Context, RawAliases> | ContextOrderByMap<Entity, RootAlias, Context, RawAliases>[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields>;
530
+ orderBy(orderBy: ContextOrderByMap<Entity, RootAlias, Context, RawAliases> | ContextOrderByMap<Entity, RootAlias, Context, RawAliases>[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
526
531
  /**
527
532
  * Adds an ORDER BY clause to the query, replacing any existing order.
528
533
  *
@@ -536,17 +541,17 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
536
541
  */
537
542
  orderBy<const T extends Record<string, QueryOrderKeysFlat>>(orderBy: T & {
538
543
  [K in keyof T]: K extends NestedAutoPath<Entity, RootAlias, Context, K & string> ? T[K] : (K extends RawAliases ? T[K] : never);
539
- }): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields>;
544
+ }): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
540
545
  /**
541
546
  * Adds additional ORDER BY clause without replacing existing order.
542
547
  */
543
- andOrderBy(orderBy: ContextOrderByMap<Entity, RootAlias, Context, RawAliases> | ContextOrderByMap<Entity, RootAlias, Context, RawAliases>[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields>;
548
+ andOrderBy(orderBy: ContextOrderByMap<Entity, RootAlias, Context, RawAliases> | ContextOrderByMap<Entity, RootAlias, Context, RawAliases>[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
544
549
  /**
545
550
  * Adds additional ORDER BY clause without replacing existing order.
546
551
  */
547
552
  andOrderBy<const T extends Record<string, QueryOrderKeysFlat>>(orderBy: T & {
548
553
  [K in keyof T]: K extends NestedAutoPath<Entity, RootAlias, Context, K & string> ? T[K] : (K extends RawAliases ? T[K] : never);
549
- }): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields>;
554
+ }): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
550
555
  private processOrderBy;
551
556
  /** Collect custom aliases from select fields (stored as 'resolved as alias' strings by select()). */
552
557
  private getSelectAliases;
@@ -559,7 +564,7 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
559
564
  * .groupBy('status');
560
565
  * ```
561
566
  */
562
- groupBy<const F extends readonly Field<Entity, RootAlias, Context>[]>(fields: F): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields>;
567
+ groupBy<const F extends readonly Field<Entity, RootAlias, Context>[]>(fields: F): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
563
568
  /**
564
569
  * Adds a GROUP BY clause to the query.
565
570
  *
@@ -569,7 +574,7 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
569
574
  * .groupBy('status');
570
575
  * ```
571
576
  */
572
- groupBy<F extends Field<Entity, RootAlias, Context>>(fields: F): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields>;
577
+ groupBy<F extends Field<Entity, RootAlias, Context>>(fields: F): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
573
578
  /**
574
579
  * Adds a GROUP BY clause to the query.
575
580
  *
@@ -579,7 +584,7 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
579
584
  * .groupBy('status');
580
585
  * ```
581
586
  */
582
- groupBy<const P extends string>(fields: NestedAutoPath<Entity, RootAlias, Context, P> | readonly NestedAutoPath<Entity, RootAlias, Context, P>[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields>;
587
+ groupBy<const P extends string>(fields: NestedAutoPath<Entity, RootAlias, Context, P> | readonly NestedAutoPath<Entity, RootAlias, Context, P>[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
583
588
  /**
584
589
  * Adds a HAVING clause to the query, typically used with GROUP BY.
585
590
  *
@@ -590,9 +595,9 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
590
595
  * .having({ count: { $gt: 5 } });
591
596
  * ```
592
597
  */
593
- having(cond?: QBFilterQuery<Entity, RootAlias, Context, RawAliases> | string, params?: any[], operator?: keyof typeof GroupOperator): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields>;
594
- andHaving(cond?: QBFilterQuery<Entity, RootAlias, Context, RawAliases> | string, params?: any[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields>;
595
- orHaving(cond?: QBFilterQuery<Entity, RootAlias, Context, RawAliases> | string, params?: any[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields>;
598
+ having(cond?: QBFilterQuery<Entity, RootAlias, Context, RawAliases> | string, params?: any[], operator?: keyof typeof GroupOperator): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
599
+ andHaving(cond?: QBFilterQuery<Entity, RootAlias, Context, RawAliases> | string, params?: any[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
600
+ orHaving(cond?: QBFilterQuery<Entity, RootAlias, Context, RawAliases> | string, params?: any[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
596
601
  onConflict<F extends Field<Entity, RootAlias, Context>>(fields?: F | F[] | RawQueryFragment): InsertQueryBuilder<Entity, RootAlias, Context>;
597
602
  ignore(): this;
598
603
  merge<const P extends string>(data: readonly NestedAutoPath<Entity, RootAlias, Context, P>[]): this;
@@ -611,7 +616,7 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
611
616
  * qb.select('*').limit(10, 20); // 10 results starting from offset 20
612
617
  * ```
613
618
  */
614
- limit(limit?: number, offset?: number): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields>;
619
+ limit(limit?: number, offset?: number): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
615
620
  /**
616
621
  * Sets an OFFSET clause to skip a number of results.
617
622
  *
@@ -620,7 +625,7 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
620
625
  * qb.select('*').limit(10).offset(20); // Results 21-30
621
626
  * ```
622
627
  */
623
- offset(offset?: number): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields>;
628
+ offset(offset?: number): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
624
629
  withSchema(schema?: string): this;
625
630
  setLockMode(mode?: LockMode, tables?: string[]): this;
626
631
  setFlushMode(flushMode?: FlushMode): this;
@@ -650,12 +655,17 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
650
655
  * Specifies FROM which entity's table select/update/delete will be executed, removing all previously set FROM-s.
651
656
  * Allows setting a main string alias of the selection data.
652
657
  */
653
- from<Entity extends object>(target: QueryBuilder<Entity>, aliasName?: string): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields>;
658
+ from<Entity extends object>(target: QueryBuilder<Entity>, aliasName?: string): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
654
659
  /**
655
660
  * Specifies FROM which entity's table select/update/delete will be executed, removing all previously set FROM-s.
656
661
  * Allows setting a main string alias of the selection data.
657
662
  */
658
- from<Entity extends object>(target: EntityName<Entity>): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields>;
663
+ from<Entity extends object>(target: EntityName<Entity>): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
664
+ /**
665
+ * Specifies a CTE name as the FROM source, with full type safety.
666
+ * The entity type is inferred from the CTE definition passed to `.with()`.
667
+ */
668
+ from<Name extends string & keyof CTEs, Alias extends string = Name>(target: Name, aliasName?: Alias): SelectQueryBuilder<CTEs[Name], Alias, never, never, never, '*', CTEs>;
659
669
  getNativeQuery(processVirtualEntity?: boolean): NativeQueryBuilder;
660
670
  /**
661
671
  * Returns the query with parameters as wildcards.
@@ -786,7 +796,48 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
786
796
  */
787
797
  union(...others: (QueryBuilder<any> | NativeQueryBuilder)[]): QueryBuilder<Entity>;
788
798
  private buildUnionQuery;
789
- clone(reset?: boolean | string[], preserve?: string[]): QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields>;
799
+ /**
800
+ * Adds a Common Table Expression (CTE) to the query.
801
+ * When a `QueryBuilder` is passed, its entity type is tracked for type-safe `from()`.
802
+ *
803
+ * @example
804
+ * ```ts
805
+ * const recentBooks = em.createQueryBuilder(Book, 'b').select('*').where({ ... });
806
+ * const qb = em.createQueryBuilder(Author, 'a')
807
+ * .with('recent_books', recentBooks)
808
+ * .select('*')
809
+ * .from('recent_books', 'rb'); // entity type inferred as Book
810
+ * ```
811
+ */
812
+ with<Name extends string, Q extends QueryBuilder<any>>(name: Name, query: Q, options?: CteOptions): QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs & Record<Name, Q extends QueryBuilder<infer T> ? T : object>>;
813
+ /**
814
+ * Adds a Common Table Expression (CTE) to the query using a `NativeQueryBuilder` or raw SQL fragment.
815
+ * The CTE name is tracked but without entity type inference — use `from()` to query from it.
816
+ */
817
+ with<Name extends string>(name: Name, query: NativeQueryBuilder | RawQueryFragment, options?: CteOptions): QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs & Record<Name, object>>;
818
+ /**
819
+ * Adds a recursive Common Table Expression (CTE) to the query.
820
+ * When a `QueryBuilder` is passed, its entity type is tracked for type-safe `from()`.
821
+ *
822
+ * @example
823
+ * ```ts
824
+ * const base = em.createQueryBuilder(Category).select('*').where({ parent: null });
825
+ * const rec = em.createQueryBuilder(Category, 'c').select('c.*')
826
+ * .leftJoin('c.parent', 'ct', { id: sql.ref('c.parentId') });
827
+ * const qb = em.createQueryBuilder(Category)
828
+ * .withRecursive('category_tree', base.unionAll(rec))
829
+ * .select('*')
830
+ * .from('category_tree', 'ct'); // entity type inferred as Category
831
+ * ```
832
+ */
833
+ withRecursive<Name extends string, Q extends QueryBuilder<any>>(name: Name, query: Q, options?: CteOptions): QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs & Record<Name, Q extends QueryBuilder<infer T> ? T : object>>;
834
+ /**
835
+ * Adds a recursive Common Table Expression (CTE) to the query using a `NativeQueryBuilder` or raw SQL fragment.
836
+ * The CTE name is tracked but without entity type inference — use `from()` to query from it.
837
+ */
838
+ withRecursive<Name extends string>(name: Name, query: NativeQueryBuilder | RawQueryFragment, options?: CteOptions): QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs & Record<Name, object>>;
839
+ private addCte;
840
+ clone(reset?: boolean | string[], preserve?: string[]): QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
790
841
  /**
791
842
  * Sets logger context for this query builder.
792
843
  */
@@ -876,6 +927,7 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
876
927
  private createMainAlias;
877
928
  private fromSubQuery;
878
929
  private fromEntityName;
930
+ private fromRawTable;
879
931
  private createQueryBuilderHelper;
880
932
  private ensureFromClause;
881
933
  private ensureNotFinalized;
@@ -910,7 +962,9 @@ type ExecuteDTO<T, H extends string, F extends string> = [
910
962
  } : true extends (H extends `${string}.${string}` ? true : false) ? EntityDTOFlat<Loaded<T, H, F>> : DirectDTO<T, (RootFields<F, H> | PrimaryProperty<T>) & keyof T> & {
911
963
  [K in H & keyof T]: JoinDTO<T, K, F>;
912
964
  };
913
- export interface SelectQueryBuilder<Entity extends object = AnyEntity, RootAlias extends string = never, Hint extends string = never, Context extends object = never, RawAliases extends string = never, Fields extends string = '*'> extends QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields> {
965
+ /** Shorthand for `QueryBuilder` with all generic parameters set to `any`. */
966
+ export type AnyQueryBuilder<T extends object = AnyEntity> = QueryBuilder<T, any, any, any, any, any, any>;
967
+ export interface SelectQueryBuilder<Entity extends object = AnyEntity, RootAlias extends string = never, Hint extends string = never, Context extends object = never, RawAliases extends string = never, Fields extends string = '*', CTEs extends Record<string, object> = {}> extends QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs> {
914
968
  execute<Result = ExecuteDTO<Entity, Hint, Fields>[]>(method?: 'all' | 'get' | 'run', mapResults?: boolean): Promise<Result>;
915
969
  execute<Result = ExecuteDTO<Entity, Hint, Fields>[]>(method: 'all', mapResults?: boolean): Promise<Result>;
916
970
  execute<Result = ExecuteDTO<Entity, Hint, Fields>>(method: 'get', mapResults?: boolean): Promise<Result>;