pqb 0.56.9 → 0.56.12

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
@@ -1080,6 +1080,9 @@ const quoteValue = (arg, ctx, quotedAs, IN) => {
1080
1080
  if ("toSQL" in arg) {
1081
1081
  return `(${getSqlText(arg.toSQL(ctx))})`;
1082
1082
  }
1083
+ if (!(arg instanceof Date) && !Array.isArray(arg)) {
1084
+ arg = JSON.stringify(arg);
1085
+ }
1083
1086
  }
1084
1087
  return orchidCore.addValue(ctx.values, arg);
1085
1088
  };
@@ -1766,6 +1769,9 @@ const defaultSchemaConfig = {
1766
1769
  narrowType() {
1767
1770
  return this;
1768
1771
  },
1772
+ narrowAllTypes() {
1773
+ return this;
1774
+ },
1769
1775
  dateAsNumber() {
1770
1776
  return this.parse(Date.parse);
1771
1777
  },
@@ -2591,7 +2597,7 @@ const columnToSql = (ctx, data, shape, column, quotedAs, select) => {
2591
2597
  );
2592
2598
  }
2593
2599
  if (!select && data.joinedShapes?.[column]) {
2594
- return `"${column}".r`;
2600
+ return `"${column}"."${column}"`;
2595
2601
  }
2596
2602
  return simpleColumnToSQL(ctx, column, shape[column], quotedAs);
2597
2603
  };
