pqb 0.54.3 → 0.55.0

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.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { ExpressionTypeMethod, Expression, RawSQLBase, emptyObject, isTemplateLiteralArgs, ColumnTypeBase, setColumnData, pushColumnData, templateLiteralSQLToCode, quoteObjectKey, toArray, emptyArray, singleQuote, addCode, singleQuoteArray, objectHasValues, toSnakeCase, columnDefaultArgumentToCode, columnErrorMessagesToCode, setObjectValueImmutable, getValueKey, addValue, isExpression, dateDataToCode, joinTruthy, arrayDataToCode, numberDataToCode, noop, stringDataToCode, getDefaultLanguage, setDefaultNowFn, setDefaultLanguage, setCurrentColumnName, timestampHelpers, returnArg as returnArg$1, pushQueryValueImmutable, logColors, applyTransforms, callWithThis, setParserToQuery, pushOrNewArray, isRawSQL, setAdapterConnectRetry, pushOrNewArrayToObjectImmutable, QueryHookUtils, isObjectEmpty, ValExpression, applyMixins, snakeCaseKey } from 'orchid-core';
1
+ import { ExpressionTypeMethod, Expression, RawSQLBase, emptyObject, isTemplateLiteralArgs, ColumnTypeBase, setColumnData, pushColumnData, templateLiteralSQLToCode, quoteObjectKey, toArray, emptyArray, singleQuote, addCode, singleQuoteArray, objectHasValues, toSnakeCase, columnDefaultArgumentToCode, columnErrorMessagesToCode, setObjectValueImmutable, getValueKey, addValue, isExpression, dateDataToCode, joinTruthy, arrayDataToCode, numberDataToCode, noop, stringDataToCode, getDefaultLanguage, setDefaultNowFn, setDefaultLanguage, setCurrentColumnName, timestampHelpers, _getQueryAliasOrName, _getQueryOuterAliases, returnArg as returnArg$1, pushQueryValueImmutable, NotFoundError, _setSubQueryAliases, _applyRelationAliases, isRelationQuery, OrchidOrmInternalError, _checkIfAliased, logColors, OrchidOrmError, applyTransforms, callWithThis, requirePrimaryKeys, pick, getFreeAlias, _setQueryAs, _copyQueryAliasToQuery, setParserToQuery, newDelayedRelationSelect, pushOrNewArray, getPrimaryKeys, setDelayedRelation, UnhandledTypeError, isRawSQL, setAdapterConnectRetry, pushOrNewArrayToObjectImmutable, QueryHookUtils, MoreThanOneRowError, isObjectEmpty, ValExpression, applyMixins, _getQueryAs, _setQueryAlias, QueryError, snakeCaseKey } from 'orchid-core';
2
2
  import pg from 'pg';
3
3
  import { inspect } from 'node:util';
4
4
  import { AsyncLocalStorage } from 'node:async_hooks';
@@ -2603,7 +2603,7 @@ const columnWithDotToSql = (ctx, data, shape, column, index, quotedAs, select) =
2603
2603
  const shape2 = data.joinedShapes?.[table];
2604
2604
  return shape2 ? select ? makeRowToJson(table, shape2, true) : `"${table}".*` : column;
2605
2605
  }
2606
- const tableName = data.aliases?.[table] || table;
2606
+ const tableName = _getQueryAliasOrName(data, table);
2607
2607
  const quoted = `"${table}"`;
2608
2608
  const col = quoted === quotedAs ? shape[key] : data.joinedShapes?.[tableName]?.[key];
2609
2609
  if (col) {
@@ -2642,7 +2642,7 @@ const tableColumnToSqlWithAs = (ctx, data, column, table, key, as, quotedAs, sel
2642
2642
  }
2643
2643
  return column;
2644
2644
  }
2645
- const tableName = data.aliases?.[table] || table;
2645
+ const tableName = _getQueryAliasOrName(data, table);
2646
2646
  const quoted = `"${table}"`;
2647
2647
  const col = quoted === quotedAs ? data.shape[key] : data.joinedShapes?.[tableName][key];
2648
2648
  if (jsonList) jsonList[as] = col;
@@ -2703,72 +2703,6 @@ const pushDistinctSql = (ctx, table, distinct, quotedAs) => {
2703
2703
  }
2704
2704
  };
2705
2705
 
