pqb 0.56.8 → 0.56.11

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.js CHANGED
@@ -1766,6 +1766,9 @@ const defaultSchemaConfig = {
1766
1766
  narrowType() {
1767
1767
  return this;
1768
1768
  },
1769
+ narrowAllTypes() {
1770
+ return this;
1771
+ },
1769
1772
  dateAsNumber() {
1770
1773
  return this.parse(Date.parse);
1771
1774
  },
@@ -2971,6 +2974,7 @@ const pushIn = (ctx, query, ands, quotedAs, arg) => {
2971
2974
  const processJoinItem = (ctx, table, query, args, quotedAs) => {
2972
2975
  let target;
2973
2976
  let on;
2977
+ const forbidLateral = "u" in args;
2974
2978
  if ("l" in args) {
2975
2979
  const { aliasValue } = ctx;
2976
2980
  ctx.aliasValue = true;
@@ -2991,7 +2995,7 @@ const processJoinItem = (ctx, table, query, args, quotedAs) => {
2991
2995
  target += ` ${joinAs}`;
2992
2996
  }
2993
2997
  if (r && s) {
2994
- target = `LATERAL ${subJoinToSql(ctx, j, quotedTable, joinAs, true)}`;
2998
+ target = subJoinToSql(ctx, j, quotedTable, !forbidLateral, joinAs, true);
2995
2999
  } else {
2996
3000
  on = whereToSql(ctx, j, j.q, joinAs);
2997
3001
  }
@@ -3001,7 +3005,7 @@ const processJoinItem = (ctx, table, query, args, quotedAs) => {
3001
3005
  if ("r" in args) {
3002
3006
  const { s, r } = args;
3003
3007
  if (s) {
3004
- target = `LATERAL ${subJoinToSql(ctx, r, target, target)}`;
3008
+ target = subJoinToSql(ctx, r, target, !forbidLateral, target);
3005
3009
  } else {
3006
3010
  on = whereToSql(ctx, r, r.q, target);
3007
3011
  }
@@ -3032,14 +3036,14 @@ const processJoinItem = (ctx, table, query, args, quotedAs) => {
3032
3036
  let joinAs;
3033
3037
  if ("r" in args) {
3034
3038
  const { r } = args;
3035
- const res = getArgQueryTarget(ctx, q, s, s);
3036
- target = s ? `LATERAL ${res.target}` : res.target;
3039
+ const res = getArgQueryTarget(ctx, q, s && !forbidLateral, s, s);
3040
+ target = res.target;
3037
3041
  joinAs = res.joinAs;
3038
- if (!s) {
3042
+ if (!s || forbidLateral) {
3039
3043
  on = whereToSql(ctx, r, r.q, `"${getQueryAs(r)}"`);
3040
3044
  }
3041
3045
  } else {
3042
- const res = getArgQueryTarget(ctx, q, s);
3046
+ const res = getArgQueryTarget(ctx, q, false, s);
3043
3047
  target = res.target;
3044
3048
  joinAs = res.joinAs;
3045
3049
  if ("a" in args) {
@@ -3068,7 +3072,7 @@ const processJoinItem = (ctx, table, query, args, quotedAs) => {
3068
3072
  }
3069
3073
  return { target, on };
3070
3074
  };
3071
- const getArgQueryTarget = (ctx, first, joinSubQuery, cloned) => {
3075
+ const getArgQueryTarget = (ctx, first, lateral, joinSubQuery, cloned) => {
3072
3076
  const joinQuery = first.q;
3073
3077
  const quotedFrom = typeof joinQuery.from === "string" ? `"${joinQuery.from}"` : void 0;
3074
3078
  let joinAs = quotedFrom || `"${first.table}"`;
@@ -3076,7 +3080,7 @@ const getArgQueryTarget = (ctx, first, joinSubQuery, cloned) => {
3076
3080
  const addAs = qAs && qAs !== joinAs;
3077
3081
  if (joinSubQuery) {
3078
3082
  return {
3079
- target: subJoinToSql(ctx, first, joinAs, qAs, cloned),
3083
+ target: subJoinToSql(ctx, first, joinAs, lateral, qAs, cloned),
3080
3084
  joinAs: addAs ? qAs : joinAs
3081
3085
  };
3082
3086
  } else {
@@ -3088,12 +3092,13 @@ const getArgQueryTarget = (ctx, first, joinSubQuery, cloned) => {
3088
3092
  return { target, joinAs };
3089
3093
  }
3090
3094
  };
3091
- const subJoinToSql = (ctx, jq, innerAs, outerAs, cloned) => {
3095
+ const subJoinToSql = (ctx, jq, innerAs, lateral, outerAs, cloned) => {
3092
3096
  if (!jq.q.select && jq.q.selectAllColumns) {
3093
3097
  if (!cloned) jq = jq.clone();
3094
3098
  jq.q.select = [new RawSQL(`${innerAs}.*`)];
3095
3099
  }
3096
- return `(${getSqlText(jq.toSQL(ctx))}) ${outerAs || innerAs}`;
3100
+ const sql = `(${getSqlText(jq.toSQL(ctx))}) ${outerAs || innerAs}`;
3101
+ return lateral ? `LATERAL ${sql}` : sql;
3097
3102
  };
3098
3103
  const processArgs = (args, ctx, query, joinAs, joinShape, quotedAs) => {
3099
3104
  return args.length ? args.length === 1 ? getObjectOrRawConditions(
@@ -3177,7 +3182,26 @@ const skipQueryKeysForSubQuery = {
3177
3182
  returnsOne: true,
3178
3183
  aliases: true,
3179
3184
  defaults: true,
3180
- transform: true
3185
+ transform: true,
3186
+ throwOnNotFound: true,
3187
+ before: true,
3188
+ after: true,
3189
+ beforeCreate: true,
3190
+ afterCreate: true,
3191
+ afterCreateCommit: true,
3192
+ afterCreateSelect: true,
3193
+ beforeUpdate: true,
3194
+ afterUpdate: true,
3195
+ afterUpdateCommit: true,
3196
+ afterUpdateSelect: true,
3197
+ beforeDelete: true,
3198
+ afterDelete: true,
3199
+ afterDeleteCommit: true,
3200
+ afterDeleteSelect: true,
3201
+ catchAfterCommitErrors: true,
3202
+ log: true,
3203
+ logger: true,
3204
+ autoPreparedStatements: true
3181
3205
  };
3182
3206
  const getIsJoinSubQuery = (query) => {
3183
3207
  const {
@@ -3192,14 +3216,14 @@ const getIsJoinSubQuery = (query) => {
3192
3216
  return false;
3193
3217
  };
3194
3218
 
3195
- const processJoinArgs = (joinTo, first, args, joinSubQuery, whereExists) => {
3219
+ const processJoinArgs = (joinTo, first, args, joinSubQuery, shape, whereExists, forbidLateral) => {
3196
3220
  if (typeof first === "string") {
3197
3221
  if (first in joinTo.relations) {
3198
3222
  const { query: toQuery, joinQuery } = joinTo.relations[first];
3199
3223
  const j = joinQuery(toQuery, joinTo);
3200
3224
  if (typeof args[0] === "function") {
3201
3225
  const r = args[0](
3202
- makeJoinQueryBuilder(j, j.q.joinedShapes, joinTo)
3226
+ makeJoinQueryBuilder(j, j.q.joinedShapes, joinTo, shape)
3203
3227
  );
3204
3228
  return {
3205
3229
  j: j.merge(r),
@@ -3220,7 +3244,7 @@ const processJoinArgs = (joinTo, first, args, joinSubQuery, whereExists) => {
3220
3244
  j.table = first;
3221
3245
  j.q = {
3222
3246
  shape: w.shape,
3223
- computeds: w.computeds,
3247
+ runtimeComputeds: w.computeds,
3224
3248
  adapter: joinToQ.adapter,
3225
3249
  handleResult: joinToQ.handleResult,
3226
3250
  returnType: "all",
@@ -3238,7 +3262,8 @@ const processJoinArgs = (joinTo, first, args, joinSubQuery, whereExists) => {
3238
3262
  ...j.q.joinedShapes,
3239
3263
  ...joinedShapes
3240
3264
  } : joinedShapes,
3241
- joinTo
3265
+ joinTo,
3266
+ shape
3242
3267
  )
3243
3268
  );
3244
3269
  return {
@@ -3250,7 +3275,7 @@ const processJoinArgs = (joinTo, first, args, joinSubQuery, whereExists) => {
3250
3275
  }
3251
3276
  const args0 = args.length ? args[0] : orchidCore.returnArg;
3252
3277
  if (typeof args0 === "function") {
3253
- const q = first;
3278
+ let q = first;
3254
3279
  if (q.joinQueryAfterCallback) {
3255
3280
  let base = q.baseQuery;
3256
3281
  if (q.q.as) {
@@ -3260,14 +3285,17 @@ const processJoinArgs = (joinTo, first, args, joinSubQuery, whereExists) => {
3260
3285
  base,
3261
3286
  joinTo
3262
3287
  );
3263
- if (query.and) {
3264
- pushQueryArrayImmutable(q, "and", query.and);
3265
- }
3266
- if (query.or) {
3267
- pushQueryArrayImmutable(q, "or", query.or);
3268
- }
3269
- if (query.scopes) {
3270
- q.q.scopes = { ...q.q.scopes, ...query.scopes };
3288
+ if (query.and || query.or || query.scopes) {
3289
+ q = _clone(q);
3290
+ if (query.and) {
3291
+ pushQueryArrayImmutable(q, "and", query.and);
3292
+ }
3293
+ if (query.or) {
3294
+ pushQueryArrayImmutable(q, "or", query.or);
3295
+ }
3296
+ if (query.scopes) {
3297
+ q.q.scopes = { ...q.q.scopes, ...query.scopes };
3298
+ }
3271
3299
  }
3272
3300
  }
3273
3301
  const joinedShapes = {
@@ -3281,11 +3309,16 @@ const processJoinArgs = (joinTo, first, args, joinSubQuery, whereExists) => {
3281
3309
  ...q.q.joinedShapes,
3282
3310
  ...joinedShapes
3283
3311
  } : joinedShapes,
3284
- joinTo
3312
+ joinTo,
3313
+ shape
3285
3314
  )
3286
3315
  );
3287
3316
  joinSubQuery || (joinSubQuery = getIsJoinSubQuery(r));
3288
- return { q: joinSubQuery ? q.merge(r) : q, r, s: joinSubQuery };
3317
+ return {
3318
+ q: joinSubQuery && !forbidLateral ? q.merge(r) : q,
3319
+ r,
3320
+ s: joinSubQuery
3321
+ };
3289
3322
  }
3290
3323
  return {
3291
3324
  q: first,
@@ -3301,12 +3334,15 @@ const preprocessJoinArg = (q, arg) => {
3301
3334
  arg.joinQueryAfterCallback = arg.joinQuery;
3302
3335
  return arg;
3303
3336
  };
3304
- const makeJoinQueryBuilder = (joinedQuery, joinedShapes, joinTo) => {
3337
+ const makeJoinQueryBuilder = (joinedQuery, joinedShapes, joinTo, shape) => {
3305
3338
  const q = joinedQuery.baseQuery.clone();
3306
3339
  q.baseQuery = q;
3307
3340
  q.q.as = joinedQuery.q.as;
3308
3341
  q.q.joinedShapes = joinedShapes;
3309
3342
  q.q.joinTo = joinTo;
3343
+ if (shape) {
3344
+ q.q.shape = shape;
3345
+ }
3310
3346
  return q;
3311
3347
  };
3312
3348
 
@@ -3326,14 +3362,23 @@ const noneMethods = {
3326
3362
  // It is `async` so it returns a chainable Promise.
3327
3363
  async then(resolve, reject) {
3328
3364
  try {
3329
- const result = noneResult(this, this.q, this.q.returnType);
3330
- resolve?.(result);
3365
+ let result = noneResult(this, this.q, this.q.returnType);
3366
+ if (this.q.transform) {
3367
+ result = orchidCore.applyTransforms(
3368
+ this.q,
3369
+ this.q.returnType,
3370
+ this.q.transform,
3371
+ result
3372
+ );
3373
+ }
3374
+ return resolve?.(result);
3331
3375
  } catch (err) {
3332
- reject?.(err);
3376
+ return reject?.(err);
3333
3377
  }
3334
3378
  },
3335
- // `catch` returns a Promise, so it is chainable with then/catch.
3336
- catch: () => new Promise(orchidCore.noop)
3379
+ catch(reject) {
3380
+ return this.then(void 0, reject);
3381
+ }
3337
3382
  };
3338
3383
  const _queryNone = (q) => {
3339
3384
  if (isQueryNone(q)) return q;
@@ -3480,6 +3525,7 @@ const existsArgs = (self, q, args) => {
3480
3525
  preprocessJoinArg(self, q),
3481
3526
  args,
3482
3527
  false,
3528
+ void 0,
3483
3529
  true
3484
3530
  );
3485
3531
  return [
@@ -4320,7 +4366,7 @@ const getFullColumnTable = (q, column, index, as) => {
4320
4366
  return as && table !== as && orchidCore._checkIfAliased(q, table, as) ? as : table;
4321
4367
  };
4322
4368
 
4323
- const _join = (query, require, type, first, args) => {
4369
+ const _joinReturningArgs = (query, require, first, args, forbidLateral) => {
4324
4370
  let joinKey;
4325
4371
  let shape;
4326
4372
  let parsers;
@@ -4335,7 +4381,7 @@ const _join = (query, require, type, first, args) => {
4335
4381
  first = first._internalJoin;
4336
4382
  }
4337
4383
  if (require && isQueryNone(first)) {
4338
- return _queryNone(query);
4384
+ return;
4339
4385
  }
4340
4386
  const q = first;
4341
4387
  if (!isInternalJoin) {
@@ -4344,9 +4390,9 @@ const _join = (query, require, type, first, args) => {
4344
4390
  joinKey = q.q.as || q.table;
4345
4391
  if (joinKey) {
4346
4392
  shape = getShapeFromSelect(q, joinSubQuery && !!q.q.select);
4347
- parsers = q.q.parsers;
4393
+ parsers = orchidCore.getQueryParsers(q);
4348
4394
  batchParsers = q.q.batchParsers;
4349
- computeds = q.q.computeds;
4395
+ computeds = q.q.runtimeComputeds;
4350
4396
  if (joinSubQuery) {
4351
4397
  first = q.clone();
4352
4398
  first.shape = shape;
@@ -4358,9 +4404,9 @@ const _join = (query, require, type, first, args) => {
4358
4404
  if (relation) {
4359
4405
  shape = getShapeFromSelect(relation.query);
4360
4406
  const r = relation.query;
4361
- parsers = r.q.parsers;
4407
+ parsers = orchidCore.getQueryParsers(r);
4362
4408
  batchParsers = r.q.batchParsers;
4363
- computeds = r.q.computeds;
4409
+ computeds = r.q.runtimeComputeds;
4364
4410
  } else {
4365
4411
  const w = query.q.withShapes?.[joinKey];
4366
4412
  shape = w?.shape;
@@ -4378,18 +4424,23 @@ const _join = (query, require, type, first, args) => {
4378
4424
  query,
4379
4425
  first,
4380
4426
  args,
4381
- joinSubQuery
4427
+ joinSubQuery,
4428
+ shape,
4429
+ false,
4430
+ forbidLateral
4382
4431
  );
4383
4432
  if (require && "r" in joinArgs && isQueryNone(joinArgs.r)) {
4384
- return _queryNone(query);
4433
+ return;
4385
4434
  } else if (joinKey && "s" in joinArgs && joinArgs.s) {
4386
4435
  const j = "j" in joinArgs ? joinArgs.r ?? joinArgs.j : "r" in joinArgs ? joinArgs.r : joinArgs.q;
4387
4436
  const jq = j.q;
4388
4437
  if (jq.select || !jq.selectAllColumns) {
4389
4438
  const { q } = query;
4390
- const shape2 = getShapeFromSelect(j, true);
4391
- orchidCore.setObjectValueImmutable(q, "joinedShapes", joinKey, shape2);
4392
- orchidCore.setObjectValueImmutable(q, "joinedParsers", joinKey, jq.parsers);
4439
+ if ("r" in joinArgs && joinArgs.r) {
4440
+ joinArgs.c = shape = getShapeFromSelect(j, true);
4441
+ }
4442
+ orchidCore.setObjectValueImmutable(q, "joinedShapes", joinKey, shape);
4443
+ orchidCore.setObjectValueImmutable(q, "joinedParsers", joinKey, orchidCore.getQueryParsers(j));
4393
4444
  if (jq.batchParsers) {
4394
4445
  orchidCore.setObjectValueImmutable(
4395
4446
  jq,
@@ -4398,7 +4449,12 @@ const _join = (query, require, type, first, args) => {
4398
4449
  jq.batchParsers
4399
4450
  );
4400
4451
  }
4401
- orchidCore.setObjectValueImmutable(q, "joinedComputeds", joinKey, jq.computeds);
4452
+ orchidCore.setObjectValueImmutable(
4453
+ q,
4454
+ "joinedComputeds",
4455
+ joinKey,
4456
+ jq.runtimeComputeds
4457
+ );
4402
4458
  } else {
4403
4459
  addAllShapesAndParsers(
4404
4460
  query,
@@ -4419,6 +4475,13 @@ const _join = (query, require, type, first, args) => {
4419
4475
  computeds
4420
4476
  );
4421
4477
  }
4478
+ return joinArgs;
4479
+ };
4480
+ const _join = (query, require, type, first, args) => {
4481
+ const joinArgs = _joinReturningArgs(query, require, first, args);
4482
+ if (!joinArgs) {
4483
+ return _queryNone(query);
4484
+ }
4422
4485
  orchidCore.pushQueryValueImmutable(query, "join", {
4423
4486
  type,
4424
4487
  args: joinArgs
@@ -4484,7 +4547,12 @@ const _joinLateral = (self, type, arg, as, innerJoinLateral) => {
4484
4547
  if (joinKey) {
4485
4548
  const shape = getShapeFromSelect(arg, true);
4486
4549
  orchidCore.setObjectValueImmutable(q.q, "joinedShapes", joinKey, shape);
4487
- orchidCore.setObjectValueImmutable(q.q, "joinedParsers", joinKey, arg.q.parsers);
4550
+ orchidCore.setObjectValueImmutable(
4551
+ q.q,
4552
+ "joinedParsers",
4553
+ joinKey,
4554
+ orchidCore.getQueryParsers(arg)
4555
+ );
4488
4556
  if (arg.q.batchParsers) {
4489
4557
  orchidCore.setObjectValueImmutable(
4490
4558
  q.q,
@@ -4495,7 +4563,7 @@ const _joinLateral = (self, type, arg, as, innerJoinLateral) => {
4495
4563
  }
4496
4564
  }
4497
4565
  as || (as = getQueryAs(arg));
4498
- orchidCore.setObjectValueImmutable(q.q, "joinedComputeds", as, arg.q.computeds);
4566
+ orchidCore.setObjectValueImmutable(q.q, "joinedComputeds", as, arg.q.runtimeComputeds);
4499
4567
  orchidCore.pushQueryValueImmutable(q, "join", {
4500
4568
  type: `${type} LATERAL`,
4501
4569
  args: { l: arg, a: as, i: innerJoinLateral }
@@ -4880,6 +4948,7 @@ class ComputedColumn {
4880
4948
  const computeAtRuntime = (deps, fn) => new ComputedColumn("one", deps, fn);
4881
4949
  const computeBatchAtRuntime = (deps, fn) => new ComputedColumn("many", deps, fn);
4882
4950
  const applyComputedColumns = (q, fn) => {
4951
+ var _a;
4883
4952
  q.computeAtRuntime = computeAtRuntime;
4884
4953
  q.computeBatchAtRuntime = computeBatchAtRuntime;
4885
4954
  const computed = fn(q);
@@ -4887,8 +4956,8 @@ const applyComputedColumns = (q, fn) => {
4887
4956
  let item = computed[key];
4888
4957
  if (typeof item === "function") item = item.call(computed);
4889
4958
  if (item instanceof ComputedColumn) {
4890
- q.q.computeds = {
4891
- ...q.q.computeds,
4959
+ q.q.runtimeComputeds = {
4960
+ ...q.q.runtimeComputeds,
4892
4961
  [key]: item
4893
4962
  };
4894
4963
  } else {
@@ -4904,11 +4973,10 @@ const applyComputedColumns = (q, fn) => {
4904
4973
  data.computed = item;
4905
4974
  data.explicitSelect = true;
4906
4975
  data.readOnly = true;
4907
- addColumnParserToQuery(
4908
- q.q,
4909
- key,
4910
- item.result.value
4911
- );
4976
+ const parse = item.result.value._parse;
4977
+ if (parse) {
4978
+ ((_a = q.q).defaultParsers ?? (_a.defaultParsers = {}))[key] = parse;
4979
+ }
4912
4980
  }
4913
4981
  }
4914
4982
  q.computeAtRuntime = q.computeBatchAtRuntime = void 0;
@@ -5117,7 +5185,7 @@ const then = async (q, adapter, trx, beforeHooks, afterHooks, afterCommitHooks,
5117
5185
  )
5118
5186
  );
5119
5187
  }
5120
- sql = q.toSQL();
5188
+ const localSql = sql = q.toSQL();
5121
5189
  const { hookSelect, delayedRelationSelect } = sql;
5122
5190
  const { returnType = "all" } = query;
5123
5191
  const tempReturnType = hookSelect || returnType === "rows" && q.q.batchParsers || delayedRelationSelect?.value ? "all" : returnType;
@@ -5142,7 +5210,7 @@ const then = async (q, adapter, trx, beforeHooks, afterHooks, afterCommitHooks,
5142
5210
  if (query.patchResult) {
5143
5211
  await query.patchResult(q, hookSelect, queryResult);
5144
5212
  }
5145
- result = query.handleResult(q, tempReturnType, queryResult);
5213
+ result = query.handleResult(q, tempReturnType, queryResult, localSql);
5146
5214
  } else {
5147
5215
  const queryMethod = queryMethodByReturnType[tempReturnType];
5148
5216
  const queryBatch = async (batch) => {
@@ -5180,10 +5248,7 @@ const then = async (q, adapter, trx, beforeHooks, afterHooks, afterCommitHooks,
5180
5248
  if (query.patchResult) {
5181
5249
  await query.patchResult(q, hookSelect, queryResult);
5182
5250
  }
5183
- result = query.handleResult(q, tempReturnType, queryResult);
5184
- }
5185
- if (result && typeof result === "object" && typeof result.then === "function") {
5186
- result = await result;
5251
+ result = query.handleResult(q, tempReturnType, queryResult, localSql);
5187
5252
  }
5188
5253
  let tempColumns;
5189
5254
  let renames;
@@ -5207,8 +5272,8 @@ const then = async (q, adapter, trx, beforeHooks, afterHooks, afterCommitHooks,
5207
5272
  }
5208
5273
  }
5209
5274
  if (query.selectedComputeds) {
5210
- const promise = processComputedResult(query, result);
5211
- if (promise) await promise;
5275
+ const promise2 = processComputedResult(query, result);
5276
+ if (promise2) await promise2;
5212
5277
  }
5213
5278
  }
5214
5279
  const hasAfterHook = afterHooks || afterCommitHooks || query.after;
@@ -5265,19 +5330,15 @@ const then = async (q, adapter, trx, beforeHooks, afterHooks, afterCommitHooks,
5265
5330
  );
5266
5331
  const selectQuery = q2.clone();
5267
5332
  selectQuery.q.type = selectQuery.q.returnType = void 0;
5268
- ((_a = selectQuery.q).and ?? (_a.and = [])).push(orchidCore.pick(result, primaryKeys));
5269
- const relationsSelect = delayedRelationSelect.value;
5270
- let selectAs;
5271
- if (renames) {
5272
- selectAs = {};
5273
- for (const key in renames) {
5274
- if (key in relationsSelect) {
5275
- selectAs[renames[key]] = relationsSelect[key];
5276
- }
5277
- }
5278
- } else {
5279
- selectAs = { ...relationsSelect };
5333
+ const matchSourceTableIds = {};
5334
+ for (const pkey of primaryKeys) {
5335
+ matchSourceTableIds[pkey] = {
5336
+ in: result.map((row) => row[pkey])
5337
+ };
5280
5338
  }
5339
+ ((_a = selectQuery.q).and ?? (_a.and = [])).push(matchSourceTableIds);
5340
+ const relationsSelect = delayedRelationSelect.value;
5341
+ const selectAs = { ...relationsSelect };
5281
5342
  const select = [{ selectAs }];
5282
5343
  const relationKeyAliases = primaryKeys.map((key) => {
5283
5344
  if (key in selectAs) {
@@ -5301,16 +5362,30 @@ const then = async (q, adapter, trx, beforeHooks, afterHooks, afterCommitHooks,
5301
5362
  Object.assign(row, relationRow);
5302
5363
  }
5303
5364
  }
5365
+ if (renames) {
5366
+ for (const key in relationsSelect) {
5367
+ if (key in renames) {
5368
+ delete renames[key];
5369
+ }
5370
+ }
5371
+ }
5304
5372
  }
5373
+ const promise = parseBatch(q, queryResult, delayedRelationSelect);
5374
+ if (promise) await promise;
5305
5375
  if (hookSelect || tempReturnType !== returnType) {
5306
5376
  if (renames) {
5307
- for (const a in renames) {
5308
- for (const record of result) {
5309
- const value = record[a];
5310
- record[a] = record[renames[a]];
5311
- record[renames[a]] = value;
5377
+ const renamedResult = Array.from({
5378
+ length: result.length
5379
+ });
5380
+ for (let i = 0, len = result.length; i < len; ++i) {
5381
+ const record = result[i];
5382
+ const renamedRecord = renamedResult[i] = { ...record };
5383
+ for (const a in renames) {
5384
+ renamedRecord[a] = record[renames[a]];
5385
+ renamedRecord[renames[a]] = record[a];
5312
5386
  }
5313
5387
  }
5388
+ result = renamedResult;
5314
5389
  }
5315
5390
  result = filterResult(
5316
5391
  q,
@@ -5364,68 +5439,46 @@ const execQuery = (adapter, method, sql) => {
5364
5439
  return result;
5365
5440
  });
5366
5441
  };
5367
- const handleResult = (q, returnType, result, isSubQuery) => {
5368
- const { parsers } = q.q;
5442
+ const handleResult = (q, returnType, result, sql, isSubQuery) => {
5443
+ const parsers = orchidCore.getQueryParsers(q, sql.hookSelect);
5369
5444
  switch (returnType) {
5370
5445
  case "all": {
5371
5446
  if (q.q.throwOnNotFound && result.rows.length === 0)
5372
5447
  throw new orchidCore.NotFoundError(q);
5373
- const promise = parseBatch(q, result);
5374
5448
  const { rows } = result;
5375
5449
  if (parsers) {
5376
5450
  for (const row of rows) {
5377
5451
  parseRecord(parsers, row);
5378
5452
  }
5379
5453
  }
5380
- return promise ? promise.then(() => rows) : rows;
5454
+ return rows;
5381
5455
  }
5382
5456
  case "one": {
5383
5457
  const { rows } = result;
5384
5458
  if (!rows.length) return;
5385
- const promise = parseBatch(q, result);
5386
5459
  if (parsers) parseRecord(parsers, rows[0]);
5387
- return promise ? promise.then(() => rows[0]) : rows[0];
5460
+ return rows[0];
5388
5461
  }
5389
5462
  case "oneOrThrow": {
5390
5463
  const { rows } = result;
5391
5464
  if (!rows.length) throw new orchidCore.NotFoundError(q);
5392
- const promise = parseBatch(q, result);
5393
5465
  if (parsers) parseRecord(parsers, rows[0]);
5394
- return promise ? promise.then(() => rows[0]) : rows[0];
5466
+ return rows[0];
5395
5467
  }
5396
5468
  case "rows": {
5397
5469
  const { rows } = result;
5398
- const promise = parseBatch(q, result);
5399
- if (promise) {
5400
- return promise.then(() => {
5401
- if (parsers) parseRows(parsers, result.fields, rows);
5402
- return rows;
5403
- });
5404
- } else if (parsers) {
5470
+ if (parsers) {
5405
5471
  parseRows(parsers, result.fields, rows);
5406
5472
  }
5407
5473
  return rows;
5408
5474
  }
5409
5475
  case "pluck": {
5410
5476
  const { rows } = result;
5411
- const promise = parseBatch(q, result);
5412
- if (promise) {
5413
- return promise.then(() => {
5414
- parsePluck(parsers, isSubQuery, rows);
5415
- return rows;
5416
- });
5417
- }
5418
5477
  parsePluck(parsers, isSubQuery, rows);
5419
5478
  return rows;
5420
5479
  }
5421
5480
  case "value": {
5422
5481
  const { rows } = result;
5423
- const promise = parseBatch(q, result);
5424
- if (promise) {
5425
- return promise.then(() => {
5426
- return rows[0]?.[0] !== void 0 ? parseValue(rows[0][0], parsers) : q.q.notFoundDefault;
5427
- });
5428
- }
5429
5482
  return rows[0]?.[0] !== void 0 ? parseValue(rows[0][0], parsers) : q.q.notFoundDefault;
5430
5483
  }
5431
5484
  case "valueOrThrow": {
@@ -5436,13 +5489,6 @@ const handleResult = (q, returnType, result, isSubQuery) => {
5436
5489
  return result.rowCount;
5437
5490
  }
5438
5491
  const { rows } = result;
5439
- const promise = parseBatch(q, result);
5440
- if (promise) {
5441
- return promise.then(() => {
5442
- if (rows[0]?.[0] === void 0) throw new orchidCore.NotFoundError(q);
5443
- return parseValue(rows[0][0], parsers);
5444
- });
5445
- }
5446
5492
  if (rows[0]?.[0] === void 0) throw new orchidCore.NotFoundError(q);
5447
5493
  return parseValue(rows[0][0], parsers);
5448
5494
  }
@@ -5451,9 +5497,9 @@ const handleResult = (q, returnType, result, isSubQuery) => {
5451
5497
  }
5452
5498
  }
5453
5499
  };
5454
- const parseBatch = (q, queryResult) => {
5500
+ const parseBatch = (q, queryResult, delayedRelationSelect) => {
5455
5501
  let promises;
5456
- if (q.q.batchParsers) {
5502
+ if (q.q.batchParsers && !delayedRelationSelect?.value) {
5457
5503
  for (const parser of q.q.batchParsers) {
5458
5504
  const res = parser.fn(parser.path, queryResult);
5459
5505
  if (res) (promises ?? (promises = [])).push(res);
@@ -5566,44 +5612,46 @@ const filterAllResult = (result, tempColumns, hasAfterHook) => {
5566
5612
  return result;
5567
5613
  };
5568
5614
 
5615
+ const addWithParsers = (w, parsers) => {
5616
+ for (const key in w.shape) {
5617
+ const { _parse } = w.shape[key];
5618
+ if (_parse) parsers[key] = _parse;
5619
+ }
5620
+ };
5569
5621
  function queryFrom(self, arg) {
5570
5622
  const data = self.q;
5571
5623
  if (typeof arg === "string") {
5572
5624
  data.as || (data.as = arg);
5573
5625
  const w = data.withShapes?.[arg];
5574
5626
  data.shape = w?.shape ?? anyShape;
5575
- data.computeds = w?.computeds;
5576
- } else if (orchidCore.isExpression(arg)) {
5577
- data.as || (data.as = "t");
5627
+ data.runtimeComputeds = w?.computeds;
5628
+ const parsers = {};
5629
+ data.defaultParsers = parsers;
5630
+ if (w) addWithParsers(w, parsers);
5578
5631
  } else if (Array.isArray(arg)) {
5579
5632
  const { shape } = data;
5580
- let clonedParsers = false;
5633
+ const joinedParsers = {};
5581
5634
  for (const item of arg) {
5582
5635
  if (typeof item === "string") {
5583
5636
  const w = data.withShapes[item];
5584
5637
  Object.assign(shape, w.shape);
5585
- if (w.computeds) data.computeds = { ...data.computeds, ...w.computeds };
5586
- for (const key in w.shape) {
5587
- addColumnParserToQuery(
5588
- self,
5589
- key,
5590
- w.shape[key]
5591
- );
5592
- }
5638
+ if (w.computeds)
5639
+ data.runtimeComputeds = { ...data.runtimeComputeds, ...w.computeds };
5640
+ const parsers = {};
5641
+ joinedParsers[item] = parsers;
5642
+ addWithParsers(w, parsers);
5593
5643
  } else if (!orchidCore.isExpression(item)) {
5594
5644
  Object.assign(shape, getShapeFromSelect(item, true));
5595
- if (!clonedParsers) {
5596
- data.parsers = { ...data.parsers };
5597
- clonedParsers = true;
5598
- }
5599
- Object.assign(data.parsers, item.q.parsers);
5645
+ const key = getQueryAs(item);
5646
+ joinedParsers[key] = orchidCore.getQueryParsers(item);
5600
5647
  }
5601
5648
  }
5649
+ data.joinedParsers = joinedParsers;
5602
5650
  } else {
5603
5651
  const q = arg;
5604
5652
  data.as || (data.as = q.q.as || q.table || "t");
5605
5653
  data.shape = getShapeFromSelect(q, true);
5606
- data.parsers = q.q.parsers;
5654
+ data.defaultParsers = orchidCore.getQueryParsers(q);
5607
5655
  data.batchParsers = q.q.batchParsers;
5608
5656
  }
5609
5657
  data.from = arg;
@@ -5716,7 +5764,7 @@ const addParsersForSelectJoined = (q, arg, as = arg) => {
5716
5764
  }
5717
5765
  };
5718
5766
  const addParserForSelectItem = (q, as, key, arg, columnAlias, joinQuery) => {
5719
- if (typeof arg === "object" || typeof arg === "function") {
5767
+ if (typeof arg === "object") {
5720
5768
  const { q: query } = arg;
5721
5769
  if (query.batchParsers) {
5722
5770
  pushQueryArrayImmutable(
@@ -5728,7 +5776,8 @@ const addParserForSelectItem = (q, as, key, arg, columnAlias, joinQuery) => {
5728
5776
  }))
5729
5777
  );
5730
5778
  }
5731
- if (query.hookSelect || query.parsers || query.transform || query.returnType === "oneOrThrow" || query.returnType === "valueOrThrow" || query.returnType === "one" || query.returnType === "value") {
5779
+ const parsers = orchidCore.isExpression(arg) ? void 0 : orchidCore.getQueryParsers(arg);
5780
+ if (parsers || query.hookSelect || query.transform || query.returnType === "oneOrThrow" || query.returnType === "valueOrThrow" || query.returnType === "one" || query.returnType === "value") {
5732
5781
  orchidCore.pushQueryValueImmutable(q, "batchParsers", {
5733
5782
  path: [key],
5734
5783
  fn: (path, queryResult) => {
@@ -5752,7 +5801,6 @@ const addParserForSelectItem = (q, as, key, arg, columnAlias, joinQuery) => {
5752
5801
  collectNestedSelectBatches(batches, rows, path, last);
5753
5802
  switch (returnType) {
5754
5803
  case "all": {
5755
- const { parsers } = query;
5756
5804
  if (parsers) {
5757
5805
  for (const { data } of batches) {
5758
5806
  for (const one of data) {
@@ -5764,7 +5812,6 @@ const addParserForSelectItem = (q, as, key, arg, columnAlias, joinQuery) => {
5764
5812
  }
5765
5813
  case "one":
5766
5814
  case "oneOrThrow": {
5767
- const { parsers } = query;
5768
5815
  if (parsers) {
5769
5816
  if (returnType === "one") {
5770
5817
  for (const batch of batches) {
@@ -5795,7 +5842,7 @@ const addParserForSelectItem = (q, as, key, arg, columnAlias, joinQuery) => {
5795
5842
  break;
5796
5843
  }
5797
5844
  case "pluck": {
5798
- const parse = query.parsers?.pluck;
5845
+ const parse = parsers?.pluck;
5799
5846
  if (parse) {
5800
5847
  for (const { data } of batches) {
5801
5848
  for (let i = 0; i < data.length; i++) {
@@ -5808,7 +5855,7 @@ const addParserForSelectItem = (q, as, key, arg, columnAlias, joinQuery) => {
5808
5855
  case "value":
5809
5856
  case "valueOrThrow": {
5810
5857
  const notNullable = !query.getColumn?.data.isNullable;
5811
- const parse = query.parsers?.[orchidCore.getValueKey];
5858
+ const parse = parsers?.[orchidCore.getValueKey];
5812
5859
  if (parse) {
5813
5860
  if (returnType === "value") {
5814
5861
  for (const item of batches) {
@@ -6039,31 +6086,30 @@ const setParserForSelectedString = (query, arg, as, columnAs, columnAlias) => {
6039
6086
  const computeds = q.joinedComputeds?.[table];
6040
6087
  if (computeds?.[column]) {
6041
6088
  const computed = computeds[column];
6042
- const map = q.hookSelect = new Map(q.hookSelect);
6043
- for (const column2 of computed.deps) {
6044
- map.set(column2, { select: `${table}.${column2}` });
6045
- }
6089
+ orchidCore._addToHookSelectWithTable(query, computed.deps, table);
6046
6090
  orchidCore.setObjectValueImmutable(q, "selectedComputeds", column, computed);
6047
6091
  return;
6048
6092
  }
6049
6093
  return arg;
6050
6094
  };
6051
6095
  const selectColumn = (query, q, key, columnAs, columnAlias) => {
6052
- if (columnAs && q.parsers) {
6053
- const parser = q.parsers[key];
6054
- if (parser) orchidCore.setObjectValueImmutable(q, "parsers", columnAs, parser);
6055
- }
6056
- if (q.computeds?.[key]) {
6057
- const computed = q.computeds[key];
6058
- const map = query.q.hookSelect = new Map(query.q.hookSelect);
6059
- for (const key2 of computed.deps) {
6060
- map.set(key2, { select: key2 });
6061
- }
6062
- query.q.selectedComputeds = {
6063
- ...query.q.selectedComputeds,
6064
- [columnAlias || key]: computed
6065
- };
6066
- return;
6096
+ if (key === "*") {
6097
+ const { defaultParsers } = query.q;
6098
+ if (defaultParsers) {
6099
+ orchidCore.spreadObjectValues(query.q, "parsers", defaultParsers);
6100
+ }
6101
+ } else {
6102
+ const parser = query.q.defaultParsers?.[key];
6103
+ if (parser) orchidCore.setObjectValueImmutable(q, "parsers", columnAs || key, parser);
6104
+ if (q.runtimeComputeds?.[key]) {
6105
+ const computed = q.runtimeComputeds[key];
6106
+ orchidCore._addToHookSelect(query, computed.deps);
6107
+ query.q.selectedComputeds = {
6108
+ ...query.q.selectedComputeds,
6109
+ [columnAlias || key]: computed
6110
+ };
6111
+ return;
6112
+ }
6067
6113
  }
6068
6114
  return key;
6069
6115
  };
@@ -6196,6 +6242,11 @@ function _querySelect(q, args) {
6196
6242
  }
6197
6243
  return pushQueryArrayImmutable(q, "select", selectArgs);
6198
6244
  }
6245
+ const _querySelectAll = (query) => {
6246
+ const q = query;
6247
+ q.q.select = ["*"];
6248
+ q.q.parsers = q.q.defaultParsers;
6249
+ };
6199
6250
  class Select {
6200
6251
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
6201
6252
  select(...args) {
@@ -6219,7 +6270,7 @@ class Select {
6219
6270
  */
6220
6271
  selectAll() {
6221
6272
  const q = _clone(this);
6222
- q.q.select = ["*"];
6273
+ _querySelectAll(q);
6223
6274
  if (q.q.returning) {
6224
6275
  q.q.returnType = q.q.returningMany ? "all" : "oneOrThrow";
6225
6276
  q.q.returning = void 0;
@@ -7076,7 +7127,7 @@ const selectAllSql = (query, quotedAs, jsonList) => {
7076
7127
  if (jsonList) {
7077
7128
  Object.assign(jsonList, query.selectAllShape);
7078
7129
  }
7079
- return query.join?.length ? query.selectAllColumns?.map((item) => `${quotedAs}.${item}`).join(", ") || `${quotedAs}.*` : query.selectAllColumns?.join(", ") || "*";
7130
+ return query.join?.length || query.updateFrom ? query.selectAllColumns?.map((item) => `${quotedAs}.${item}`).join(", ") || `${quotedAs}.*` : query.selectAllColumns?.join(", ") || "*";
7080
7131
  };
7081
7132
  const pushSubQuerySql = (ctx, mainQuery, query, as, list, quotedAs, aliases) => {
7082
7133
  const { returnType = "all" } = query.q;
@@ -7147,7 +7198,7 @@ const pushSubQuerySql = (ctx, mainQuery, query, as, list, quotedAs, aliases) =>
7147
7198
  case "pluck": {
7148
7199
  const { select } = query.q;
7149
7200
  const first = select?.[0];
7150
- if (!first && query.q.computeds?.[as]) {
7201
+ if (!first && query.q.runtimeComputeds?.[as]) {
7151
7202
  query = queryJson(query);
7152
7203
  } else if (!first) {
7153
7204
  throw new orchidCore.OrchidOrmInternalError(
@@ -7164,7 +7215,7 @@ const pushSubQuerySql = (ctx, mainQuery, query, as, list, quotedAs, aliases) =>
7164
7215
  }
7165
7216
  case "value":
7166
7217
  case "valueOrThrow":
7167
- if (!query.q.returning && query.q.computeds?.[as]) {
7218
+ if (!query.q.returning && query.q.runtimeComputeds?.[as]) {
7168
7219
  query = queryJson(query);
7169
7220
  }
7170
7221
  break;
@@ -7276,9 +7327,6 @@ const pushFromAndAs = (ctx, table, data, quotedAs) => {
7276
7327
  let sql = "FROM ";
7277
7328
  const from = getFrom(ctx, table, data, quotedAs);
7278
7329
  sql += from;
7279
- if (data.as && quotedAs && quotedAs !== from) {
7280
- sql += ` ${quotedAs}`;
7281
- }
7282
7330
  for (const as in data.sources) {
7283
7331
  const source = data.sources[as];
7284
7332
  const lang = getSearchLang(ctx, data, source, quotedAs);
@@ -7325,6 +7373,9 @@ const getFrom = (ctx, table, data, quotedAs) => {
7325
7373
  return fromToSql(ctx, data, from, quotedAs);
7326
7374
  }
7327
7375
  let sql = quoteSchemaAndTable(data.schema, table.table);
7376
+ if (data.as && quotedAs && quotedAs !== sql) {
7377
+ sql += ` ${quotedAs}`;
7378
+ }
7328
7379
  if (data.only) sql = `ONLY ${sql}`;
7329
7380
  return sql;
7330
7381
  };
@@ -7333,13 +7384,13 @@ const fromToSql = (ctx, data, from, quotedAs) => {
7333
7384
  let sql;
7334
7385
  if (typeof from === "object") {
7335
7386
  if (orchidCore.isExpression(from)) {
7336
- sql = from.toSQL(ctx, quotedAs);
7387
+ sql = from.toSQL(ctx, quotedAs) + " " + quotedAs;
7337
7388
  } else {
7338
7389
  only = from.q.only;
7339
7390
  if (!from.table) {
7340
7391
  sql = `(${getSqlText(toSQL(from, ctx))})`;
7341
7392
  } else if (!checkIfASimpleQuery(from)) {
7342
- sql = `(${getSqlText(toSQL(from, ctx))})`;
7393
+ sql = `(${getSqlText(toSQL(from, ctx))}) ${quotedAs || `"${getQueryAs(from)}"`}`;
7343
7394
  } else {
7344
7395
  sql = quoteSchemaAndTable(from.q.schema, from.table);
7345
7396
  }
@@ -7457,7 +7508,45 @@ const pushUpdateSql = (ctx, table, query, quotedAs) => {
7457
7508
  }
7458
7509
  ctx.sql.push("SET");
7459
7510
  ctx.sql.push(set.join(", "));
7460
- pushWhereStatementSql(ctx, table, query, quotedAs);
7511
+ const { updateFrom } = query;
7512
+ let fromWhereSql;
7513
+ if (updateFrom) {
7514
+ const { target, on } = processJoinItem(
7515
+ ctx,
7516
+ table,
7517
+ query,
7518
+ updateFrom,
7519
+ quotedAs
7520
+ );
7521
+ ctx.sql.push(`FROM ${target}`);
7522
+ fromWhereSql = on;
7523
+ if (query.join) {
7524
+ const joinSet = query.join.length > 1 ? /* @__PURE__ */ new Set() : null;
7525
+ for (const item of query.join) {
7526
+ const { target: target2, on: on2 } = processJoinItem(
7527
+ ctx,
7528
+ table,
7529
+ query,
7530
+ item.args,
7531
+ quotedAs
7532
+ );
7533
+ if (joinSet) {
7534
+ const key = `${item.type}${target2}${on2}`;
7535
+ if (joinSet.has(key)) continue;
7536
+ joinSet.add(key);
7537
+ }
7538
+ ctx.sql.push(`${item.type} ${target2} ON true`);
7539
+ if (on2) {
7540
+ fromWhereSql = fromWhereSql ? fromWhereSql + " AND " + on2 : on2;
7541
+ }
7542
+ }
7543
+ }
7544
+ }
7545
+ const mainWhereSql = whereToSql(ctx, table, query, quotedAs);
7546
+ const whereSql = mainWhereSql ? fromWhereSql ? mainWhereSql + " AND " + fromWhereSql : mainWhereSql : fromWhereSql;
7547
+ if (whereSql) {
7548
+ ctx.sql.push("WHERE", whereSql);
7549
+ }
7461
7550
  hookSelect = pushUpdateReturning(
7462
7551
  ctx,
7463
7552
  table,
@@ -8749,7 +8838,7 @@ class WithMethods {
8749
8838
  const shape = getShapeFromSelect(query, true);
8750
8839
  return setQueryObjectValueImmutable(q, "withShapes", name, {
8751
8840
  shape,
8752
- computeds: query.q.computeds
8841
+ computeds: query.q.runtimeComputeds
8753
8842
  });
8754
8843
  }
8755
8844
  withRecursive(name, ...args) {
@@ -8760,7 +8849,7 @@ class WithMethods {
8760
8849
  arg.q.withShapes = q.q.withShapes;
8761
8850
  let query = typeof baseFn === "function" ? baseFn(arg) : baseFn;
8762
8851
  const shape = getShapeFromSelect(query, true);
8763
- const withConfig = { shape, computeds: query.q.computeds };
8852
+ const withConfig = { shape, computeds: query.q.runtimeComputeds };
8764
8853
  ((_a = arg.q).withShapes ?? (_a.withShapes = {}))[name] = withConfig;
8765
8854
  const recursive = recursiveFn(arg);
8766
8855
  query = _queryUnion(query, [recursive], options.union ?? "UNION ALL");
@@ -8777,14 +8866,15 @@ class WithMethods {
8777
8866
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
8778
8867
  withSql(name, ...args) {
8779
8868
  const q = _clone(this);
8780
- const [options, shape, sql] = args.length === 2 ? [void 0, args[0], args[1]] : args;
8869
+ const [options, shapeFn, sql] = args.length === 2 ? [void 0, args[0], args[1]] : args;
8870
+ const shape = shapeFn(this.columnTypes);
8781
8871
  orchidCore.pushQueryValueImmutable(q, "with", {
8782
8872
  n: name,
8783
- o: options,
8873
+ o: { ...options, columns: Object.keys(shape) },
8784
8874
  s: sql(q)
8785
8875
  });
8786
8876
  return setQueryObjectValueImmutable(q, "withShapes", name, {
8787
- shape: shape(this.columnTypes)
8877
+ shape
8788
8878
  });
8789
8879
  }
8790
8880
  }
@@ -9035,7 +9125,7 @@ const createSelect = (q) => {
9035
9125
  if (q.q.returnType === "void" || isSelectingCount(q)) {
9036
9126
  q.q.select = void 0;
9037
9127
  } else if (!q.q.select) {
9038
- q.q.select = ["*"];
9128
+ _querySelectAll(q);
9039
9129
  q.q.returning = true;
9040
9130
  }
9041
9131
  };
@@ -10881,6 +10971,7 @@ class JsonMethods {
10881
10971
  const mergableObjects = /* @__PURE__ */ new Set([
10882
10972
  "shape",
10883
10973
  "withShapes",
10974
+ "defaultParsers",
10884
10975
  "parsers",
10885
10976
  "defaults",
10886
10977
  "joinedShapes",
@@ -10967,7 +11058,8 @@ const _queryChangeCounter = (self, op, data) => {
10967
11058
  orchidCore.pushQueryValueImmutable(self, "updateData", map);
10968
11059
  return self;
10969
11060
  };
10970
- const _queryUpdate = (query, arg) => {
11061
+ const _queryUpdate = (updateSelf, arg) => {
11062
+ const query = updateSelf;
10971
11063
  const { q } = query;
10972
11064
  q.type = "update";
10973
11065
  const returnCount = !q.select;
@@ -10975,6 +11067,7 @@ const _queryUpdate = (query, arg) => {
10975
11067
  orchidCore.pushQueryValueImmutable(query, "updateData", set);
10976
11068
  const { shape } = q;
10977
11069
  const ctx = {};
11070
+ let selectQuery;
10978
11071
  for (const key in arg) {
10979
11072
  const item = shape[key];
10980
11073
  if (!item && shape !== anyShape) {
@@ -10986,8 +11079,12 @@ const _queryUpdate = (query, arg) => {
10986
11079
  if (item) throwOnReadOnly(query, item, key);
10987
11080
  let value = set[key];
10988
11081
  if (typeof value === "function") {
11082
+ if (!selectQuery) {
11083
+ selectQuery = query.clone();
11084
+ selectQuery.q.type = void 0;
11085
+ }
10989
11086
  value = resolveSubQueryCallbackV2(
10990
- query.baseQuery,
11087
+ selectQuery,
10991
11088
  value
10992
11089
  );
10993
11090
  if (value instanceof Db && value.q.type && value.q.subQuery) {
@@ -11000,14 +11097,7 @@ const _queryUpdate = (query, arg) => {
11000
11097
  }
11001
11098
  if (value !== null && value !== void 0 && !orchidCore.isExpression(value)) {
11002
11099
  if (value instanceof Db) {
11003
- moveQueryValueToWith(
11004
- query,
11005
- q,
11006
- value,
11007
- "with",
11008
- set,
11009
- key
11010
- );
11100
+ moveQueryValueToWith(query, q, value, "with", set, key);
11011
11101
  } else {
11012
11102
  const encode = item?.data.encode;
11013
11103
  if (encode) set[key] = encode(value);
@@ -11035,10 +11125,7 @@ const _queryUpdate = (query, arg) => {
11035
11125
  primaryKeys,
11036
11126
  queryResult.rows.map((item) => primaryKeys.map((key) => item[key]))
11037
11127
  );
11038
- await _queryUpdate(
11039
- t,
11040
- ctx.collect.data
11041
- );
11128
+ await _queryUpdate(t, ctx.collect.data);
11042
11129
  for (const row of queryResult.rows) {
11043
11130
  Object.assign(row, ctx.collect.data);
11044
11131
  }
@@ -11050,7 +11137,9 @@ const _queryUpdate = (query, arg) => {
11050
11137
  q.returnType = "valueOrThrow";
11051
11138
  q.returning = true;
11052
11139
  }
11053
- throwIfNoWhere(query, "update");
11140
+ if (!q.updateFrom) {
11141
+ throwIfNoWhere(query, "update");
11142
+ }
11054
11143
  return query;
11055
11144
  };
11056
11145
  const _queryUpdateOrThrow = (q, arg) => {
@@ -11288,6 +11377,77 @@ class Update {
11288
11377
  updateOrThrow(arg) {
11289
11378
  return _queryUpdateOrThrow(_clone(this), arg);
11290
11379
  }
11380
+ /**
11381
+ * Use `updateFrom` to update records in one table based on a query result from another table or CTE.
11382
+ *
11383
+ * `updateFrom` accepts the same arguments as {@link Query.join}.
11384
+ *
11385
+ * ```ts
11386
+ * // save all author names to their books by using a relation name:
11387
+ * db.books.updateFrom('author').set({ authorName: (q) => q.ref('author.name') });
11388
+ *
11389
+ * // update from authors that match the condition:
11390
+ * db.books
11391
+ * .updateFrom((q) => q.author.where({ writingSkills: 'good' }))
11392
+ * .set({ authorName: (q) => q.ref('author.name') });
11393
+ *
11394
+ * // update from any table using custom `on` conditions:
11395
+ * db.books
11396
+ * .updateFrom(
11397
+ * () => db.authors,
11398
+ * (q) => q.on('authors.id', 'books.authorId'),
11399
+ * )
11400
+ * .set({ authorName: (q) => q.ref('author.name') });
11401
+ *
11402
+ * // conditions after `updateFrom` can reference both tables:
11403
+ * db.books
11404
+ * .updateFrom(() => db.authors)
11405
+ * .where({
11406
+ * 'authors.id': (q) => q.ref('books.authorId'),
11407
+ * })
11408
+ * .set({ authorName: (q) => q.ref('author.name') });
11409
+ *
11410
+ * // can join and use another table in between `updateFrom` and `set`:
11411
+ * db.books
11412
+ * .updateFrom('author')
11413
+ * .join('publisher')
11414
+ * .set({
11415
+ * authorName: (q) => q.ref('author.name'),
11416
+ * publisherName: (q) => q.ref('publisher.name'),
11417
+ * });
11418
+ *
11419
+ * // updating from a CTE
11420
+ * db.books
11421
+ * .with('a', () =>
11422
+ * db.authors.where({ writingSkills: 'good' }).select('id', 'name').limit(10),
11423
+ * )
11424
+ * .updateFrom('a', (q) => q.on('a.id', 'books.authorId'))
11425
+ * .set({ authorName: (q) => q.ref('author.name') });
11426
+ * ```
11427
+ */
11428
+ updateFrom(arg, ...args) {
11429
+ const q = _clone(this);
11430
+ const joinArgs = _joinReturningArgs(
11431
+ q,
11432
+ true,
11433
+ arg,
11434
+ args,
11435
+ // eslint-disable-line @typescript-eslint/no-explicit-any
11436
+ true
11437
+ );
11438
+ if (!joinArgs) {
11439
+ return _queryNone(q);
11440
+ }
11441
+ joinArgs.u = true;
11442
+ q.q.updateFrom = joinArgs;
11443
+ return q;
11444
+ }
11445
+ /**
11446
+ * Use after {@link updateFrom}
11447
+ */
11448
+ set(arg) {
11449
+ return _queryUpdate(_clone(this), arg);
11450
+ }
11291
11451
  /**
11292
11452
  * Increments a column by `1`, returns a count of updated records by default.
11293
11453
  *
@@ -11616,8 +11776,8 @@ function orCreate(query, data, updateData, mergeData) {
11616
11776
  const { handleResult } = q;
11617
11777
  let result;
11618
11778
  let created = false;
11619
- q.handleResult = (q2, t, r, s) => {
11620
- return created ? result : handleResult(q2, t, r, s);
11779
+ q.handleResult = (q2, t, r, s, i) => {
11780
+ return created ? result : handleResult(q2, t, r, s, i);
11621
11781
  };
11622
11782
  q.hookSelect = new Map(q.hookSelect);
11623
11783
  q.patchResult = async (q2, hookSelect, queryResult) => {
@@ -11656,7 +11816,7 @@ function orCreate(query, data, updateData, mergeData) {
11656
11816
  );
11657
11817
  let afterHooks;
11658
11818
  let afterCommitHooks;
11659
- q22.q.handleResult = (a, t, r, s) => {
11819
+ q22.q.handleResult = (a, t, r, s, i) => {
11660
11820
  if (hasAfterCallback || hasAfterCommitCallback) {
11661
11821
  const fieldName = r.fields[0].name;
11662
11822
  if (r.rows[0][fieldName]) {
@@ -11668,7 +11828,7 @@ function orCreate(query, data, updateData, mergeData) {
11668
11828
  }
11669
11829
  delete r.rows[0][fieldName];
11670
11830
  }
11671
- result = handleResult(a, t, r, s);
11831
+ result = handleResult(a, t, r, s, i);
11672
11832
  return a.q.hookSelect ? result.map((row) => ({ ...row })) : result;
11673
11833
  };
11674
11834
  q22.q.log = q2.q.log;
@@ -12992,15 +13152,6 @@ class Db extends QueryMethods {
12992
13152
  const self = this;
12993
13153
  const { softDelete } = options;
12994
13154
  const scopes = options.scopes || softDelete ? {} : orchidCore.emptyObject;
12995
- this.internal = {
12996
- transactionStorage,
12997
- scopes,
12998
- snakeCase: options.snakeCase,
12999
- noPrimaryKey: options.noPrimaryKey === "ignore",
13000
- comment: options.comment,
13001
- nowSQL: options.nowSQL,
13002
- tableData
13003
- };
13004
13155
  this.baseQuery = this;
13005
13156
  this.relations = {};
13006
13157
  this.relationQueries = {};
@@ -13010,6 +13161,7 @@ class Db extends QueryMethods {
13010
13161
  let modifyQuery = void 0;
13011
13162
  let prepareSelectAll = false;
13012
13163
  let hasHookSetters;
13164
+ let runtimeDefaultColumns;
13013
13165
  const { snakeCase } = options;
13014
13166
  for (const key in shape) {
13015
13167
  const column = shape[key];
@@ -13035,9 +13187,8 @@ class Db extends QueryMethods {
13035
13187
  modifyQuery = orchidCore.pushOrNewArray(modifyQuery, (q) => mq(q, column));
13036
13188
  }
13037
13189
  if (typeof column.data.default === "function") {
13038
- const arr = this.internal.runtimeDefaultColumns;
13039
- if (!arr) this.internal.runtimeDefaultColumns = [key];
13040
- else arr.push(key);
13190
+ if (!runtimeDefaultColumns) runtimeDefaultColumns = [key];
13191
+ else runtimeDefaultColumns.push(key);
13041
13192
  if (!column.data.runtimeDefault) {
13042
13193
  const {
13043
13194
  data: { default: def, encode }
@@ -13049,6 +13200,16 @@ class Db extends QueryMethods {
13049
13200
  hasHookSetters = true;
13050
13201
  }
13051
13202
  }
13203
+ this.internal = {
13204
+ runtimeDefaultColumns,
13205
+ transactionStorage,
13206
+ scopes,
13207
+ snakeCase: options.snakeCase,
13208
+ noPrimaryKey: options.noPrimaryKey === "ignore",
13209
+ comment: options.comment,
13210
+ nowSQL: options.nowSQL,
13211
+ tableData
13212
+ };
13052
13213
  this.q = {
13053
13214
  adapter,
13054
13215
  shape,
@@ -13056,7 +13217,7 @@ class Db extends QueryMethods {
13056
13217
  logger,
13057
13218
  log: logParamToLogObject(logger, options.log),
13058
13219
  autoPreparedStatements: options.autoPreparedStatements ?? false,
13059
- parsers: hasParsers ? parsers : void 0,
13220
+ defaultParsers: hasParsers ? parsers : void 0,
13060
13221
  language: options.language,
13061
13222
  schema: options?.schema
13062
13223
  };
@@ -13597,6 +13758,7 @@ exports._queryOr = _queryOr;
13597
13758
  exports._queryOrNot = _queryOrNot;
13598
13759
  exports._queryRows = _queryRows;
13599
13760
  exports._querySelect = _querySelect;
13761
+ exports._querySelectAll = _querySelectAll;
13600
13762
  exports._queryTake = _queryTake;
13601
13763
  exports._queryTakeOptional = _queryTakeOptional;
13602
13764
  exports._queryUnion = _queryUnion;