@@ -2601,7 +2607,7 @@ const maybeSelectedColumnToSql = (ctx, data, column, quotedAs) => {
2601
2607
  return columnWithDotToSql(ctx, data, data.shape, column, index, quotedAs);
2602
2608
  } else {
2603
2609
  if (data.joinedShapes?.[column]) {
2604
- return `"${column}".r`;
2610
+ return `"${column}"."${column}"`;
2605
2611
  }
2606
2612
  if (data.select) {
2607
2613
  for (const s of data.select) {
@@ -2906,7 +2912,7 @@ const processWhere = (ands, ctx, table, query, data, quotedAs) => {
2906
2912
  quotedColumn = simpleColumnToSQL(ctx, name, column, quoted);
2907
2913
  } else {
2908
2914
  column = query.joinedShapes?.[key]?.value;
2909
- quotedColumn = `"${key}".r`;
2915
+ quotedColumn = `"${key}"."${key}"`;
2910
2916
  }
2911
2917
  if (!column || !quotedColumn) {
2912
2918
  throw new Error(`Unknown column ${key} provided to condition`);
@@ -2971,6 +2977,7 @@ const pushIn = (ctx, query, ands, quotedAs, arg) => {
2971
2977
  const processJoinItem = (ctx, table, query, args, quotedAs) => {
2972
2978
  let target;
2973
2979
  let on;
2980
+ const forbidLateral = "u" in args;
2974
2981
  if ("l" in args) {
2975
2982
  const { aliasValue } = ctx;
2976
2983
  ctx.aliasValue = true;
@@ -2978,7 +2985,7 @@ const processJoinItem = (ctx, table, query, args, quotedAs) => {
2978
2985
  query,
2979
2986
  args.a
2980
2987
  )}"`;
2981
- on = `${args.i ? `"${args.a}".r IS NOT NULL` : "true"}`;
2988
+ on = `${args.i ? `"${args.a}"."${args.a}" IS NOT NULL` : "true"}`;
2982
2989
  ctx.aliasValue = aliasValue;
2983
2990
  } else if ("j" in args) {
2984
2991
  const { j, s, r } = args;
@@ -2991,7 +2998,7 @@ const processJoinItem = (ctx, table, query, args, quotedAs) => {
2991
2998
  target += ` ${joinAs}`;
2992
2999
  }
2993
3000
  if (r && s) {
2994
- target = `LATERAL ${subJoinToSql(ctx, j, quotedTable, joinAs, true)}`;
3001
+ target = subJoinToSql(ctx, j, quotedTable, !forbidLateral, joinAs, true);
2995
3002
  } else {
2996
3003
  on = whereToSql(ctx, j, j.q, joinAs);
2997
3004
  }
@@ -3001,7 +3008,7 @@ const processJoinItem = (ctx, table, query, args, quotedAs) => {
3001
3008
  if ("r" in args) {
3002
3009
  const { s, r } = args;
3003
3010
  if (s) {
3004
- target = `LATERAL ${subJoinToSql(ctx, r, target, target)}`;
3011
+ target = subJoinToSql(ctx, r, target, !forbidLateral, target);
3005
3012
  } else {
3006
3013
  on = whereToSql(ctx, r, r.q, target);
3007
3014
  }
@@ -3032,14 +3039,14 @@ const processJoinItem = (ctx, table, query, args, quotedAs) => {
3032
3039
  let joinAs;
3033
3040
  if ("r" in args) {
3034
3041
  const { r } = args;
3035
- const res = getArgQueryTarget(ctx, q, s, s);
3036
- target = s ? `LATERAL ${res.target}` : res.target;
3042
+ const res = getArgQueryTarget(ctx, q, s && !forbidLateral, s, s);
3043
+ target = res.target;
3037
3044
  joinAs = res.joinAs;
3038
- if (!s) {
3045
+ if (!s || forbidLateral) {
3039
3046
  on = whereToSql(ctx, r, r.q, `"${getQueryAs(r)}"`);
3040
3047
  }
3041
3048
  } else {
3042
- const res = getArgQueryTarget(ctx, q, s);
3049
+ const res = getArgQueryTarget(ctx, q, false, s);
3043
3050
  target = res.target;
3044
3051
  joinAs = res.joinAs;
3045
3052
  if ("a" in args) {
@@ -3068,7 +3075,7 @@ const processJoinItem = (ctx, table, query, args, quotedAs) => {
3068
3075
  }
3069
3076
  return { target, on };
3070
3077
  };
3071
- const getArgQueryTarget = (ctx, first, joinSubQuery, cloned) => {
3078
+ const getArgQueryTarget = (ctx, first, lateral, joinSubQuery, cloned) => {
3072
3079
  const joinQuery = first.q;
3073
3080
  const quotedFrom = typeof joinQuery.from === "string" ? `"${joinQuery.from}"` : void 0;
3074
3081
  let joinAs = quotedFrom || `"${first.table}"`;
@@ -3076,7 +3083,7 @@ const getArgQueryTarget = (ctx, first, joinSubQuery, cloned) => {
3076
3083
  const addAs = qAs && qAs !== joinAs;
3077
3084
  if (joinSubQuery) {
3078
3085
  return {
3079
- target: subJoinToSql(ctx, first, joinAs, qAs, cloned),
3086
+ target: subJoinToSql(ctx, first, joinAs, lateral, qAs, cloned),
3080
3087
  joinAs: addAs ? qAs : joinAs
3081
3088
  };
3082
3089
  } else {
@@ -3088,12 +3095,13 @@ const getArgQueryTarget = (ctx, first, joinSubQuery, cloned) => {
3088
3095
  return { target, joinAs };
3089
3096
  }
3090
3097
  };
3091
- const subJoinToSql = (ctx, jq, innerAs, outerAs, cloned) => {
3098
+ const subJoinToSql = (ctx, jq, innerAs, lateral, outerAs, cloned) => {
3092
3099
  if (!jq.q.select && jq.q.selectAllColumns) {
3093
3100
  if (!cloned) jq = jq.clone();
3094
3101
  jq.q.select = [new RawSQL(`${innerAs}.*`)];
3095
3102
  }
3096
- return `(${getSqlText(jq.toSQL(ctx))}) ${outerAs || innerAs}`;
3103
+ const sql = `(${getSqlText(jq.toSQL(ctx))}) ${outerAs || innerAs}`;
3104
+ return lateral ? `LATERAL ${sql}` : sql;
3097
3105
  };
3098
3106
  const processArgs = (args, ctx, query, joinAs, joinShape, quotedAs) => {
3099
3107
  return args.length ? args.length === 1 ? getObjectOrRawConditions(
@@ -3177,7 +3185,26 @@ const skipQueryKeysForSubQuery = {
3177
3185
  returnsOne: true,
3178
3186
  aliases: true,
3179
3187
  defaults: true,
3180
- transform: true
3188
+ transform: true,
3189
+ throwOnNotFound: true,
3190
+ before: true,
3191
+ after: true,
3192
+ beforeCreate: true,
3193
+ afterCreate: true,
3194
+ afterCreateCommit: true,
3195
+ afterCreateSelect: true,
3196
+ beforeUpdate: true,
3197
+ afterUpdate: true,
3198
+ afterUpdateCommit: true,
3199
+ afterUpdateSelect: true,
3200
+ beforeDelete: true,
3201
+ afterDelete: true,
3202
+ afterDeleteCommit: true,
3203
+ afterDeleteSelect: true,
3204
+ catchAfterCommitErrors: true,
3205
+ log: true,
3206
+ logger: true,
3207
+ autoPreparedStatements: true
3181
3208
  };
3182
3209
  const getIsJoinSubQuery = (query) => {
3183
3210
  const {
@@ -3192,14 +3219,14 @@ const getIsJoinSubQuery = (query) => {
3192
3219
  return false;
3193
3220
  };
3194
3221
 
3195
- const processJoinArgs = (joinTo, first, args, joinSubQuery, whereExists) => {
3222
+ const processJoinArgs = (joinTo, first, args, joinSubQuery, shape, whereExists, forbidLateral) => {
3196
3223
  if (typeof first === "string") {
3197
3224
  if (first in joinTo.relations) {
3198
3225
  const { query: toQuery, joinQuery } = joinTo.relations[first];
3199
3226
  const j = joinQuery(toQuery, joinTo);
3200
3227
  if (typeof args[0] === "function") {
3201
3228
  const r = args[0](
3202
- makeJoinQueryBuilder(j, j.q.joinedShapes, joinTo)
3229
+ makeJoinQueryBuilder(j, j.q.joinedShapes, joinTo, shape)
3203
3230
  );
3204
3231
  return {
3205
3232
  j: j.merge(r),
@@ -3220,7 +3247,7 @@ const processJoinArgs = (joinTo, first, args, joinSubQuery, whereExists) => {
3220
3247
  j.table = first;
3221
3248
  j.q = {
3222
3249
  shape: w.shape,
3223
- computeds: w.computeds,
3250
+ runtimeComputeds: w.computeds,
3224
3251
  adapter: joinToQ.adapter,
3225
3252
  handleResult: joinToQ.handleResult,
3226
3253
  returnType: "all",
@@ -3238,7 +3265,8 @@ const processJoinArgs = (joinTo, first, args, joinSubQuery, whereExists) => {
3238
3265
  ...j.q.joinedShapes,
3239
3266
  ...joinedShapes
3240
3267
  } : joinedShapes,
3241
- joinTo
3268
+ joinTo,
3269
+ shape
3242
3270
  )
3243
3271
  );
3244
3272
  return {
@@ -3250,7 +3278,7 @@ const processJoinArgs = (joinTo, first, args, joinSubQuery, whereExists) => {
3250
3278
  }
3251
3279
  const args0 = args.length ? args[0] : orchidCore.returnArg;
3252
3280
  if (typeof args0 === "function") {
3253
- const q = first;
3281
+ let q = first;
3254
3282
  if (q.joinQueryAfterCallback) {
3255
3283
  let base = q.baseQuery;
3256
3284
  if (q.q.as) {
@@ -3260,14 +3288,17 @@ const processJoinArgs = (joinTo, first, args, joinSubQuery, whereExists) => {
3260
3288
  base,
3261
3289
  joinTo
3262
3290
  );
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 };
3291
+ if (query.and || query.or || query.scopes) {
3292
+ q = _clone(q);
3293
+ if (query.and) {
3294
+ pushQueryArrayImmutable(q, "and", query.and);
3295
+ }
3296
+ if (query.or) {
3297
+ pushQueryArrayImmutable(q, "or", query.or);
3298
+ }
3299
+ if (query.scopes) {
3300
+ q.q.scopes = { ...q.q.scopes, ...query.scopes };
3301
+ }
3271
3302
  }
3272
3303
  }
3273
3304
  const joinedShapes = {
@@ -3281,11 +3312,16 @@ const processJoinArgs = (joinTo, first, args, joinSubQuery, whereExists) => {
3281
3312
  ...q.q.joinedShapes,
3282
3313
  ...joinedShapes
3283
3314
  } : joinedShapes,
3284
- joinTo
3315
+ joinTo,
3316
+ shape
3285
3317
  )
3286
3318
  );
3287
3319
  joinSubQuery || (joinSubQuery = getIsJoinSubQuery(r));
3288
- return { q: joinSubQuery ? q.merge(r) : q, r, s: joinSubQuery };
3320
+ return {
3321
+ q: joinSubQuery && !forbidLateral ? q.merge(r) : q,
3322
+ r,
3323
+ s: joinSubQuery
3324
+ };
3289
3325
  }
3290
3326
  return {
3291
3327
  q: first,
@@ -3301,12 +3337,15 @@ const preprocessJoinArg = (q, arg) => {
3301
3337
  arg.joinQueryAfterCallback = arg.joinQuery;
3302
3338
  return arg;
3303
3339
  };
3304
- const makeJoinQueryBuilder = (joinedQuery, joinedShapes, joinTo) => {
3340
+ const makeJoinQueryBuilder = (joinedQuery, joinedShapes, joinTo, shape) => {
3305
3341
  const q = joinedQuery.baseQuery.clone();
3306
3342
  q.baseQuery = q;
3307
3343
  q.q.as = joinedQuery.q.as;
3308
3344
  q.q.joinedShapes = joinedShapes;
3309
3345
  q.q.joinTo = joinTo;
3346
+ if (shape) {
3347
+ q.q.shape = shape;
3348
+ }
3310
3349
  return q;
3311
3350
  };
3312
3351
 
@@ -3326,14 +3365,23 @@ const noneMethods = {
3326
3365
  // It is `async` so it returns a chainable Promise.
3327
3366
  async then(resolve, reject) {
3328
3367
  try {
3329
- const result = noneResult(this, this.q, this.q.returnType);
3330
- resolve?.(result);
3368
+ let result = noneResult(this, this.q, this.q.returnType);
3369
+ if (this.q.transform) {
3370
+ result = orchidCore.applyTransforms(
3371
+ this.q,
3372
+ this.q.returnType,
3373
+ this.q.transform,
3374
+ result
3375
+ );
3376
+ }
3377
+ return resolve?.(result);
3331
3378
  } catch (err) {
3332
- reject?.(err);
3379
+ return reject?.(err);
3333
3380
  }
3334
3381
  },
3335
- // `catch` returns a Promise, so it is chainable with then/catch.
3336
- catch: () => new Promise(orchidCore.noop)
3382
+ catch(reject) {
3383
+ return this.then(void 0, reject);
3384
+ }
3337
3385
  };
3338
3386
  const _queryNone = (q) => {
3339
3387
  if (isQueryNone(q)) return q;
@@ -3480,6 +3528,7 @@ const existsArgs = (self, q, args) => {
3480
3528
  preprocessJoinArg(self, q),
3481
3529
  args,
3482
3530
  false,
3531
+ void 0,
3483
3532
  true
3484
3533
  );
3485
3534
  return [
@@ -4320,7 +4369,7 @@ const getFullColumnTable = (q, column, index, as) => {
4320
4369
  return as && table !== as && orchidCore._checkIfAliased(q, table, as) ? as : table;
4321
4370
  };
4322
4371
 
4323
- const _join = (query, require, type, first, args) => {
4372
+ const _joinReturningArgs = (query, require, first, args, forbidLateral) => {
4324
4373
  let joinKey;
4325
4374
  let shape;
4326
4375
  let parsers;
@@ -4335,7 +4384,7 @@ const _join = (query, require, type, first, args) => {
4335
4384
  first = first._internalJoin;
4336
4385
  }
4337
4386
  if (require && isQueryNone(first)) {
4338
- return _queryNone(query);
4387
+ return;
4339
4388
  }
4340
4389
  const q = first;
4341
4390
  if (!isInternalJoin) {
@@ -4344,9 +4393,9 @@ const _join = (query, require, type, first, args) => {
4344
4393
  joinKey = q.q.as || q.table;
4345
4394
  if (joinKey) {
4346
4395
  shape = getShapeFromSelect(q, joinSubQuery && !!q.q.select);
4347
- parsers = q.q.parsers;
4396
+ parsers = orchidCore.getQueryParsers(q);
4348
4397
  batchParsers = q.q.batchParsers;
4349
- computeds = q.q.computeds;
4398
+ computeds = q.q.runtimeComputeds;
4350
4399
  if (joinSubQuery) {
4351
4400
  first = q.clone();
4352
4401
  first.shape = shape;
@@ -4358,9 +4407,9 @@ const _join = (query, require, type, first, args) => {
4358
4407
  if (relation) {
4359
4408
  shape = getShapeFromSelect(relation.query);
4360
4409
  const r = relation.query;
4361
- parsers = r.q.parsers;
4410
+ parsers = orchidCore.getQueryParsers(r);
4362
4411
  batchParsers = r.q.batchParsers;
4363
- computeds = r.q.computeds;
4412
+ computeds = r.q.runtimeComputeds;
4364
4413
  } else {
4365
4414
  const w = query.q.withShapes?.[joinKey];
4366
4415
  shape = w?.shape;
@@ -4378,18 +4427,23 @@ const _join = (query, require, type, first, args) => {
4378
4427
  query,
4379
4428
  first,
4380
4429
  args,
4381
- joinSubQuery
4430
+ joinSubQuery,
4431
+ shape,
4432
+ false,
4433
+ forbidLateral
4382
4434
  );
4383
4435
  if (require && "r" in joinArgs && isQueryNone(joinArgs.r)) {
4384
- return _queryNone(query);
4436
+ return;
4385
4437
  } else if (joinKey && "s" in joinArgs && joinArgs.s) {
4386
4438
  const j = "j" in joinArgs ? joinArgs.r ?? joinArgs.j : "r" in joinArgs ? joinArgs.r : joinArgs.q;
4387
4439
  const jq = j.q;
4388
4440
  if (jq.select || !jq.selectAllColumns) {
4389
4441
  const { q } = query;
4390
- const shape2 = getShapeFromSelect(j, true);
4391
- orchidCore.setObjectValueImmutable(q, "joinedShapes", joinKey, shape2);
4392
- orchidCore.setObjectValueImmutable(q, "joinedParsers", joinKey, jq.parsers);
4442
+ if ("r" in joinArgs && joinArgs.r) {
4443
+ joinArgs.c = shape = getShapeFromSelect(j, true);
4444
+ }
4445
+ orchidCore.setObjectValueImmutable(q, "joinedShapes", joinKey, shape);
4446
+ orchidCore.setObjectValueImmutable(q, "joinedParsers", joinKey, orchidCore.getQueryParsers(j));
4393
4447
  if (jq.batchParsers) {
4394
4448
  orchidCore.setObjectValueImmutable(
4395
4449
  jq,
@@ -4398,7 +4452,12 @@ const _join = (query, require, type, first, args) => {
4398
4452
  jq.batchParsers
4399
4453
  );
4400
4454
  }
4401
- orchidCore.setObjectValueImmutable(q, "joinedComputeds", joinKey, jq.computeds);
4455
+ orchidCore.setObjectValueImmutable(
4456
+ q,
4457
+ "joinedComputeds",
4458
+ joinKey,
4459
+ jq.runtimeComputeds
4460
+ );
4402
4461
  } else {
4403
4462
  addAllShapesAndParsers(
4404
4463
  query,
@@ -4419,6 +4478,13 @@ const _join = (query, require, type, first, args) => {
4419
4478
  computeds
4420
4479
  );
4421
4480
  }
4481
+ return joinArgs;
4482
+ };
4483
+ const _join = (query, require, type, first, args) => {
4484
+ const joinArgs = _joinReturningArgs(query, require, first, args);
4485
+ if (!joinArgs) {
4486
+ return _queryNone(query);
4487
+ }
4422
4488
  orchidCore.pushQueryValueImmutable(query, "join", {
4423
4489
  type,
4424
4490
  args: joinArgs
@@ -4484,7 +4550,12 @@ const _joinLateral = (self, type, arg, as, innerJoinLateral) => {
4484
4550
  if (joinKey) {
4485
4551
  const shape = getShapeFromSelect(arg, true);
4486
4552
  orchidCore.setObjectValueImmutable(q.q, "joinedShapes", joinKey, shape);
4487
- orchidCore.setObjectValueImmutable(q.q, "joinedParsers", joinKey, arg.q.parsers);
4553
+ orchidCore.setObjectValueImmutable(
4554
+ q.q,
4555
+ "joinedParsers",
4556
+ joinKey,
4557
+ orchidCore.getQueryParsers(arg)
4558
+ );
4488
4559
  if (arg.q.batchParsers) {
4489
4560
  orchidCore.setObjectValueImmutable(
4490
4561
  q.q,
@@ -4495,12 +4566,39 @@ const _joinLateral = (self, type, arg, as, innerJoinLateral) => {
4495
4566
  }
4496
4567
  }
4497
4568
  as || (as = getQueryAs(arg));
4498
- orchidCore.setObjectValueImmutable(q.q, "joinedComputeds", as, arg.q.computeds);
4569
+ orchidCore.setObjectValueImmutable(q.q, "joinedComputeds", as, arg.q.runtimeComputeds);
4570
+ const joinArgs = {
4571
+ l: arg,
4572
+ a: as,
4573
+ i: innerJoinLateral
4574
+ };
4575
+ if (arg.q.returnType === "value" || arg.q.returnType === "valueOrThrow") {
4576
+ const map = q.q.joinValueDedup ? new Map(q.q.joinValueDedup) : /* @__PURE__ */ new Map();
4577
+ q.q.joinValueDedup = map;
4578
+ const select = arg.q.select[0];
4579
+ arg.q.select = [];
4580
+ const dedupKey = getSqlText(arg.toSQL());
4581
+ const existing = map.get(dedupKey);
4582
+ if (existing) {
4583
+ existing.q.q.select = [
4584
+ {
4585
+ selectAs: {
4586
+ ...existing.q.q.select[0].selectAs,
4587
+ [joinKey]: select
4588
+ }
4589
+ }
4590
+ ];
4591
+ return existing.a;
4592
+ } else {
4593
+ arg.q.select = [{ selectAs: { [joinKey]: select } }];
4594
+ map.set(dedupKey, { q: arg, a: as });
4595
+ }
4596
+ }
4499
4597
  orchidCore.pushQueryValueImmutable(q, "join", {
4500
4598
  type: `${type} LATERAL`,
4501
- args: { l: arg, a: as, i: innerJoinLateral }
4599
+ args: joinArgs
4502
4600
  });
4503
- return q;
4601
+ return joinKey;
4504
4602
  };
4505
4603
 
4506
4604
  const escape = (value, migration, nested) => {
@@ -4880,6 +4978,7 @@ class ComputedColumn {
4880
4978
  const computeAtRuntime = (deps, fn) => new ComputedColumn("one", deps, fn);
4881
4979
  const computeBatchAtRuntime = (deps, fn) => new ComputedColumn("many", deps, fn);
4882
4980
  const applyComputedColumns = (q, fn) => {
4981
+ var _a;
4883
4982
  q.computeAtRuntime = computeAtRuntime;
4884
4983
  q.computeBatchAtRuntime = computeBatchAtRuntime;
4885
4984
  const computed = fn(q);
@@ -4887,8 +4986,8 @@ const applyComputedColumns = (q, fn) => {
4887
4986
  let item = computed[key];
4888
4987
  if (typeof item === "function") item = item.call(computed);
4889
4988
  if (item instanceof ComputedColumn) {
4890
- q.q.computeds = {
4891
- ...q.q.computeds,
4989
+ q.q.runtimeComputeds = {
4990
+ ...q.q.runtimeComputeds,
4892
4991
  [key]: item
4893
4992
  };
4894
4993
  } else {
@@ -4904,11 +5003,10 @@ const applyComputedColumns = (q, fn) => {
4904
5003
  data.computed = item;
4905
5004
  data.explicitSelect = true;
4906
5005
  data.readOnly = true;
4907
- addColumnParserToQuery(
4908
- q.q,
4909
- key,
4910
- item.result.value
4911
- );
5006
+ const parse = item.result.value._parse;
5007
+ if (parse) {
5008
+ ((_a = q.q).defaultParsers ?? (_a.defaultParsers = {}))[key] = parse;
5009
+ }
4912
5010
  }
4913
5011
  }
4914
5012
  q.computeAtRuntime = q.computeBatchAtRuntime = void 0;
@@ -5117,7 +5215,7 @@ const then = async (q, adapter, trx, beforeHooks, afterHooks, afterCommitHooks,
5117
5215
  )
5118
5216
  );
5119
5217
  }
5120
- sql = q.toSQL();
5218
+ const localSql = sql = q.toSQL();
5121
5219
  const { hookSelect, delayedRelationSelect } = sql;
5122
5220
  const { returnType = "all" } = query;
5123
5221
  const tempReturnType = hookSelect || returnType === "rows" && q.q.batchParsers || delayedRelationSelect?.value ? "all" : returnType;
@@ -5142,7 +5240,7 @@ const then = async (q, adapter, trx, beforeHooks, afterHooks, afterCommitHooks,
5142
5240
  if (query.patchResult) {
5143
5241
  await query.patchResult(q, hookSelect, queryResult);
5144
5242
  }
5145
- result = query.handleResult(q, tempReturnType, queryResult);
5243
+ result = query.handleResult(q, tempReturnType, queryResult, localSql);
5146
5244
  } else {
5147
5245
  const queryMethod = queryMethodByReturnType[tempReturnType];
5148
5246
  const queryBatch = async (batch) => {
@@ -5180,10 +5278,7 @@ const then = async (q, adapter, trx, beforeHooks, afterHooks, afterCommitHooks,
5180
5278
  if (query.patchResult) {
5181
5279
  await query.patchResult(q, hookSelect, queryResult);
5182
5280
  }
5183
- result = query.handleResult(q, tempReturnType, queryResult);
5184
- }
5185
- if (result && typeof result === "object" && typeof result.then === "function") {
5186
- result = await result;
5281
+ result = query.handleResult(q, tempReturnType, queryResult, localSql);
5187
5282
  }
5188
5283
  let tempColumns;
5189
5284
  let renames;
@@ -5207,8 +5302,8 @@ const then = async (q, adapter, trx, beforeHooks, afterHooks, afterCommitHooks,
5207
5302
  }
5208
5303
  }
5209
5304
  if (query.selectedComputeds) {
5210
- const promise = processComputedResult(query, result);
5211
- if (promise) await promise;
5305
+ const promise2 = processComputedResult(query, result);
5306
+ if (promise2) await promise2;
5212
5307
  }
5213
5308
  }
5214
5309
  const hasAfterHook = afterHooks || afterCommitHooks || query.after;
@@ -5265,19 +5360,15 @@ const then = async (q, adapter, trx, beforeHooks, afterHooks, afterCommitHooks,
5265
5360
  );
5266
5361
  const selectQuery = q2.clone();
5267
5362
  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 };
5363
+ const matchSourceTableIds = {};
5364
+ for (const pkey of primaryKeys) {
5365
+ matchSourceTableIds[pkey] = {
5366
+ in: result.map((row) => row[pkey])
5367
+ };
5280
5368
  }
5369
+ ((_a = selectQuery.q).and ?? (_a.and = [])).push(matchSourceTableIds);
5370
+ const relationsSelect = delayedRelationSelect.value;
5371
+ const selectAs = { ...relationsSelect };
5281
5372
  const select = [{ selectAs }];
5282
5373
  const relationKeyAliases = primaryKeys.map((key) => {
5283
5374
  if (key in selectAs) {
@@ -5301,16 +5392,30 @@ const then = async (q, adapter, trx, beforeHooks, afterHooks, afterCommitHooks,
5301
5392
  Object.assign(row, relationRow);
5302
5393
  }
5303
5394
  }
5395
+ if (renames) {
5396
+ for (const key in relationsSelect) {
5397
+ if (key in renames) {
5398
+ delete renames[key];
5399
+ }
5400
+ }
5401
+ }
5304
5402
  }
5403
+ const promise = parseBatch(q, queryResult, delayedRelationSelect);
5404
+ if (promise) await promise;
5305
5405
  if (hookSelect || tempReturnType !== returnType) {
5306
5406
  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;
5407
+ const renamedResult = Array.from({
5408
+ length: result.length
5409
+ });
5410
+ for (let i = 0, len = result.length; i < len; ++i) {
5411
+ const record = result[i];
5412
+ const renamedRecord = renamedResult[i] = { ...record };
5413
+ for (const a in renames) {
5414
+ renamedRecord[a] = record[renames[a]];
5415
+ renamedRecord[renames[a]] = record[a];
5312
5416
  }
5313
5417
  }
5418
+ result = renamedResult;
5314
5419
  }
5315
5420
  result = filterResult(
5316
5421
  q,
@@ -5364,68 +5469,46 @@ const execQuery = (adapter, method, sql) => {
5364
5469
  return result;
5365
5470
  });
5366
5471
  };
5367
- const handleResult = (q, returnType, result, isSubQuery) => {
5368
- const { parsers } = q.q;
5472
+ const handleResult = (q, returnType, result, sql, isSubQuery) => {
5473
+ const parsers = orchidCore.getQueryParsers(q, sql.hookSelect);
5369
5474
  switch (returnType) {
5370
5475
  case "all": {
5371
5476
  if (q.q.throwOnNotFound && result.rows.length === 0)
5372
5477
  throw new orchidCore.NotFoundError(q);
5373
- const promise = parseBatch(q, result);
5374
5478
  const { rows } = result;
5375
5479
  if (parsers) {
5376
5480
  for (const row of rows) {
5377
5481
  parseRecord(parsers, row);
5378
5482
  }
5379
5483
  }
5380
- return promise ? promise.then(() => rows) : rows;
5484
+ return rows;
5381
5485
  }
5382
5486
  case "one": {
5383
5487
  const { rows } = result;
5384
5488
  if (!rows.length) return;
5385
- const promise = parseBatch(q, result);
5386
5489
  if (parsers) parseRecord(parsers, rows[0]);
5387
- return promise ? promise.then(() => rows[0]) : rows[0];
5490
+ return rows[0];
5388
5491
  }
5389
5492
  case "oneOrThrow": {
5390
5493
  const { rows } = result;
5391
5494
  if (!rows.length) throw new orchidCore.NotFoundError(q);
5392
- const promise = parseBatch(q, result);
5393
5495
  if (parsers) parseRecord(parsers, rows[0]);
5394
- return promise ? promise.then(() => rows[0]) : rows[0];
5496
+ return rows[0];
5395
5497
  }
5396
5498
  case "rows": {
5397
5499
  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) {
5500
+ if (parsers) {
5405
5501
  parseRows(parsers, result.fields, rows);
5406
5502
  }
5407
5503
  return rows;
5408
5504
  }
5409
5505
  case "pluck": {
5410
5506
  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
5507
  parsePluck(parsers, isSubQuery, rows);
5419
5508
  return rows;
5420
5509
  }
5421
5510
  case "value": {
5422
5511
  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
5512
  return rows[0]?.[0] !== void 0 ? parseValue(rows[0][0], parsers) : q.q.notFoundDefault;
5430
5513
  }
5431
5514
  case "valueOrThrow": {
@@ -5436,13 +5519,6 @@ const handleResult = (q, returnType, result, isSubQuery) => {
5436
5519
  return result.rowCount;
5437
5520
  }
5438
5521
  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
5522
  if (rows[0]?.[0] === void 0) throw new orchidCore.NotFoundError(q);
5447
5523
  return parseValue(rows[0][0], parsers);
5448
5524
  }
@@ -5451,9 +5527,9 @@ const handleResult = (q, returnType, result, isSubQuery) => {
5451
5527
  }
5452
5528
  }
5453
5529
  };
5454
- const parseBatch = (q, queryResult) => {
5530
+ const parseBatch = (q, queryResult, delayedRelationSelect) => {
5455
5531
  let promises;
5456
- if (q.q.batchParsers) {
5532
+ if (q.q.batchParsers && !delayedRelationSelect?.value) {
5457
5533
  for (const parser of q.q.batchParsers) {
5458
5534
  const res = parser.fn(parser.path, queryResult);
5459
5535
  if (res) (promises ?? (promises = [])).push(res);
@@ -5566,44 +5642,46 @@ const filterAllResult = (result, tempColumns, hasAfterHook) => {
5566
5642
  return result;
5567
5643
  };
5568
5644
 
5645
+ const addWithParsers = (w, parsers) => {
5646
+ for (const key in w.shape) {
5647
+ const { _parse } = w.shape[key];
5648
+ if (_parse) parsers[key] = _parse;
5649
+ }
5650
+ };
5569
5651
  function queryFrom(self, arg) {
5570
5652
  const data = self.q;
5571
5653
  if (typeof arg === "string") {
5572
5654
  data.as || (data.as = arg);
5573
5655
  const w = data.withShapes?.[arg];
5574
5656
  data.shape = w?.shape ?? anyShape;
5575
- data.computeds = w?.computeds;
5576
- } else if (orchidCore.isExpression(arg)) {
5577
- data.as || (data.as = "t");
5657
+ data.runtimeComputeds = w?.computeds;
5658
+ const parsers = {};
5659
+ data.defaultParsers = parsers;
5660
+ if (w) addWithParsers(w, parsers);
5578
5661
  } else if (Array.isArray(arg)) {
5579
5662
  const { shape } = data;
5580
- let clonedParsers = false;
5663
+ const joinedParsers = {};
5581
5664
  for (const item of arg) {
5582
5665
  if (typeof item === "string") {
5583
5666
  const w = data.withShapes[item];
5584
5667
  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
- }
5668
+ if (w.computeds)
5669
+ data.runtimeComputeds = { ...data.runtimeComputeds, ...w.computeds };
5670
+ const parsers = {};
5671
+ joinedParsers[item] = parsers;
5672
+ addWithParsers(w, parsers);
5593
5673
  } else if (!orchidCore.isExpression(item)) {
5594
5674
  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);
5675
+ const key = getQueryAs(item);
5676
+ joinedParsers[key] = orchidCore.getQueryParsers(item);
5600
5677
  }
5601
5678
  }
5679
+ data.joinedParsers = joinedParsers;
5602
5680
  } else {
5603
5681
  const q = arg;
5604
5682
  data.as || (data.as = q.q.as || q.table || "t");
5605
5683
  data.shape = getShapeFromSelect(q, true);
5606
- data.parsers = q.q.parsers;
5684
+ data.defaultParsers = orchidCore.getQueryParsers(q);
5607
5685
  data.batchParsers = q.q.batchParsers;
5608
5686
  }
5609
5687
  data.from = arg;
@@ -5716,7 +5794,7 @@ const addParsersForSelectJoined = (q, arg, as = arg) => {
5716
5794
  }
5717
5795
  };
5718
5796
  const addParserForSelectItem = (q, as, key, arg, columnAlias, joinQuery) => {
5719
- if (typeof arg === "object" || typeof arg === "function") {
5797
+ if (typeof arg === "object") {
5720
5798
  const { q: query } = arg;
5721
5799
  if (query.batchParsers) {
5722
5800
  pushQueryArrayImmutable(
@@ -5728,7 +5806,8 @@ const addParserForSelectItem = (q, as, key, arg, columnAlias, joinQuery) => {
5728
5806
  }))
5729
5807
  );
5730
5808
  }
5731
- if (query.hookSelect || query.parsers || query.transform || query.returnType === "oneOrThrow" || query.returnType === "valueOrThrow" || query.returnType === "one" || query.returnType === "value") {
5809
+ const parsers = orchidCore.isExpression(arg) ? void 0 : orchidCore.getQueryParsers(arg);
5810
+ if (parsers || query.hookSelect || query.transform || query.returnType === "oneOrThrow" || query.returnType === "valueOrThrow" || query.returnType === "one" || query.returnType === "value") {
5732
5811
  orchidCore.pushQueryValueImmutable(q, "batchParsers", {
5733
5812
  path: [key],
5734
5813
  fn: (path, queryResult) => {
@@ -5752,7 +5831,6 @@ const addParserForSelectItem = (q, as, key, arg, columnAlias, joinQuery) => {
5752
5831
  collectNestedSelectBatches(batches, rows, path, last);
5753
5832
  switch (returnType) {
5754
5833
  case "all": {
5755
- const { parsers } = query;
5756
5834
  if (parsers) {
5757
5835
  for (const { data } of batches) {
5758
5836
  for (const one of data) {
@@ -5764,7 +5842,6 @@ const addParserForSelectItem = (q, as, key, arg, columnAlias, joinQuery) => {
5764
5842
  }
5765
5843
  case "one":
5766
5844
  case "oneOrThrow": {
5767
- const { parsers } = query;
5768
5845
  if (parsers) {
5769
5846
  if (returnType === "one") {
5770
5847
  for (const batch of batches) {
@@ -5795,7 +5872,7 @@ const addParserForSelectItem = (q, as, key, arg, columnAlias, joinQuery) => {
5795
5872
  break;
5796
5873
  }
5797
5874
  case "pluck": {
5798
- const parse = query.parsers?.pluck;
5875
+ const parse = parsers?.pluck;
5799
5876
  if (parse) {
5800
5877
  for (const { data } of batches) {
5801
5878
  for (let i = 0; i < data.length; i++) {
@@ -5808,7 +5885,7 @@ const addParserForSelectItem = (q, as, key, arg, columnAlias, joinQuery) => {
5808
5885
  case "value":
5809
5886
  case "valueOrThrow": {
5810
5887
  const notNullable = !query.getColumn?.data.isNullable;
5811
- const parse = query.parsers?.[orchidCore.getValueKey];
5888
+ const parse = parsers?.[orchidCore.getValueKey];
5812
5889
  if (parse) {
5813
5890
  if (returnType === "value") {
5814
5891
  for (const item of batches) {
@@ -5979,12 +6056,7 @@ const processSelectArg = (q, as, arg, columnAs) => {
5979
6056
  subQuery = value;
5980
6057
  }
5981
6058
  }
5982
- value.q.joinedForSelect = orchidCore._copyQueryAliasToQuery(
5983
- value,
5984
- q,
5985
- key
5986
- );
5987
- _joinLateral(
6059
+ const as2 = _joinLateral(
5988
6060
  q,
5989
6061
  innerJoinLateral ? "JOIN" : "LEFT JOIN",
5990
6062
  subQuery,
@@ -5993,6 +6065,13 @@ const processSelectArg = (q, as, arg, columnAs) => {
5993
6065
  // `JOIN` will handle it on itself.
5994
6066
  innerJoinLateral && returnType !== "one" && returnType !== "oneOrThrow"
5995
6067
  );
6068
+ if (as2) {
6069
+ value.q.joinedForSelect = orchidCore._copyQueryAliasToQuery(
6070
+ value,
6071
+ q,
6072
+ as2
6073
+ );
6074
+ }
5996
6075
  }
5997
6076
  }
5998
6077
  selectAs[key] = addParserForSelectItem(
@@ -6039,31 +6118,30 @@ const setParserForSelectedString = (query, arg, as, columnAs, columnAlias) => {
6039
6118
  const computeds = q.joinedComputeds?.[table];
6040
6119
  if (computeds?.[column]) {
6041
6120
  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
- }
6121
+ orchidCore._addToHookSelectWithTable(query, computed.deps, table);
6046
6122
  orchidCore.setObjectValueImmutable(q, "selectedComputeds", column, computed);
6047
6123
  return;
6048
6124
  }
6049
6125
  return arg;
6050
6126
  };
6051
6127
  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;
6128
+ if (key === "*") {
6129
+ const { defaultParsers } = query.q;
6130
+ if (defaultParsers) {
6131
+ orchidCore.spreadObjectValues(query.q, "parsers", defaultParsers);
6132
+ }
6133
+ } else {
6134
+ const parser = query.q.defaultParsers?.[key];
6135
+ if (parser) orchidCore.setObjectValueImmutable(q, "parsers", columnAs || key, parser);
6136
+ if (q.runtimeComputeds?.[key]) {
6137
+ const computed = q.runtimeComputeds[key];
6138
+ orchidCore._addToHookSelect(query, computed.deps);
6139
+ query.q.selectedComputeds = {
6140
+ ...query.q.selectedComputeds,
6141
+ [columnAlias || key]: computed
6142
+ };
6143
+ return;
6144
+ }
6067
6145
  }
6068
6146
  return key;
6069
6147
  };
@@ -6118,7 +6196,7 @@ const getShapeFromSelect = (q, isSubQuery) => {
6118
6196
  const { returnType } = it.q;
6119
6197
  if (returnType === "value" || returnType === "valueOrThrow") {
6120
6198
  const type = it.q.getColumn;
6121
- result[key] = type || UnknownColumn.instance;
6199
+ result[key] = type ? mapSubSelectColumn(type, isSubQuery) : UnknownColumn.instance;
6122
6200
  } else {
6123
6201
  result[key] = new JSONTextColumn(defaultSchemaConfig);
6124
6202
  }
@@ -6196,6 +6274,11 @@ function _querySelect(q, args) {
6196
6274
  }
6197
6275
  return pushQueryArrayImmutable(q, "select", selectArgs);
6198
6276
  }
6277
+ const _querySelectAll = (query) => {
6278
+ const q = query;
6279
+ q.q.select = ["*"];
6280
+ q.q.parsers = q.q.defaultParsers;
6281
+ };
6199
6282
  class Select {
6200
6283
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
6201
6284
  select(...args) {
@@ -6219,7 +6302,7 @@ class Select {
6219
6302
  */
6220
6303
  selectAll() {
6221
6304
  const q = _clone(this);
6222
- q.q.select = ["*"];
6305
+ _querySelectAll(q);
6223
6306
  if (q.q.returning) {
6224
6307
  q.q.returnType = q.q.returningMany ? "all" : "oneOrThrow";
6225
6308
  q.q.returning = void 0;
@@ -7070,13 +7153,13 @@ const selectToSql = (ctx, table, query, quotedAs, hookSelect = query.hookSelect,
7070
7153
  };
7071
7154
  function selectedObjectToSQL(ctx, quotedAs, item) {
7072
7155
  const sql = item.toSQL(ctx, quotedAs);
7073
- return ctx.aliasValue ? `${sql} r` : sql;
7156
+ return ctx.aliasValue ? `${sql} "${quotedAs}"` : sql;
7074
7157
  }
7075
7158
  const selectAllSql = (query, quotedAs, jsonList) => {
7076
7159
  if (jsonList) {
7077
7160
  Object.assign(jsonList, query.selectAllShape);
7078
7161
  }
7079
- return query.join?.length ? query.selectAllColumns?.map((item) => `${quotedAs}.${item}`).join(", ") || `${quotedAs}.*` : query.selectAllColumns?.join(", ") || "*";
7162
+ return query.join?.length || query.updateFrom ? query.selectAllColumns?.map((item) => `${quotedAs}.${item}`).join(", ") || `${quotedAs}.*` : query.selectAllColumns?.join(", ") || "*";
7080
7163
  };
7081
7164
  const pushSubQuerySql = (ctx, mainQuery, query, as, list, quotedAs, aliases) => {
7082
7165
  const { returnType = "all" } = query.q;
@@ -7118,14 +7201,14 @@ const pushSubQuerySql = (ctx, mainQuery, query, as, list, quotedAs, aliases) =>
7118
7201
  break;
7119
7202
  }
7120
7203
  case "all":
7121
- case "pluck":
7122
7204
  case "value":
7205
+ case "pluck":
7123
7206
  case "rows":
7124
- sql = `"${query.q.joinedForSelect}".r`;
7207
+ sql = `"${query.q.joinedForSelect}"."${as}"`;
7125
7208
  break;
7126
7209
  case "valueOrThrow":
7127
7210
  if (query.q.returning) return;
7128
- sql = `"${query.q.joinedForSelect}".r`;
7211
+ sql = `"${query.q.joinedForSelect}"."${as}"`;
7129
7212
  break;
7130
7213
  case "void":
7131
7214
  return;
@@ -7147,7 +7230,7 @@ const pushSubQuerySql = (ctx, mainQuery, query, as, list, quotedAs, aliases) =>
7147
7230
  case "pluck": {
7148
7231
  const { select } = query.q;
7149
7232
  const first = select?.[0];
7150
- if (!first && query.q.computeds?.[as]) {
7233
+ if (!first && query.q.runtimeComputeds?.[as]) {
7151
7234
  query = queryJson(query);
7152
7235
  } else if (!first) {
7153
7236
  throw new orchidCore.OrchidOrmInternalError(
@@ -7164,7 +7247,7 @@ const pushSubQuerySql = (ctx, mainQuery, query, as, list, quotedAs, aliases) =>
7164
7247
  }
7165
7248
  case "value":
7166
7249
  case "valueOrThrow":
7167
- if (!query.q.returning && query.q.computeds?.[as]) {
7250
+ if (!query.q.returning && query.q.runtimeComputeds?.[as]) {
7168
7251
  query = queryJson(query);
7169
7252
  }
7170
7253
  break;
@@ -7276,9 +7359,6 @@ const pushFromAndAs = (ctx, table, data, quotedAs) => {
7276
7359
  let sql = "FROM ";
7277
7360
  const from = getFrom(ctx, table, data, quotedAs);
7278
7361
  sql += from;
7279
- if (data.as && quotedAs && quotedAs !== from) {
7280
- sql += ` ${quotedAs}`;
7281
- }
7282
7362
  for (const as in data.sources) {
7283
7363
  const source = data.sources[as];
7284
7364
  const lang = getSearchLang(ctx, data, source, quotedAs);
@@ -7325,6 +7405,9 @@ const getFrom = (ctx, table, data, quotedAs) => {
7325
7405
  return fromToSql(ctx, data, from, quotedAs);
7326
7406
  }
7327
7407
  let sql = quoteSchemaAndTable(data.schema, table.table);
7408
+ if (data.as && quotedAs && quotedAs !== sql) {
7409
+ sql += ` ${quotedAs}`;
7410
+ }
7328
7411
  if (data.only) sql = `ONLY ${sql}`;
7329
7412
  return sql;
7330
7413
  };
@@ -7333,13 +7416,13 @@ const fromToSql = (ctx, data, from, quotedAs) => {
7333
7416
  let sql;
7334
7417
  if (typeof from === "object") {
7335
7418
  if (orchidCore.isExpression(from)) {
7336
- sql = from.toSQL(ctx, quotedAs);
7419
+ sql = from.toSQL(ctx, quotedAs) + " " + quotedAs;
7337
7420
  } else {
7338
7421
  only = from.q.only;
7339
7422
  if (!from.table) {
7340
7423
  sql = `(${getSqlText(toSQL(from, ctx))})`;
7341
7424
  } else if (!checkIfASimpleQuery(from)) {
7342
- sql = `(${getSqlText(toSQL(from, ctx))})`;
7425
+ sql = `(${getSqlText(toSQL(from, ctx))}) ${quotedAs || `"${getQueryAs(from)}"`}`;
7343
7426
  } else {
7344
7427
  sql = quoteSchemaAndTable(from.q.schema, from.table);
7345
7428
  }
@@ -7457,7 +7540,45 @@ const pushUpdateSql = (ctx, table, query, quotedAs) => {
7457
7540
  }
7458
7541
  ctx.sql.push("SET");
7459
7542
  ctx.sql.push(set.join(", "));
7460
- pushWhereStatementSql(ctx, table, query, quotedAs);
7543
+ const { updateFrom } = query;
7544
+ let fromWhereSql;
7545
+ if (updateFrom) {
7546
+ const { target, on } = processJoinItem(
7547
+ ctx,
7548
+ table,
7549
+ query,
7550
+ updateFrom,
7551
+ quotedAs
7552
+ );
7553
+ ctx.sql.push(`FROM ${target}`);
7554
+ fromWhereSql = on;
7555
+ if (query.join) {
7556
+ const joinSet = query.join.length > 1 ? /* @__PURE__ */ new Set() : null;
7557
+ for (const item of query.join) {
7558
+ const { target: target2, on: on2 } = processJoinItem(
7559
+ ctx,
7560
+ table,
7561
+ query,
7562
+ item.args,
7563
+ quotedAs
7564
+ );
7565
+ if (joinSet) {
7566
+ const key = `${item.type}${target2}${on2}`;
7567
+ if (joinSet.has(key)) continue;
7568
+ joinSet.add(key);
7569
+ }
7570
+ ctx.sql.push(`${item.type} ${target2} ON true`);
7571
+ if (on2) {
7572
+ fromWhereSql = fromWhereSql ? fromWhereSql + " AND " + on2 : on2;
7573
+ }
7574
+ }
7575
+ }
7576
+ }
7577
+ const mainWhereSql = whereToSql(ctx, table, query, quotedAs);
7578
+ const whereSql = mainWhereSql ? fromWhereSql ? mainWhereSql + " AND " + fromWhereSql : mainWhereSql : fromWhereSql;
7579
+ if (whereSql) {
7580
+ ctx.sql.push("WHERE", whereSql);
7581
+ }
7461
7582
  hookSelect = pushUpdateReturning(
7462
7583
  ctx,
7463
7584
  table,
@@ -8749,7 +8870,7 @@ class WithMethods {
8749
8870
  const shape = getShapeFromSelect(query, true);
8750
8871
  return setQueryObjectValueImmutable(q, "withShapes", name, {
8751
8872
  shape,
8752
- computeds: query.q.computeds
8873
+ computeds: query.q.runtimeComputeds
8753
8874
  });
8754
8875
  }
8755
8876
  withRecursive(name, ...args) {
@@ -8760,7 +8881,7 @@ class WithMethods {
8760
8881
  arg.q.withShapes = q.q.withShapes;
8761
8882
  let query = typeof baseFn === "function" ? baseFn(arg) : baseFn;
8762
8883
  const shape = getShapeFromSelect(query, true);
8763
- const withConfig = { shape, computeds: query.q.computeds };
8884
+ const withConfig = { shape, computeds: query.q.runtimeComputeds };
8764
8885
  ((_a = arg.q).withShapes ?? (_a.withShapes = {}))[name] = withConfig;
8765
8886
  const recursive = recursiveFn(arg);
8766
8887
  query = _queryUnion(query, [recursive], options.union ?? "UNION ALL");
@@ -8777,14 +8898,15 @@ class WithMethods {
8777
8898
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
8778
8899
  withSql(name, ...args) {
8779
8900
  const q = _clone(this);
8780
- const [options, shape, sql] = args.length === 2 ? [void 0, args[0], args[1]] : args;
8901
+ const [options, shapeFn, sql] = args.length === 2 ? [void 0, args[0], args[1]] : args;
8902
+ const shape = shapeFn(this.columnTypes);
8781
8903
  orchidCore.pushQueryValueImmutable(q, "with", {
8782
8904
  n: name,
8783
- o: options,
8905
+ o: { ...options, columns: Object.keys(shape) },
8784
8906
  s: sql(q)
8785
8907
  });
8786
8908
  return setQueryObjectValueImmutable(q, "withShapes", name, {
8787
- shape: shape(this.columnTypes)
8909
+ shape
8788
8910
  });
8789
8911
  }
8790
8912
  }
@@ -9035,7 +9157,7 @@ const createSelect = (q) => {
9035
9157
  if (q.q.returnType === "void" || isSelectingCount(q)) {
9036
9158
  q.q.select = void 0;
9037
9159
  } else if (!q.q.select) {
9038
- q.q.select = ["*"];
9160
+ _querySelectAll(q);
9039
9161
  q.q.returning = true;
9040
9162
  }
9041
9163
  };
@@ -10672,11 +10794,12 @@ class Join {
10672
10794
  */
10673
10795
  joinLateral(arg, cb) {
10674
10796
  const q = _clone(this);
10675
- return _joinLateral(
10797
+ _joinLateral(
10676
10798
  q,
10677
10799
  "JOIN",
10678
10800
  _joinLateralProcessArg(q, arg, cb)
10679
10801
  );
10802
+ return q;
10680
10803
  }
10681
10804
  /**
10682
10805
  * The same as {@link joinLateral}, but when no records found for the join it will result in `null`:
@@ -10695,11 +10818,12 @@ class Join {
10695
10818
  */
10696
10819
  leftJoinLateral(arg, cb) {
10697
10820
  const q = _clone(this);
10698
- return _joinLateral(
10699
- _clone(this),
10821
+ _joinLateral(
10822
+ q,
10700
10823
  "LEFT JOIN",
10701
10824
  _joinLateralProcessArg(q, arg, cb)
10702
10825
  );
10826
+ return q;
10703
10827
  }
10704
10828
  /**
10705
10829
  * This method may be useful
@@ -10881,6 +11005,7 @@ class JsonMethods {
10881
11005
  const mergableObjects = /* @__PURE__ */ new Set([
10882
11006
  "shape",
10883
11007
  "withShapes",
11008
+ "defaultParsers",
10884
11009
  "parsers",
10885
11010
  "defaults",
10886
11011
  "joinedShapes",
@@ -10967,7 +11092,8 @@ const _queryChangeCounter = (self, op, data) => {
10967
11092
  orchidCore.pushQueryValueImmutable(self, "updateData", map);
10968
11093
  return self;
10969
11094
  };
10970
- const _queryUpdate = (query, arg) => {
11095
+ const _queryUpdate = (updateSelf, arg) => {
11096
+ const query = updateSelf;
10971
11097
  const { q } = query;
10972
11098
  q.type = "update";
10973
11099
  const returnCount = !q.select;
@@ -10975,6 +11101,7 @@ const _queryUpdate = (query, arg) => {
10975
11101
  orchidCore.pushQueryValueImmutable(query, "updateData", set);
10976
11102
  const { shape } = q;
10977
11103
  const ctx = {};
11104
+ let selectQuery;
10978
11105
  for (const key in arg) {
10979
11106
  const item = shape[key];
10980
11107
  if (!item && shape !== anyShape) {
@@ -10986,8 +11113,12 @@ const _queryUpdate = (query, arg) => {
10986
11113
  if (item) throwOnReadOnly(query, item, key);
10987
11114
  let value = set[key];
10988
11115
  if (typeof value === "function") {
11116
+ if (!selectQuery) {
11117
+ selectQuery = query.clone();
11118
+ selectQuery.q.type = void 0;
11119
+ }
10989
11120
  value = resolveSubQueryCallbackV2(
10990
- query.baseQuery,
11121
+ selectQuery,
10991
11122
  value
10992
11123
  );
10993
11124
  if (value instanceof Db && value.q.type && value.q.subQuery) {
@@ -11000,14 +11131,7 @@ const _queryUpdate = (query, arg) => {
11000
11131
  }
11001
11132
  if (value !== null && value !== void 0 && !orchidCore.isExpression(value)) {
11002
11133
  if (value instanceof Db) {
11003
- moveQueryValueToWith(
11004
- query,
11005
- q,
11006
- value,
11007
- "with",
11008
- set,
11009
- key
11010
- );
11134
+ moveQueryValueToWith(query, q, value, "with", set, key);
11011
11135
  } else {
11012
11136
  const encode = item?.data.encode;
11013
11137
  if (encode) set[key] = encode(value);
@@ -11035,10 +11159,7 @@ const _queryUpdate = (query, arg) => {
11035
11159
  primaryKeys,
11036
11160
  queryResult.rows.map((item) => primaryKeys.map((key) => item[key]))
11037
11161
  );
11038
- await _queryUpdate(
11039
- t,
11040
- ctx.collect.data
11041
- );
11162
+ await _queryUpdate(t, ctx.collect.data);
11042
11163
  for (const row of queryResult.rows) {
11043
11164
  Object.assign(row, ctx.collect.data);
11044
11165
  }
@@ -11050,7 +11171,9 @@ const _queryUpdate = (query, arg) => {
11050
11171
  q.returnType = "valueOrThrow";
11051
11172
  q.returning = true;
11052
11173
  }
11053
- throwIfNoWhere(query, "update");
11174
+ if (!q.updateFrom) {
11175
+ throwIfNoWhere(query, "update");
11176
+ }
11054
11177
  return query;
11055
11178
  };
11056
11179
  const _queryUpdateOrThrow = (q, arg) => {
@@ -11288,6 +11411,77 @@ class Update {
11288
11411
  updateOrThrow(arg) {
11289
11412
  return _queryUpdateOrThrow(_clone(this), arg);
11290
11413
  }
11414
+ /**
11415
+ * Use `updateFrom` to update records in one table based on a query result from another table or CTE.
11416
+ *
11417
+ * `updateFrom` accepts the same arguments as {@link Query.join}.
11418
+ *
11419
+ * ```ts
11420
+ * // save all author names to their books by using a relation name:
11421
+ * db.books.updateFrom('author').set({ authorName: (q) => q.ref('author.name') });
11422
+ *
11423
+ * // update from authors that match the condition:
11424
+ * db.books
11425
+ * .updateFrom((q) => q.author.where({ writingSkills: 'good' }))
11426
+ * .set({ authorName: (q) => q.ref('author.name') });
11427
+ *
11428
+ * // update from any table using custom `on` conditions:
11429
+ * db.books
11430
+ * .updateFrom(
11431
+ * () => db.authors,
11432
+ * (q) => q.on('authors.id', 'books.authorId'),
11433
+ * )
11434
+ * .set({ authorName: (q) => q.ref('author.name') });
11435
+ *
11436
+ * // conditions after `updateFrom` can reference both tables:
11437
+ * db.books
11438
+ * .updateFrom(() => db.authors)
11439
+ * .where({
11440
+ * 'authors.id': (q) => q.ref('books.authorId'),
11441
+ * })
11442
+ * .set({ authorName: (q) => q.ref('author.name') });
11443
+ *
11444
+ * // can join and use another table in between `updateFrom` and `set`:
11445
+ * db.books
11446
+ * .updateFrom('author')
11447
+ * .join('publisher')
11448
+ * .set({
11449
+ * authorName: (q) => q.ref('author.name'),
11450
+ * publisherName: (q) => q.ref('publisher.name'),
11451
+ * });
11452
+ *
11453
+ * // updating from a CTE
11454
+ * db.books
11455
+ * .with('a', () =>
11456
+ * db.authors.where({ writingSkills: 'good' }).select('id', 'name').limit(10),
11457
+ * )
11458
+ * .updateFrom('a', (q) => q.on('a.id', 'books.authorId'))
11459
+ * .set({ authorName: (q) => q.ref('author.name') });
11460
+ * ```
11461
+ */
11462
+ updateFrom(arg, ...args) {
11463
+ const q = _clone(this);
11464
+ const joinArgs = _joinReturningArgs(
11465
+ q,
11466
+ true,
11467
+ arg,
11468
+ args,
11469
+ // eslint-disable-line @typescript-eslint/no-explicit-any
11470
+ true
11471
+ );
11472
+ if (!joinArgs) {
11473
+ return _queryNone(q);
11474
+ }
11475
+ joinArgs.u = true;
11476
+ q.q.updateFrom = joinArgs;
11477
+ return q;
11478
+ }
11479
+ /**
11480
+ * Use after {@link updateFrom}
11481
+ */
11482
+ set(arg) {
11483
+ return _queryUpdate(_clone(this), arg);
11484
+ }
11291
11485
  /**
11292
11486
  * Increments a column by `1`, returns a count of updated records by default.
11293
11487
  *
@@ -11616,8 +11810,8 @@ function orCreate(query, data, updateData, mergeData) {
11616
11810
  const { handleResult } = q;
11617
11811
  let result;
11618
11812
  let created = false;
11619
- q.handleResult = (q2, t, r, s) => {
11620
- return created ? result : handleResult(q2, t, r, s);
11813
+ q.handleResult = (q2, t, r, s, i) => {
11814
+ return created ? result : handleResult(q2, t, r, s, i);
11621
11815
  };
11622
11816
  q.hookSelect = new Map(q.hookSelect);
11623
11817
  q.patchResult = async (q2, hookSelect, queryResult) => {
@@ -11656,7 +11850,7 @@ function orCreate(query, data, updateData, mergeData) {
11656
11850
  );
11657
11851
  let afterHooks;
11658
11852
  let afterCommitHooks;
11659
- q22.q.handleResult = (a, t, r, s) => {
11853
+ q22.q.handleResult = (a, t, r, s, i) => {
11660
11854
  if (hasAfterCallback || hasAfterCommitCallback) {
11661
11855
  const fieldName = r.fields[0].name;
11662
11856
  if (r.rows[0][fieldName]) {
@@ -11668,7 +11862,7 @@ function orCreate(query, data, updateData, mergeData) {
11668
11862
  }
11669
11863
  delete r.rows[0][fieldName];
11670
11864
  }
11671
- result = handleResult(a, t, r, s);
11865
+ result = handleResult(a, t, r, s, i);
11672
11866
  return a.q.hookSelect ? result.map((row) => ({ ...row })) : result;
11673
11867
  };
11674
11868
  q22.q.log = q2.q.log;
@@ -12992,15 +13186,6 @@ class Db extends QueryMethods {
12992
13186
  const self = this;
12993
13187
  const { softDelete } = options;
12994
13188
  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
13189
  this.baseQuery = this;
13005
13190
  this.relations = {};
13006
13191
  this.relationQueries = {};
@@ -13010,6 +13195,7 @@ class Db extends QueryMethods {
13010
13195
  let modifyQuery = void 0;
13011
13196
  let prepareSelectAll = false;
13012
13197
  let hasHookSetters;
13198
+ let runtimeDefaultColumns;
13013
13199
  const { snakeCase } = options;
13014
13200
  for (const key in shape) {
13015
13201
  const column = shape[key];
@@ -13035,9 +13221,8 @@ class Db extends QueryMethods {
13035
13221
  modifyQuery = orchidCore.pushOrNewArray(modifyQuery, (q) => mq(q, column));
13036
13222
  }
13037
13223
  if (typeof column.data.default === "function") {
13038
- const arr = this.internal.runtimeDefaultColumns;
13039
- if (!arr) this.internal.runtimeDefaultColumns = [key];
13040
- else arr.push(key);
13224
+ if (!runtimeDefaultColumns) runtimeDefaultColumns = [key];
13225
+ else runtimeDefaultColumns.push(key);
13041
13226
  if (!column.data.runtimeDefault) {
13042
13227
  const {
13043
13228
  data: { default: def, encode }
@@ -13049,6 +13234,16 @@ class Db extends QueryMethods {
13049
13234
  hasHookSetters = true;
13050
13235
  }
13051
13236
  }
13237
+ this.internal = {
13238
+ runtimeDefaultColumns,
13239
+ transactionStorage,
13240
+ scopes,
13241
+ snakeCase: options.snakeCase,
13242
+ noPrimaryKey: options.noPrimaryKey === "ignore",
13243
+ comment: options.comment,
13244
+ nowSQL: options.nowSQL,
13245
+ tableData
13246
+ };
13052
13247
  this.q = {
13053
13248
  adapter,
13054
13249
  shape,
@@ -13056,7 +13251,7 @@ class Db extends QueryMethods {
13056
13251
  logger,
13057
13252
  log: logParamToLogObject(logger, options.log),
13058
13253
  autoPreparedStatements: options.autoPreparedStatements ?? false,
13059
- parsers: hasParsers ? parsers : void 0,
13254
+ defaultParsers: hasParsers ? parsers : void 0,
13060
13255
  language: options.language,
13061
13256
  schema: options?.schema
13062
13257
  };
@@ -13597,6 +13792,7 @@ exports._queryOr = _queryOr;
13597
13792
  exports._queryOrNot = _queryOrNot;
13598
13793
  exports._queryRows = _queryRows;
13599
13794
  exports._querySelect = _querySelect;
13795
+ exports._querySelectAll = _querySelectAll;
13600
13796
  exports._queryTake = _queryTake;
13601
13797
  exports._queryTakeOptional = _queryTakeOptional;
13602
13798
  exports._queryUnion = _queryUnion;