2706
- var __typeError = (msg) => {
2707
- throw TypeError(msg);
2708
- };
2709
- var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
2710
- var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
2711
- var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
2712
- var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
2713
- var _query, _query2;
2714
- class OrchidOrmError extends Error {
2715
- }
2716
- class NotFoundError extends OrchidOrmError {
2717
- constructor(query, message = "Record is not found") {
2718
- super(message);
2719
- // `#query` is private to prevent it from serializing to not cause problems to test runner reports
2720
- __privateAdd(this, _query);
2721
- __privateSet(this, _query, query);
2722
- }
2723
- get query() {
2724
- return __privateGet(this, _query);
2725
- }
2726
- }
2727
- _query = new WeakMap();
2728
- class OrchidOrmInternalError extends Error {
2729
- constructor(query, message, data) {
2730
- super(message);
2731
- this.data = data;
2732
- // `#query` is private to prevent it from serializing to not cause problems to test runner reports
2733
- __privateAdd(this, _query2);
2734
- __privateSet(this, _query2, query);
2735
- }
2736
- get query() {
2737
- return __privateGet(this, _query2);
2738
- }
2739
- }
2740
- _query2 = new WeakMap();
2741
- class QueryError extends OrchidOrmInternalError {
2742
- get isUnique() {
2743
- return this.code === "23505";
2744
- }
2745
- get columns() {
2746
- if (this.columnsCache) return this.columnsCache;
2747
- const columns = {};
2748
- if (this.detail) {
2749
- const list = this.detail.match(/\((.*)\)=/)?.[1];
2750
- if (list) {
2751
- list.split(", ").forEach((item) => {
2752
- const column = item.startsWith('"') ? item.slice(1, -1) : item;
2753
- const key = this.query.columnNameToKey(column) ?? column;
2754
- columns[key] = true;
2755
- });
2756
- }
2757
- }
2758
- return this.columnsCache = columns;
2759
- }
2760
- }
2761
- class MoreThanOneRowError extends OrchidOrmInternalError {
2762
- constructor(query, message) {
2763
- super(query, message);
2764
- }
2765
- }
2766
- class UnhandledTypeError extends OrchidOrmInternalError {
2767
- constructor(query, value) {
2768
- super(query, `Unhandled type: ${JSON.stringify(value)} received`);
2769
- }
2770
- }
2771
-
2772
2706
  const pushWhereStatementSql = (ctx, table, query, quotedAs) => {
2773
2707
  const res = whereToSql(ctx, table, query, quotedAs);
2774
2708
  if (res) {
@@ -2890,7 +2824,7 @@ const processWhere = (ands, ctx, table, query, data, quotedAs) => {
2890
2824
  const joinAs = `"${getJoinItemSource(item.joinFrom)}"`;
2891
2825
  const q = item.useOuterAliases ? {
2892
2826
  joinedShapes: query.joinedShapes,
2893
- aliases: query.outerAliases,
2827
+ aliases: _getQueryOuterAliases(query),
2894
2828
  shape: query.shape
2895
2829
  } : query;
2896
2830
  ands.push(
@@ -3016,7 +2950,10 @@ const processJoinItem = (ctx, table, query, args, quotedAs) => {
3016
2950
  if ("l" in args) {
3017
2951
  const { aliasValue } = ctx;
3018
2952
  ctx.aliasValue = true;
3019
- target = `(${getSqlText(args.l.toSQL(ctx))}) "${query.aliases?.[args.a] || args.a}"`;
2953
+ target = `(${getSqlText(args.l.toSQL(ctx))}) "${_getQueryAliasOrName(
2954
+ query,
2955
+ args.a
2956
+ )}"`;
3020
2957
  on = `${args.i ? `"${args.a}".r IS NOT NULL` : "true"}`;
3021
2958
  ctx.aliasValue = aliasValue;
3022
2959
  } else if ("j" in args) {
@@ -3395,7 +3332,7 @@ const resolveCallbacksInArgs = (q, args) => {
3395
3332
  qb.q = getClonedQueryData(q.q);
3396
3333
  qb.q.and = qb.q.or = qb.q.scopes = void 0;
3397
3334
  qb.q.subQuery = 1;
3398
- qb.q.outerAliases = qb.q.aliases;
3335
+ _setSubQueryAliases(qb);
3399
3336
  args[i] = resolveSubQueryCallbackV2(qb, arg);
3400
3337
  }
3401
3338
  }
@@ -4163,42 +4100,6 @@ class Where {
4163
4100
  }
4164
4101
  }
4165
4102
 
4166
- const _queryAs = (self, as) => {
4167
- const { q } = self;
4168
- q.as = as;
4169
- q.aliases = {
4170
- ...q.aliases,
4171
- [as]: q.aliases ? _queryResolveAlias(q.aliases, as) : as
4172
- };
4173
- return self;
4174
- };
4175
- const _queryResolveAlias = (aliases, as) => {
4176
- if (!aliases[as]) return as;
4177
- let suffix = 2;
4178
- let privateAs;
4179
- while (aliases[privateAs = as + suffix]) {
4180
- suffix++;
4181
- }
4182
- return privateAs;
4183
- };
4184
- class AsMethods {
4185
- /**
4186
- * Sets table alias:
4187
- *
4188
- * ```ts
4189
- * db.table.as('u').select('u.name');
4190
- *
4191
- * // Can be used in the join:
4192
- * db.table.join(Profile.as('p'), 'p.userId', 'user.id');
4193
- * ```
4194
- *
4195
- * @param as - alias for the table of this query
4196
- */
4197
- as(as) {
4198
- return _queryAs(_clone(this), as);
4199
- }
4200
- }
4201
-
4202
4103
  const _chain = (fromQuery, toQuery, rel) => {
4203
4104
  const self = fromQuery;
4204
4105
  const toTable = toQuery;
@@ -4230,13 +4131,7 @@ const _chain = (fromQuery, toQuery, rel) => {
4230
4131
  } else {
4231
4132
  q.relChain = [{ query: self, rel }];
4232
4133
  }
4233
- const aliases = self.q.as ? { ...self.q.aliases } : { ...self.q.aliases, [self.table]: self.table };
4234
- const relAliases = q.aliases;
4235
- for (const as in relAliases) {
4236
- aliases[as] = _queryResolveAlias(aliases, as);
4237
- }
4238
- q.as = aliases[q.as];
4239
- q.aliases = aliases;
4134
+ _applyRelationAliases(self, q);
4240
4135
  q.joinedShapes = {
4241
4136
  [getQueryAs(self)]: self.q.shape,
4242
4137
  ...self.q.joinedShapes
@@ -4277,14 +4172,11 @@ const resolveSubQueryCallbackV2 = (q, cb) => {
4277
4172
  const arg = Object.create(base);
4278
4173
  arg.q = getClonedQueryData(q.q);
4279
4174
  arg.q.subQuery = 1;
4280
- arg.q.relChain = void 0;
4281
- arg.q.outerAliases = q.q.aliases;
4175
+ arg.q.with = arg.q.relChain = void 0;
4176
+ _setSubQueryAliases(arg);
4282
4177
  return cb(arg);
4283
4178
  };
4284
- const joinSubQuery = (q, sub) => {
4285
- if (!("joinQuery" in sub)) return sub;
4286
- return sub.joinQuery(sub, q);
4287
- };
4179
+ const joinSubQuery = (q, sub) => isRelationQuery(sub) ? sub.joinQuery(sub, q) : sub;
4288
4180
 
4289
4181
  const _clone = (q) => q.clone();
4290
4182
  const pushQueryArrayImmutable = (q, key, value) => {
@@ -4308,9 +4200,7 @@ const throwIfNoWhere = (q, method) => {
4308
4200
  }
4309
4201
  };
4310
4202
  const throwIfJoinLateral = (q, method) => {
4311
- if (q.q.join?.some(
4312
- (x) => Array.isArray(x) || "s" in x.args && x.args.s
4313
- )) {
4203
+ if (q.q.join?.some((x) => Array.isArray(x) || "s" in x.args && x.args.s)) {
4314
4204
  throw new OrchidOrmInternalError(
4315
4205
  q,
4316
4206
  `Cannot join a complex query in ${method}`
@@ -4338,24 +4228,6 @@ const extendQuery = (q, methods) => {
4338
4228
  cloned.q = getClonedQueryData(q.q);
4339
4229
  return cloned;
4340
4230
  };
4341
- const getPrimaryKeys = (q) => {
4342
- var _a;
4343
- return (_a = q.internal).primaryKeys ?? (_a.primaryKeys = collectPrimaryKeys(q));
4344
- };
4345
- const collectPrimaryKeys = (q) => {
4346
- const primaryKeys = [];
4347
- const { shape } = q.q;
4348
- for (const key in shape) {
4349
- if (shape[key].data.primaryKey) {
4350
- primaryKeys.push(key);
4351
- }
4352
- }
4353
- const pkey = q.internal.tableData.primaryKey;
4354
- if (pkey) {
4355
- primaryKeys.push(...pkey.columns);
4356
- }
4357
- return primaryKeys;
4358
- };
4359
4231
  const _queryAll = (q) => {
4360
4232
  q.q.returnType = "all";
4361
4233
  q.q.all = true;
@@ -4405,7 +4277,7 @@ const _queryRows = (q) => {
4405
4277
  };
4406
4278
  const getFullColumnTable = (q, column, index, as) => {
4407
4279
  const table = column.slice(0, index);
4408
- return as && table !== as && q.q.aliases?.[table] === as ? as : table;
4280
+ return as && table !== as && _checkIfAliased(q, table, as) ? as : table;
4409
4281
  };
4410
4282
 
4411
4283
  const _join = (query, require, type, first, args) => {
@@ -5153,7 +5025,7 @@ function maybeWrappedThen(resolve, reject) {
5153
5025
  }
5154
5026
  }
5155
5027
  const trx = this.internal.transactionStorage.getStore();
5156
- if ((q.wrapInTransaction || afterHooks) && !trx) {
5028
+ if ((q.wrapInTransaction || q.selectRelation && q.type || afterHooks) && !trx) {
5157
5029
  return this.transaction(
5158
5030
  () => new Promise((resolve2, reject2) => {
5159
5031
  const trx2 = this.internal.transactionStorage.getStore();
@@ -5189,6 +5061,7 @@ const callAfterHook = function(cb) {
5189
5061
  };
5190
5062
  const beginSql = { text: "BEGIN" };
5191
5063
  const then = async (q, adapter, trx, beforeHooks, afterHooks, afterCommitHooks, resolve, reject) => {
5064
+ var _a;
5192
5065
  const { q: query } = q;
5193
5066
  let sql;
5194
5067
  let logData;
@@ -5204,9 +5077,9 @@ const then = async (q, adapter, trx, beforeHooks, afterHooks, afterCommitHooks,
5204
5077
  );
5205
5078
  }
5206
5079
  sql = q.toSQL();
5207
- const { hookSelect } = sql;
5080
+ const { hookSelect, delayedRelationSelect } = sql;
5208
5081
  const { returnType = "all" } = query;
5209
- const tempReturnType = hookSelect || returnType === "rows" && q.q.batchParsers ? "all" : returnType;
5082
+ const tempReturnType = hookSelect || returnType === "rows" && q.q.batchParsers || delayedRelationSelect?.value ? "all" : returnType;
5210
5083
  let result;
5211
5084
  let queryResult;
5212
5085
  if ("text" in sql) {
@@ -5338,6 +5211,51 @@ const then = async (q, adapter, trx, beforeHooks, afterHooks, afterCommitHooks,
5338
5211
  await Promise.all(query.after.map(callAfterHook, args));
5339
5212
  }
5340
5213
  }
5214
+ if (delayedRelationSelect?.value) {
5215
+ const q2 = delayedRelationSelect.query;
5216
+ const primaryKeys = requirePrimaryKeys(
5217
+ q2,
5218
+ "Cannot select a relation of a table that has no primary keys"
5219
+ );
5220
+ const selectQuery = q2.clone();
5221
+ selectQuery.q.type = selectQuery.q.returnType = void 0;
5222
+ ((_a = selectQuery.q).and ?? (_a.and = [])).push(pick(result, primaryKeys));
5223
+ const relationsSelect = delayedRelationSelect.value;
5224
+ let selectAs;
5225
+ if (renames) {
5226
+ selectAs = {};
5227
+ for (const key in renames) {
5228
+ if (key in relationsSelect) {
5229
+ selectAs[renames[key]] = relationsSelect[key];
5230
+ }
5231
+ }
5232
+ } else {
5233
+ selectAs = { ...relationsSelect };
5234
+ }
5235
+ const select = [{ selectAs }];
5236
+ const relationKeyAliases = primaryKeys.map((key) => {
5237
+ if (key in selectAs) {
5238
+ const as = getFreeAlias(selectAs, key);
5239
+ selectAs[as] = key;
5240
+ return as;
5241
+ } else {
5242
+ select.push(key);
5243
+ return key;
5244
+ }
5245
+ });
5246
+ selectQuery.q.select = select;
5247
+ const relationsResult = await selectQuery;
5248
+ for (const row of result) {
5249
+ const relationRow = relationsResult.find((relationRow2) => {
5250
+ return !primaryKeys.some(
5251
+ (key, i) => relationRow2[relationKeyAliases[i]] !== row[key]
5252
+ );
5253
+ });
5254
+ if (relationRow) {
5255
+ Object.assign(row, relationRow);
5256
+ }
5257
+ }
5258
+ }
5341
5259
  if (hookSelect || tempReturnType !== returnType) {
5342
5260
  if (renames) {
5343
5261
  for (const a in renames) {
@@ -5747,7 +5665,7 @@ class FromMethods {
5747
5665
  }
5748
5666
 
5749
5667
  function queryWrap(self, query, as = "t") {
5750
- return _queryAs(queryFrom(query, self), as);
5668
+ return _setQueryAs(queryFrom(query, self), as);
5751
5669
  }
5752
5670
  function cloneQueryBaseUnscoped(query) {
5753
5671
  const q = query.baseQuery.clone();
@@ -5984,11 +5902,11 @@ const collectNestedSelectBatches = (batches, rows, path, last) => {
5984
5902
  };
5985
5903
  const emptyArrSQL = new RawSQL("'[]'");
5986
5904
  const processSelectArg = (q, as, arg, columnAs) => {
5905
+ const query = q;
5987
5906
  if (typeof arg === "string") {
5988
5907
  return setParserForSelectedString(q, arg, as, columnAs);
5989
5908
  }
5990
5909
  const selectAs = {};
5991
- let aliases;
5992
5910
  for (const key in arg) {
5993
5911
  let value = arg[key];
5994
5912
  let joinQuery;
@@ -5999,18 +5917,18 @@ const processSelectArg = (q, as, arg, columnAs) => {
5999
5917
  return false;
6000
5918
  }
6001
5919
  }
6002
- if (!isExpression(value) && value.joinQuery) {
6003
- joinQuery = true;
5920
+ if (!isExpression(value) && isRelationQuery(value)) {
5921
+ query.q.selectRelation = joinQuery = true;
6004
5922
  value = value.joinQuery(value, q);
6005
- let query;
5923
+ let subQuery;
6006
5924
  const { returnType, innerJoinLateral } = value.q;
6007
5925
  if (!returnType || returnType === "all") {
6008
- query = value.json(false);
5926
+ subQuery = value.json(false);
6009
5927
  if (!innerJoinLateral) {
6010
5928
  value.q.coalesceValue = emptyArrSQL;
6011
5929
  }
6012
5930
  } else if (returnType === "pluck") {
6013
- query = value.q.select ? value.wrap(cloneQueryBaseUnscoped(value)).jsonAgg(value.q.select[0]) : value.json(false);
5931
+ subQuery = value.q.select ? value.wrap(cloneQueryBaseUnscoped(value)).jsonAgg(value.q.select[0]) : value.json(false);
6014
5932
  value.q.coalesceValue = emptyArrSQL;
6015
5933
  } else {
6016
5934
  if (returnType === "value" || returnType === "valueOrThrow") {
@@ -6020,23 +5938,23 @@ const processSelectArg = (q, as, arg, columnAs) => {
6020
5938
  selectAs: { r: value.q.select[0] }
6021
5939
  };
6022
5940
  }
6023
- query = value;
5941
+ subQuery = value;
6024
5942
  } else {
6025
- query = value.json(false);
5943
+ subQuery = value.json(false);
6026
5944
  }
6027
5945
  } else {
6028
- query = value;
5946
+ subQuery = value;
6029
5947
  }
6030
5948
  }
6031
- const asOverride = value.q.aliases[key] ?? key;
6032
- value.q.joinedForSelect = asOverride;
6033
- if (asOverride !== key) {
6034
- aliases = { ...q.q.aliases, [key]: asOverride };
6035
- }
5949
+ value.q.joinedForSelect = _copyQueryAliasToQuery(
5950
+ value,
5951
+ q,
5952
+ key
5953
+ );
6036
5954
  _joinLateral(
6037
5955
  q,
6038
5956
  innerJoinLateral ? "JOIN" : "LEFT JOIN",
6039
- query,
5957
+ subQuery,
6040
5958
  key,
6041
5959
  // no need for `ON p.r IS NOT NULL` check when joining a single record,
6042
5960
  // `JOIN` will handle it on itself.
@@ -6044,7 +5962,6 @@ const processSelectArg = (q, as, arg, columnAs) => {
6044
5962
  );
6045
5963
  }
6046
5964
  }
6047
- if (aliases) q.q.aliases = aliases;
6048
5965
  selectAs[key] = addParserForSelectItem(
6049
5966
  q,
6050
5967
  as,
@@ -6461,6 +6378,7 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
6461
6378
  }
6462
6379
  }
6463
6380
  const insertSql = `INSERT INTO ${quotedAs}${quotedColumns.length ? "(" + quotedColumns.join(", ") + ")" : ""}`;
6381
+ const hasNonSelect = ctx.hasNonSelect;
6464
6382
  if ("from" in values && query.insertWith) {
6465
6383
  pushWithSql(ctx, Object.values(query.insertWith).flat());
6466
6384
  }
@@ -6519,6 +6437,7 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
6519
6437
  }
6520
6438
  pushWhereStatementSql(ctx, q, query, quotedAs);
6521
6439
  let returning;
6440
+ let delayedRelationSelect;
6522
6441
  if (inCTE) {
6523
6442
  const select = inCTE.returning?.select;
6524
6443
  returning = {
@@ -6526,7 +6445,15 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
6526
6445
  hookSelect: inCTE.returning?.hookSelect
6527
6446
  };
6528
6447
  } else {
6529
- returning = makeReturningSql(ctx, q, query, quotedAs, 2);
6448
+ delayedRelationSelect = q.q.selectRelation ? newDelayedRelationSelect(q) : void 0;
6449
+ returning = makeReturningSql(
6450
+ ctx,
6451
+ q,
6452
+ query,
6453
+ quotedAs,
6454
+ delayedRelationSelect,
6455
+ 2
6456
+ );
6530
6457
  }
6531
6458
  if (returning.select) ctx.sql.push("RETURNING", returning.select);
6532
6459
  if ("from" in values) {
@@ -6549,7 +6476,7 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
6549
6476
  )
6550
6477
  );
6551
6478
  }
6552
- ctx.sql[valuesPos] = getSqlText(toSQL(q2, { values: ctx.values }));
6479
+ ctx.sql[valuesPos] = getSqlText(toSQL(q2, ctx));
6553
6480
  } else {
6554
6481
  const valuesSql = [];
6555
6482
  let ctxValues = ctx.values;
@@ -6606,6 +6533,12 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
6606
6533
  ctx.sql[valuesPos - 1] = "WITH " + withSqls.join(", ") + " " + insertSql;
6607
6534
  }
6608
6535
  if (batch) {
6536
+ if (hasNonSelect) {
6537
+ throw new OrchidOrmInternalError(
6538
+ q,
6539
+ `Cannot insert many records when having a non-select sub-query`
6540
+ );
6541
+ }
6609
6542
  ctx.sql[valuesPos] = (inCTE ? "SELECT " : "VALUES ") + valuesSql.join(", ");
6610
6543
  batch.push({
6611
6544
  text: ctx.sql.join(" "),
@@ -6613,6 +6546,7 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
6613
6546
  });
6614
6547
  return {
6615
6548
  hookSelect: returning.hookSelect,
6549
+ delayedRelationSelect,
6616
6550
  batch
6617
6551
  };
6618
6552
  } else {
@@ -6624,6 +6558,7 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
6624
6558
  }
6625
6559
  return {
6626
6560
  hookSelect: returning.hookSelect,
6561
+ delayedRelationSelect,
6627
6562
  text: ctx.sql.join(" "),
6628
6563
  values: ctx.values
6629
6564
  };
@@ -6795,7 +6730,7 @@ const hookSelectKeys = [
6795
6730
  "afterCreateSelect",
6796
6731
  "afterDeleteSelect"
6797
6732
  ];
6798
- const makeReturningSql = (ctx, q, data, quotedAs, hookSelectI, addHookSelectI) => {
6733
+ const makeReturningSql = (ctx, q, data, quotedAs, delayedRelationSelect, hookSelectI, addHookSelectI) => {
6799
6734
  if (data.inCTE) {
6800
6735
  if (hookSelectI !== 2) {
6801
6736
  const returning = makeReturningSql(
@@ -6803,6 +6738,7 @@ const makeReturningSql = (ctx, q, data, quotedAs, hookSelectI, addHookSelectI) =
6803
6738
  q,
6804
6739
  data,
6805
6740
  quotedAs,
6741
+ delayedRelationSelect,
6806
6742
  2,
6807
6743
  hookSelectI
6808
6744
  );
@@ -6824,7 +6760,7 @@ const makeReturningSql = (ctx, q, data, quotedAs, hookSelectI, addHookSelectI) =
6824
6760
  }
6825
6761
  const otherCTEHookSelect = addHookSelectI && data[hookSelectKeys[addHookSelectI]];
6826
6762
  let tempSelect;
6827
- if (q.q.hookSelect || hookSelect || otherCTEHookSelect) {
6763
+ if (q.q.hookSelect || hookSelect || otherCTEHookSelect || q.q.selectRelation) {
6828
6764
  tempSelect = new Map(q.q.hookSelect);
6829
6765
  if (hookSelect) {
6830
6766
  for (const column of hookSelect) {
@@ -6836,12 +6772,30 @@ const makeReturningSql = (ctx, q, data, quotedAs, hookSelectI, addHookSelectI) =
6836
6772
  tempSelect.set(column, { select: column });
6837
6773
  }
6838
6774
  }
6775
+ if (q.q.selectRelation) {
6776
+ for (const column of getPrimaryKeys(q)) {
6777
+ tempSelect.set(column, { select: column });
6778
+ }
6779
+ }
6839
6780
  }
6840
6781
  let sql;
6841
6782
  if (tempSelect?.size || select?.length) {
6842
- sql = selectToSql(ctx, q, data, quotedAs, tempSelect, void 0, true);
6783
+ sql = selectToSql(
6784
+ ctx,
6785
+ q,
6786
+ data,
6787
+ quotedAs,
6788
+ tempSelect,
6789
+ void 0,
6790
+ true,
6791
+ void 0,
6792
+ delayedRelationSelect
6793
+ );
6843
6794
  }
6844
- return { select: sql, hookSelect: tempSelect };
6795
+ return {
6796
+ select: sql,
6797
+ hookSelect: tempSelect
6798
+ };
6845
6799
  };
6846
6800
 
6847
6801
  const pushSelectSql = (ctx, table, query, quotedAs, aliases) => {
@@ -6860,13 +6814,14 @@ const pushSelectSql = (ctx, table, query, quotedAs, aliases) => {
6860
6814
  if (sql) ctx.sql.push(sql);
6861
6815
  }
6862
6816
  };
6863
- const selectToSql = (ctx, table, query, quotedAs, hookSelect = query.hookSelect, aliases, skipCTE, jsonList) => {
6817
+ const selectToSql = (ctx, table, query, quotedAs, hookSelect = query.hookSelect, aliases, skipCTE, jsonList, delayedRelationSelect) => {
6864
6818
  if (query.inCTE && !skipCTE) {
6865
6819
  const { select } = makeReturningSql(
6866
6820
  ctx,
6867
6821
  table,
6868
6822
  query,
6869
- quotedAs
6823
+ quotedAs,
6824
+ query.inCTE.delayedRelationSelect
6870
6825
  );
6871
6826
  return query.inCTE.selectNum || !select ? select ? "0, " + select : "0" : select;
6872
6827
  }
@@ -6940,6 +6895,8 @@ const selectToSql = (ctx, table, query, quotedAs, hookSelect = query.hookSelect,
6940
6895
  jsonList[as] = value.result.value;
6941
6896
  }
6942
6897
  aliases?.push(as);
6898
+ } else if (delayedRelationSelect && isRelationQuery(value)) {
6899
+ setDelayedRelation(delayedRelationSelect, as, value);
6943
6900
  } else {
6944
6901
  pushSubQuerySql(ctx, query, value, as, list, quotedAs, aliases);
6945
6902
  if (jsonList) {
@@ -7302,6 +7259,14 @@ const fromToSql = (ctx, data, from, quotedAs) => {
7302
7259
  fromQuery = from;
7303
7260
  }
7304
7261
  } else {
7262
+ if (data.with) {
7263
+ for (const w of data.with) {
7264
+ if (w?.n === from && w.q?.q.inCTE) {
7265
+ ctx.delayedRelationSelect = w.q.q.inCTE.delayedRelationSelect;
7266
+ break;
7267
+ }
7268
+ }
7269
+ }
7305
7270
  sql = quoteSchemaAndTable(data.schema, from);
7306
7271
  }
7307
7272
  return (only === void 0 ? data.only : only) ? `ONLY ${sql}` : sql;
@@ -7381,38 +7346,55 @@ const pushUpdateSql = (ctx, table, query, quotedAs) => {
7381
7346
  if (query.hookUpdateSet) {
7382
7347
  applySet(ctx, table, set, hookSet, emptyObject, quotedAs);
7383
7348
  }
7349
+ let hookSelect;
7350
+ const delayedRelationSelect = query.selectRelation ? newDelayedRelationSelect(table) : void 0;
7384
7351
  if (!set.length) {
7385
7352
  if (!query.select) {
7386
7353
  query.select = countSelect;
7387
7354
  }
7388
- const hookSelect = pushUpdateReturning(
7355
+ hookSelect = pushUpdateReturning(
7389
7356
  ctx,
7390
7357
  table,
7391
7358
  query,
7392
7359
  quotedAs,
7393
- "SELECT"
7360
+ "SELECT",
7361
+ delayedRelationSelect
7394
7362
  );
7395
7363
  ctx.sql.push(`FROM ${quotedTable}`);
7396
7364
  pushWhereStatementSql(ctx, table, query, quotedAs);
7397
7365
  pushLimitSQL(ctx.sql, ctx.values, query);
7398
- return hookSelect;
7399
- }
7400
- ctx.sql.push(`UPDATE ${quotedTable}`);
7401
- if (quotedTable !== quotedAs) {
7402
- ctx.sql.push(quotedAs);
7366
+ } else {
7367
+ ctx.sql.push(`UPDATE ${quotedTable}`);
7368
+ if (quotedTable !== quotedAs) {
7369
+ ctx.sql.push(quotedAs);
7370
+ }
7371
+ ctx.sql.push("SET");
7372
+ ctx.sql.push(set.join(", "));
7373
+ pushWhereStatementSql(ctx, table, query, quotedAs);
7374
+ hookSelect = pushUpdateReturning(
7375
+ ctx,
7376
+ table,
7377
+ query,
7378
+ quotedAs,
7379
+ "RETURNING",
7380
+ delayedRelationSelect
7381
+ );
7403
7382
  }
7404
- ctx.sql.push("SET");
7405
- ctx.sql.push(set.join(", "));
7406
- pushWhereStatementSql(ctx, table, query, quotedAs);
7407
- return pushUpdateReturning(ctx, table, query, quotedAs, "RETURNING");
7383
+ return {
7384
+ hookSelect,
7385
+ delayedRelationSelect,
7386
+ text: ctx.sql.join(" "),
7387
+ values: ctx.values
7388
+ };
7408
7389
  };
7409
- const pushUpdateReturning = (ctx, table, query, quotedAs, keyword) => {
7390
+ const pushUpdateReturning = (ctx, table, query, quotedAs, keyword, delayedRelationSelect) => {
7410
7391
  const { inCTE } = query;
7411
7392
  const { select, hookSelect } = makeReturningSql(
7412
7393
  ctx,
7413
7394
  table,
7414
7395
  query,
7415
7396
  quotedAs,
7397
+ delayedRelationSelect,
7416
7398
  1,
7417
7399
  inCTE && 2
7418
7400
  );
@@ -7480,7 +7462,11 @@ const pushDeleteSql = (ctx, table, query, quotedAs) => {
7480
7462
  const ons = [];
7481
7463
  const joinSet = query.join.length > 1 ? /* @__PURE__ */ new Set() : null;
7482
7464
  for (const item of query.join) {
7483
- if (Array.isArray(item)) {
7465
+ const lateral = "l" in item.args && item.args.l;
7466
+ if (lateral) {
7467
+ if (isRelationQuery(lateral)) {
7468
+ continue;
7469
+ }
7484
7470
  throw new OrchidOrmInternalError(
7485
7471
  table,
7486
7472
  "Join lateral is not supported in delete"
@@ -7508,9 +7494,22 @@ const pushDeleteSql = (ctx, table, query, quotedAs) => {
7508
7494
  ctx.sql.push("WHERE", conditions);
7509
7495
  }
7510
7496
  }
7511
- const returning = makeReturningSql(ctx, table, query, quotedAs, 3);
7497
+ const delayedRelationSelect = query.selectRelation ? newDelayedRelationSelect(table) : void 0;
7498
+ const returning = makeReturningSql(
7499
+ ctx,
7500
+ table,
7501
+ query,
7502
+ quotedAs,
7503
+ delayedRelationSelect,
7504
+ 3
7505
+ );
7512
7506
  if (returning.select) ctx.sql.push("RETURNING", returning.select);
7513
- return returning.hookSelect;
7507
+ return {
7508
+ hookSelect: returning.hookSelect,
7509
+ delayedRelationSelect,
7510
+ text: ctx.sql.join(" "),
7511
+ values: ctx.values
7512
+ };
7514
7513
  };
7515
7514
 
7516
7515
  const pushTruncateSql = (ctx, table, query) => {
@@ -7582,126 +7581,137 @@ const toSQL = (table, options) => {
7582
7581
  sql,
7583
7582
  values,
7584
7583
  aliasValue: options?.aliasValue,
7585
- skipBatchCheck: options?.skipBatchCheck
7584
+ skipBatchCheck: options?.skipBatchCheck,
7585
+ hasNonSelect: options?.hasNonSelect
7586
7586
  };
7587
7587
  if (query.with) {
7588
7588
  pushWithSql(ctx, query.with);
7589
7589
  }
7590
+ let result;
7590
7591
  let fromQuery;
7591
7592
  if (query.type && query.type !== "upsert") {
7592
7593
  const tableName = table.table ?? query.as;
7593
7594
  if (!tableName) throw new Error(`Table is missing for ${query.type}`);
7594
7595
  if (query.type === "truncate") {
7595
7596
  pushTruncateSql(ctx, tableName, query);
7596
- return { text: sql.join(" "), values };
7597
- }
7598
- if (query.type === "columnInfo") {
7597
+ result = { text: sql.join(" "), values };
7598
+ } else if (query.type === "columnInfo") {
7599
7599
  pushColumnInfoSql(ctx, table, query);
7600
- return { text: sql.join(" "), values };
7601
- }
7602
- const quotedAs2 = `"${query.as || tableName}"`;
7603
- if (query.type === "insert") {
7604
- return makeInsertSql(ctx, table, query, `"${tableName}"`);
7605
- }
7606
- if (query.type === "update") {
7607
- return {
7608
- hookSelect: pushUpdateSql(ctx, table, query, quotedAs2),
7609
- text: sql.join(" "),
7610
- values
7611
- };
7612
- }
7613
- if (query.type === "delete") {
7614
- return {
7615
- hookSelect: pushDeleteSql(ctx, table, query, quotedAs2),
7616
- text: sql.join(" "),
7617
- values
7618
- };
7619
- }
7620
- if (query.type === "copy") {
7621
- pushCopySql(ctx, table, query, quotedAs2);
7622
- return { text: sql.join(" "), values };
7623
- }
7624
- }
7625
- const quotedAs = (query.as || table.table) && `"${query.as || table.table}"`;
7626
- if (query.union) {
7627
- const s = getSqlText(toSQL(query.union.b, { values }));
7628
- sql.push(query.union.p ? s : `(${s})`);
7629
- for (const u of query.union.u) {
7630
- const s2 = isExpression(u.a) ? u.a.toSQL(ctx, quotedAs) : getSqlText(toSQL(u.a, { values }));
7631
- sql.push(`${u.k} ${u.p ? s2 : "(" + s2 + ")"}`);
7600
+ result = { text: sql.join(" "), values };
7601
+ } else {
7602
+ const quotedAs = `"${query.as || tableName}"`;
7603
+ if (query.type === "insert") {
7604
+ result = makeInsertSql(ctx, table, query, `"${tableName}"`);
7605
+ } else if (query.type === "update") {
7606
+ result = pushUpdateSql(ctx, table, query, quotedAs);
7607
+ } else if (query.type === "delete") {
7608
+ result = pushDeleteSql(ctx, table, query, quotedAs);
7609
+ } else if (query.type === "copy") {
7610
+ pushCopySql(ctx, table, query, quotedAs);
7611
+ result = { text: sql.join(" "), values };
7612
+ } else {
7613
+ throw new Error(`Unsupported query type ${query.type}`);
7614
+ }
7632
7615
  }
7633
7616
  } else {
7634
- sql.push("SELECT");
7635
- if (query.distinct) {
7636
- pushDistinctSql(ctx, table, query.distinct, quotedAs);
7637
- }
7638
- const aliases = query.group ? [] : void 0;
7639
- pushSelectSql(ctx, table, query, quotedAs, aliases);
7640
- fromQuery = (table.table || query.from) && pushFromAndAs(ctx, table, query, quotedAs) || void 0;
7641
- if (query.join) {
7642
- pushJoinSql(
7643
- ctx,
7644
- table,
7645
- query,
7646
- quotedAs
7647
- );
7648
- }
7649
- if (query.and || query.or || query.scopes) {
7650
- pushWhereStatementSql(ctx, table, query, quotedAs);
7651
- }
7652
- if (query.group) {
7653
- const group = query.group.map((item) => {
7654
- if (isExpression(item)) {
7655
- return item.toSQL(ctx, quotedAs);
7656
- } else {
7657
- const i = aliases.indexOf(item);
7658
- return i !== -1 ? i + 1 : columnToSql(ctx, table.q, table.shape, item, quotedAs);
7659
- }
7660
- });
7661
- sql.push(`GROUP BY ${group.join(", ")}`);
7662
- }
7663
- if (query.having) pushHavingSql(ctx, query, quotedAs);
7664
- if (query.window) {
7665
- const window = [];
7666
- for (const item of query.window) {
7667
- for (const key in item) {
7668
- window.push(
7669
- `"${key}" AS ${windowToSql(ctx, query, item[key], quotedAs)}`
7670
- );
7617
+ const quotedAs = (query.as || table.table) && `"${query.as || table.table}"`;
7618
+ if (query.union) {
7619
+ const firstSql = toSQL(query.union.b, ctx);
7620
+ ctx.delayedRelationSelect = firstSql.delayedRelationSelect;
7621
+ const s = getSqlText(firstSql);
7622
+ sql.push(query.union.p ? s : `(${s})`);
7623
+ for (const u of query.union.u) {
7624
+ const s2 = isExpression(u.a) ? u.a.toSQL(ctx, quotedAs) : getSqlText(toSQL(u.a, ctx));
7625
+ sql.push(`${u.k} ${u.p ? s2 : "(" + s2 + ")"}`);
7626
+ }
7627
+ } else {
7628
+ sql.push("SELECT");
7629
+ if (query.distinct) {
7630
+ pushDistinctSql(ctx, table, query.distinct, quotedAs);
7631
+ }
7632
+ const aliases = query.group ? [] : void 0;
7633
+ pushSelectSql(ctx, table, query, quotedAs, aliases);
7634
+ fromQuery = (table.table || query.from) && pushFromAndAs(ctx, table, query, quotedAs) || void 0;
7635
+ if (query.join) {
7636
+ pushJoinSql(
7637
+ ctx,
7638
+ table,
7639
+ query,
7640
+ quotedAs
7641
+ );
7642
+ }
7643
+ if (query.and || query.or || query.scopes) {
7644
+ pushWhereStatementSql(ctx, table, query, quotedAs);
7645
+ }
7646
+ if (query.group) {
7647
+ const group = query.group.map((item) => {
7648
+ if (isExpression(item)) {
7649
+ return item.toSQL(ctx, quotedAs);
7650
+ } else {
7651
+ const i = aliases.indexOf(item);
7652
+ return i !== -1 ? i + 1 : columnToSql(
7653
+ ctx,
7654
+ table.q,
7655
+ table.shape,
7656
+ item,
7657
+ quotedAs
7658
+ );
7659
+ }
7660
+ });
7661
+ sql.push(`GROUP BY ${group.join(", ")}`);
7662
+ }
7663
+ if (query.having) pushHavingSql(ctx, query, quotedAs);
7664
+ if (query.window) {
7665
+ const window = [];
7666
+ for (const item of query.window) {
7667
+ for (const key in item) {
7668
+ window.push(
7669
+ `"${key}" AS ${windowToSql(ctx, query, item[key], quotedAs)}`
7670
+ );
7671
+ }
7671
7672
  }
7673
+ sql.push(`WINDOW ${window.join(", ")}`);
7672
7674
  }
7673
- sql.push(`WINDOW ${window.join(", ")}`);
7674
- }
7675
- }
7676
- if (query.order) {
7677
- pushOrderBySql(ctx, query, quotedAs, query.order);
7678
- }
7679
- if (query.useFromLimitOffset) {
7680
- const q = fromQuery?.q;
7681
- if (q.limit) {
7682
- sql.push(`LIMIT ${addValue(values, q.limit)}`);
7683
7675
  }
7684
- if (q.offset) {
7685
- sql.push(`OFFSET ${addValue(values, q.offset)}`);
7676
+ if (query.order) {
7677
+ pushOrderBySql(ctx, query, quotedAs, query.order);
7686
7678
  }
7687
- } else {
7688
- pushLimitSQL(sql, values, query);
7689
- if (query.offset && !query.returnsOne) {
7690
- sql.push(`OFFSET ${addValue(values, query.offset)}`);
7679
+ if (query.useFromLimitOffset) {
7680
+ const q = fromQuery?.q;
7681
+ if (q.limit) {
7682
+ sql.push(`LIMIT ${addValue(values, q.limit)}`);
7683
+ }
7684
+ if (q.offset) {
7685
+ sql.push(`OFFSET ${addValue(values, q.offset)}`);
7686
+ }
7687
+ } else {
7688
+ pushLimitSQL(sql, values, query);
7689
+ if (query.offset && !query.returnsOne) {
7690
+ sql.push(`OFFSET ${addValue(values, query.offset)}`);
7691
+ }
7692
+ }
7693
+ if (query.for) {
7694
+ sql.push("FOR", query.for.type);
7695
+ const { tableNames } = query.for;
7696
+ if (tableNames) {
7697
+ sql.push(
7698
+ "OF",
7699
+ isExpression(tableNames) ? tableNames.toSQL(ctx, quotedAs) : tableNames.map((x) => `"${x}"`).join(", ")
7700
+ );
7701
+ }
7702
+ if (query.for.mode) sql.push(query.for.mode);
7691
7703
  }
7704
+ result = {
7705
+ text: sql.join(" "),
7706
+ values,
7707
+ hookSelect: query.hookSelect,
7708
+ delayedRelationSelect: ctx.delayedRelationSelect
7709
+ };
7692
7710
  }
7693
- if (query.for) {
7694
- sql.push("FOR", query.for.type);
7695
- const { tableNames } = query.for;
7696
- if (tableNames) {
7697
- sql.push(
7698
- "OF",
7699
- isExpression(tableNames) ? tableNames.toSQL(ctx, quotedAs) : tableNames.map((x) => `"${x}"`).join(", ")
7700
- );
7701
- }
7702
- if (query.for.mode) sql.push(query.for.mode);
7711
+ if (options && (query.type || ctx.hasNonSelect)) {
7712
+ options.hasNonSelect = true;
7703
7713
  }
7704
- return { text: sql.join(" "), values, hookSelect: query.hookSelect };
7714
+ return result;
7705
7715
  };
7706
7716
  function pushLimitSQL(sql, values, q) {
7707
7717
  if (!q.returnsOne) {
@@ -8528,6 +8538,24 @@ class AggregateMethods {
8528
8538
  }
8529
8539
  }
8530
8540
 
8541
+ class QueryAsMethods {
8542
+ /**
8543
+ * Sets table alias:
8544
+ *
8545
+ * ```ts
8546
+ * db.table.as('u').select('u.name');
8547
+ *
8548
+ * // Can be used in the join:
8549
+ * db.table.join(Profile.as('p'), 'p.userId', 'user.id');
8550
+ * ```
8551
+ *
8552
+ * @param as - alias for the table of this query
8553
+ */
8554
+ as(as) {
8555
+ return _setQueryAs(_clone(this), as);
8556
+ }
8557
+ }
8558
+
8531
8559
  class Clear {
8532
8560
  clear(...clears) {
8533
8561
  const q = _clone(this);
@@ -8571,7 +8599,7 @@ const _queryUnion = (base, args, k, p, m) => {
8571
8599
  m
8572
8600
  })
8573
8601
  );
8574
- const q = query.q;
8602
+ const { q } = query;
8575
8603
  const baseQ = base.q;
8576
8604
  q.union = baseQ.union ? {
8577
8605
  ...baseQ.union,
@@ -8725,7 +8753,7 @@ const addWith = (q, withStore, item, key = "with") => {
8725
8753
  }
8726
8754
  pushOrNewArrayToObjectImmutable(withStore, key, item);
8727
8755
  };
8728
- const moveQueryValueToWith = (q, withStore, value, set, key, withKey) => {
8756
+ const moveQueryValueToWith = (q, withStore, value, withKey, set, key) => {
8729
8757
  if (value.q.type) {
8730
8758
  const as = saveAliasedShape(q, "q", "withShapes");
8731
8759
  addWith(
@@ -8737,8 +8765,12 @@ const moveQueryValueToWith = (q, withStore, value, set, key, withKey) => {
8737
8765
  },
8738
8766
  withKey
8739
8767
  );
8740
- set[key] = new RawSQL(`(SELECT * FROM "${as}")`);
8768
+ if (set) {
8769
+ set[key] = new RawSQL(`(SELECT * FROM "${as}")`);
8770
+ }
8771
+ return as;
8741
8772
  }
8773
+ return;
8742
8774
  };
8743
8775
  class WithMethods {
8744
8776
  with(name, second, third) {
@@ -8837,9 +8869,9 @@ const processCreateItem = (q, item, rowIndex, ctx, encoders) => {
8837
8869
  q,
8838
8870
  (_a = q.q).insertWith ?? (_a.insertWith = {}),
8839
8871
  value,
8872
+ rowIndex,
8840
8873
  item,
8841
- key,
8842
- rowIndex
8874
+ key
8843
8875
  );
8844
8876
  }
8845
8877
  }
@@ -9731,9 +9763,7 @@ const _queryHookBeforeCreate = (q, cb) => {
9731
9763
  return before(
9732
9764
  q,
9733
9765
  "Create",
9734
- (q2) => cb(
9735
- new QueryHookUtils(q2, q2.q.columns, "hookCreateSet")
9736
- )
9766
+ (q2) => cb(new QueryHookUtils(q2, q2.q.columns, "hookCreateSet"))
9737
9767
  );
9738
9768
  };
9739
9769
  const _queryHookAfterCreate = (q, select, cb) => {
@@ -10890,9 +10920,9 @@ const _queryUpdate = (query, arg) => {
10890
10920
  query,
10891
10921
  q,
10892
10922
  value,
10923
+ "with",
10893
10924
  set,
10894
- key,
10895
- "with"
10925
+ key
10896
10926
  );
10897
10927
  } else {
10898
10928
  const encode = item?.data.encode;
@@ -10903,17 +10933,25 @@ const _queryUpdate = (query, arg) => {
10903
10933
  }
10904
10934
  const { queries } = ctx;
10905
10935
  if (queries) {
10936
+ const primaryKeys = requirePrimaryKeys(
10937
+ query,
10938
+ "Cannot perform complex update on a table without primary keys"
10939
+ );
10940
+ const hookSelect = q.hookSelect = new Map(q.hookSelect);
10941
+ for (const column of primaryKeys) {
10942
+ hookSelect.set(column, { select: column });
10943
+ }
10906
10944
  q.patchResult = async (_, _h, queryResult) => {
10907
10945
  await Promise.all(queries.map(callWithThis, queryResult));
10908
10946
  if (ctx.collect) {
10909
10947
  const t = query.baseQuery.clone();
10910
- const { keys } = ctx.collect;
10911
10948
  _queryWhereIn(
10912
10949
  t,
10913
- keys,
10914
- queryResult.rows.map((item) => keys.map((key) => item[key]))
10950
+ true,
10951
+ primaryKeys,
10952
+ queryResult.rows.map((item) => primaryKeys.map((key) => item[key]))
10915
10953
  );
10916
- _queryUpdate(
10954
+ await _queryUpdate(
10917
10955
  t,
10918
10956
  ctx.collect.data
10919
10957
  );
@@ -11513,7 +11551,10 @@ function orCreate(query, data, updateData, mergeData) {
11513
11551
  }
11514
11552
  const inCTE = {
11515
11553
  selectNum: !!(hasAfterCallback || hasAfterCommitCallback),
11516
- targetHookSelect: hookSelect
11554
+ targetHookSelect: hookSelect,
11555
+ delayedRelationSelect: newDelayedRelationSelect(
11556
+ query
11557
+ )
11517
11558
  };
11518
11559
  q2 = q2.clone();
11519
11560
  q2.q.inCTE = inCTE;
@@ -12439,7 +12480,7 @@ class QueryMethods {
12439
12480
  */
12440
12481
  truncate(options) {
12441
12482
  const query = _clone(this);
12442
- const q = query.q;
12483
+ const { q } = query;
12443
12484
  q.type = "truncate";
12444
12485
  if (options?.restartIdentity) {
12445
12486
  q.restartIdentity = true;
@@ -12569,11 +12610,12 @@ class QueryMethods {
12569
12610
  * @param fn - helper function
12570
12611
  */
12571
12612
  makeHelper(fn) {
12572
- const as = this.q.as || this.table;
12613
+ const helperAs = this.q.as || this.table;
12573
12614
  return (query, ...args) => {
12574
12615
  const q = _clone(query);
12575
- if (q.q.as) {
12576
- setQueryObjectValueImmutable(q, "aliases", as, q.q.as);
12616
+ const as = _getQueryAs(q);
12617
+ if (as) {
12618
+ _setQueryAlias(q, as, helperAs);
12577
12619
  }
12578
12620
  return fn(q, ...args);
12579
12621
  };
@@ -12679,7 +12721,7 @@ class QueryMethods {
12679
12721
  Object.assign(QueryMethods.prototype, QueryUpsert);
12680
12722
  Object.assign(QueryMethods.prototype, QueryOrCreate);
12681
12723
  applyMixins(QueryMethods, [
12682
- AsMethods,
12724
+ QueryAsMethods,
12683
12725
  AggregateMethods,
12684
12726
  Select,
12685
12727
  FromMethods,
@@ -13118,22 +13160,6 @@ class Db extends QueryMethods {
13118
13160
  queryArrays(...args) {
13119
13161
  return performQuery(this, args, "arrays");
13120
13162
  }
13121
- /**
13122
- * In snake case mode, or when columns have custom names,
13123
- * use this method to exchange a db column name to its runtime key.
13124
- */
13125
- columnNameToKey(name) {
13126
- let map = this.internal.columnNameToKeyMap;
13127
- if (!map) {
13128
- this.internal.columnNameToKeyMap = map = /* @__PURE__ */ new Map();
13129
- const { shape } = this;
13130
- for (const key in this.shape) {
13131
- const column = shape[key];
13132
- map.set(column.data.name ?? key, key);
13133
- }
13134
- }
13135
- return map.get(name);
13136
- }
13137
13163
  }
13138
13164
  applyMixins(Db, [QueryMethods]);
13139
13165
  Db.prototype.constructor = Db;
@@ -13342,5 +13368,5 @@ function copyTableData(query, arg) {
13342
13368
  return q;
13343
13369
  }
13344
13370
 
13345
- export { Adapter, AfterCommitError, AggregateMethods, ArrayColumn, AsMethods, BigIntColumn, BigSerialColumn, BitColumn, BitVaryingColumn, BooleanColumn, BoxColumn, ByteaColumn, CidrColumn, CircleColumn, CitextColumn, Clear, ColumnRefExpression, ColumnType, ComputedColumn, CustomTypeColumn, DateBaseColumn, DateColumn, DateTimeBaseClass, DateTimeTzBaseClass, Db, DecimalColumn, Delete, DomainColumn, DoublePrecisionColumn, DynamicRawSQL, EnumColumn, ExpressionMethods, FnExpression, For, FromMethods, Having, InetColumn, IntegerBaseColumn, IntegerColumn, IntervalColumn, JSONColumn, JSONTextColumn, Join, JsonMethods, LimitedTextBaseColumn, LineColumn, LsegColumn, MacAddr8Column, MacAddrColumn, MergeQueryMethods, MoneyColumn, MoreThanOneRowError, NotFoundError, NumberAsStringBaseColumn, NumberBaseColumn, OnConflictQueryBuilder, OnMethods, Operators, OrExpression, OrchidOrmError, OrchidOrmInternalError, PathColumn, PointColumn, PolygonColumn, PostgisGeographyPointColumn, QueryCreate, QueryError, QueryGet, QueryHooks, QueryLog, QueryMethods, QueryUpsert, RawSQL, RealColumn, RefExpression, SearchMethods, Select, SerialColumn, SmallIntColumn, SmallSerialColumn, SqlMethod, StringColumn, TextBaseColumn, TextColumn, Then, TimeColumn, TimestampColumn, TimestampTZColumn, Transaction, TransactionAdapter, TransformMethods, TsQueryColumn, TsVectorColumn, UUIDColumn, UnhandledTypeError, Union, UnknownColumn, Update, VarCharColumn, VirtualColumn, Where, WithMethods, XMLColumn, _clone, _getSelectableColumn, _initQueryBuilder, _queryAfterSaveCommit, _queryAll, _queryAs, _queryChangeCounter, _queryCreate, _queryCreateFrom, _queryCreateMany, _queryCreateManyFrom, _queryDefaults, _queryDelete, _queryExec, _queryFindBy, _queryFindByOptional, _queryGet, _queryGetOptional, _queryHookAfterCreate, _queryHookAfterCreateCommit, _queryHookAfterDelete, _queryHookAfterDeleteCommit, _queryHookAfterQuery, _queryHookAfterSave, _queryHookAfterUpdate, _queryHookAfterUpdateCommit, _queryHookBeforeCreate, _queryHookBeforeDelete, _queryHookBeforeQuery, _queryHookBeforeSave, _queryHookBeforeUpdate, _queryInsert, _queryInsertFrom, _queryInsertMany, _queryInsertManyFrom, _queryJoinOn, _queryJoinOnJsonPathEquals, _queryJoinOrOn, _queryOr, _queryOrNot, _queryResolveAlias, _queryRows, _querySelect, _queryTake, _queryTakeOptional, _queryUnion, _queryUpdate, _queryUpdateOrThrow, _queryWhere, _queryWhereExists, _queryWhereIn, _queryWhereNot, _queryWhereNotOneOf, _queryWhereNotSql, _queryWhereOneOf, _queryWhereSql, _runAfterCommitHooks, addColumnParserToQuery, addParserForRawExpression, addParserForSelectItem, addQueryOn, anyShape, applyComputedColumns, assignDbDataToColumn, checkIfASimpleQuery, cloneQueryBaseUnscoped, columnCheckToCode, columnCode, columnExcludesToCode, columnForeignKeysToCode, columnIndexesToCode, columnsShapeToCode, commitSql$1 as commitSql, constraintInnerToCode, constraintToCode, copyTableData, countSelect, createDb, defaultSchemaConfig, escapeForLog, escapeForMigration, escapeString, excludeInnerToCode, excludeToCode, extendQuery, filterResult, foreignKeyArgumentToCode, getClonedQueryData, getColumnBaseType, getColumnInfo, getColumnTypes, getFullColumnTable, getPrimaryKeys, getQueryAs, getShapeFromSelect, getSqlText, handleResult, identityToCode, indexInnerToCode, indexToCode, isDefaultTimeStamp, isInUserTransaction, isQueryReturnsAll, isSelectingCount, joinSubQuery, logParamToLogObject, makeColumnTypes, makeColumnsByType, makeFnExpression, moveQueryValueToWith, parseRecord, parseTableData, parseTableDataInput, postgisTypmodToSql, primaryKeyInnerToCode, processComputedBatches, processComputedResult, processSelectArg, pushLimitSQL, pushQueryArrayImmutable, pushQueryOn, pushQueryOnForOuter, pushQueryOrOn, pushTableDataCode, queryFrom, queryFromSql, queryJson, queryMethodByReturnType, queryTypeWithLimitOne, queryWrap, raw, referencesArgsToCode, resolveSubQueryCallbackV2, rollbackSql$1 as rollbackSql, saveAliasedShape, setColumnDefaultParse, setColumnEncode, setColumnParse, setColumnParseNull, setParserForSelectedString, setQueryObjectValueImmutable, setQueryOperators, simplifyColumnDefault, sqlFn, sqlQueryArgsToExpression, tableDataMethods, templateLiteralToSQL, testTransaction, throwIfJoinLateral, throwIfNoWhere, toSQL };
13371
+ export { Adapter, AfterCommitError, AggregateMethods, ArrayColumn, BigIntColumn, BigSerialColumn, BitColumn, BitVaryingColumn, BooleanColumn, BoxColumn, ByteaColumn, CidrColumn, CircleColumn, CitextColumn, Clear, ColumnRefExpression, ColumnType, ComputedColumn, CustomTypeColumn, DateBaseColumn, DateColumn, DateTimeBaseClass, DateTimeTzBaseClass, Db, DecimalColumn, Delete, DomainColumn, DoublePrecisionColumn, DynamicRawSQL, EnumColumn, ExpressionMethods, FnExpression, For, FromMethods, Having, InetColumn, IntegerBaseColumn, IntegerColumn, IntervalColumn, JSONColumn, JSONTextColumn, Join, JsonMethods, LimitedTextBaseColumn, LineColumn, LsegColumn, MacAddr8Column, MacAddrColumn, MergeQueryMethods, MoneyColumn, NumberAsStringBaseColumn, NumberBaseColumn, OnConflictQueryBuilder, OnMethods, Operators, OrExpression, PathColumn, PointColumn, PolygonColumn, PostgisGeographyPointColumn, QueryAsMethods, QueryCreate, QueryGet, QueryHooks, QueryLog, QueryMethods, QueryUpsert, RawSQL, RealColumn, RefExpression, SearchMethods, Select, SerialColumn, SmallIntColumn, SmallSerialColumn, SqlMethod, StringColumn, TextBaseColumn, TextColumn, Then, TimeColumn, TimestampColumn, TimestampTZColumn, Transaction, TransactionAdapter, TransformMethods, TsQueryColumn, TsVectorColumn, UUIDColumn, Union, UnknownColumn, Update, VarCharColumn, VirtualColumn, Where, WithMethods, XMLColumn, _clone, _getSelectableColumn, _initQueryBuilder, _queryAfterSaveCommit, _queryAll, _queryChangeCounter, _queryCreate, _queryCreateFrom, _queryCreateMany, _queryCreateManyFrom, _queryDefaults, _queryDelete, _queryExec, _queryFindBy, _queryFindByOptional, _queryGet, _queryGetOptional, _queryHookAfterCreate, _queryHookAfterCreateCommit, _queryHookAfterDelete, _queryHookAfterDeleteCommit, _queryHookAfterQuery, _queryHookAfterSave, _queryHookAfterUpdate, _queryHookAfterUpdateCommit, _queryHookBeforeCreate, _queryHookBeforeDelete, _queryHookBeforeQuery, _queryHookBeforeSave, _queryHookBeforeUpdate, _queryInsert, _queryInsertFrom, _queryInsertMany, _queryInsertManyFrom, _queryJoinOn, _queryJoinOnJsonPathEquals, _queryJoinOrOn, _queryOr, _queryOrNot, _queryRows, _querySelect, _queryTake, _queryTakeOptional, _queryUnion, _queryUpdate, _queryUpdateOrThrow, _queryWhere, _queryWhereExists, _queryWhereIn, _queryWhereNot, _queryWhereNotOneOf, _queryWhereNotSql, _queryWhereOneOf, _queryWhereSql, _runAfterCommitHooks, addColumnParserToQuery, addParserForRawExpression, addParserForSelectItem, addQueryOn, anyShape, applyComputedColumns, assignDbDataToColumn, checkIfASimpleQuery, cloneQueryBaseUnscoped, columnCheckToCode, columnCode, columnExcludesToCode, columnForeignKeysToCode, columnIndexesToCode, columnsShapeToCode, commitSql$1 as commitSql, constraintInnerToCode, constraintToCode, copyTableData, countSelect, createDb, defaultSchemaConfig, escapeForLog, escapeForMigration, escapeString, excludeInnerToCode, excludeToCode, extendQuery, filterResult, foreignKeyArgumentToCode, getClonedQueryData, getColumnBaseType, getColumnInfo, getColumnTypes, getFullColumnTable, getQueryAs, getShapeFromSelect, getSqlText, handleResult, identityToCode, indexInnerToCode, indexToCode, isDefaultTimeStamp, isInUserTransaction, isQueryReturnsAll, isSelectingCount, joinSubQuery, logParamToLogObject, makeColumnTypes, makeColumnsByType, makeFnExpression, moveQueryValueToWith, parseRecord, parseTableData, parseTableDataInput, postgisTypmodToSql, primaryKeyInnerToCode, processComputedBatches, processComputedResult, processSelectArg, pushLimitSQL, pushQueryArrayImmutable, pushQueryOn, pushQueryOnForOuter, pushQueryOrOn, pushTableDataCode, queryFrom, queryFromSql, queryJson, queryMethodByReturnType, queryTypeWithLimitOne, queryWrap, raw, referencesArgsToCode, resolveSubQueryCallbackV2, rollbackSql$1 as rollbackSql, saveAliasedShape, setColumnDefaultParse, setColumnEncode, setColumnParse, setColumnParseNull, setParserForSelectedString, setQueryObjectValueImmutable, setQueryOperators, simplifyColumnDefault, sqlFn, sqlQueryArgsToExpression, tableDataMethods, templateLiteralToSQL, testTransaction, throwIfJoinLateral, throwIfNoWhere, toSQL };
13346
13372
  //# sourceMappingURL=index.mjs.map