pqb 0.49.1 → 0.51.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.d.ts +35 -20
- package/dist/index.js +223 -194
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +223 -194
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1941,9 +1941,9 @@ const collectPrimaryKeys = (q) => {
|
|
|
1941
1941
|
primaryKeys.push(key);
|
|
1942
1942
|
}
|
|
1943
1943
|
}
|
|
1944
|
-
const
|
|
1945
|
-
if (
|
|
1946
|
-
primaryKeys.push(...
|
|
1944
|
+
const pkey = q.internal.tableData.primaryKey;
|
|
1945
|
+
if (pkey) {
|
|
1946
|
+
primaryKeys.push(...pkey.columns);
|
|
1947
1947
|
}
|
|
1948
1948
|
return primaryKeys;
|
|
1949
1949
|
};
|
|
@@ -2224,11 +2224,18 @@ const _join = (query, require, type, first, args) => {
|
|
|
2224
2224
|
let joinSubQuery = false;
|
|
2225
2225
|
first = preprocessJoinArg(query, first);
|
|
2226
2226
|
if (typeof first === "object") {
|
|
2227
|
+
let isInternalJoin;
|
|
2228
|
+
if ("_internalJoin" in first) {
|
|
2229
|
+
isInternalJoin = true;
|
|
2230
|
+
first = first._internalJoin;
|
|
2231
|
+
}
|
|
2227
2232
|
if (require && isQueryNone(first)) {
|
|
2228
2233
|
return _queryNone(query);
|
|
2229
2234
|
}
|
|
2230
2235
|
const q = first;
|
|
2231
|
-
|
|
2236
|
+
if (!isInternalJoin) {
|
|
2237
|
+
joinSubQuery = getIsJoinSubQuery(q);
|
|
2238
|
+
}
|
|
2232
2239
|
joinKey = q.q.as || q.table;
|
|
2233
2240
|
if (joinKey) {
|
|
2234
2241
|
shape = getShapeFromSelect(q, joinSubQuery && !!q.q.select);
|
|
@@ -3715,6 +3722,171 @@ const filterAllResult = (result, tempColumns, hasAfterHook) => {
|
|
|
3715
3722
|
return result;
|
|
3716
3723
|
};
|
|
3717
3724
|
|
|
3725
|
+
const _queryAs = (self, as) => {
|
|
3726
|
+
const { q } = self;
|
|
3727
|
+
q.as = as;
|
|
3728
|
+
q.aliases = {
|
|
3729
|
+
...q.aliases,
|
|
3730
|
+
[as]: q.aliases ? _queryResolveAlias(q.aliases, as) : as
|
|
3731
|
+
};
|
|
3732
|
+
return self;
|
|
3733
|
+
};
|
|
3734
|
+
const _queryResolveAlias = (aliases, as) => {
|
|
3735
|
+
if (!aliases[as]) return as;
|
|
3736
|
+
let suffix = 2;
|
|
3737
|
+
let privateAs;
|
|
3738
|
+
while (aliases[privateAs = as + suffix]) {
|
|
3739
|
+
suffix++;
|
|
3740
|
+
}
|
|
3741
|
+
return privateAs;
|
|
3742
|
+
};
|
|
3743
|
+
class AsMethods {
|
|
3744
|
+
/**
|
|
3745
|
+
* Sets table alias:
|
|
3746
|
+
*
|
|
3747
|
+
* ```ts
|
|
3748
|
+
* db.table.as('u').select('u.name');
|
|
3749
|
+
*
|
|
3750
|
+
* // Can be used in the join:
|
|
3751
|
+
* db.table.join(Profile.as('p'), 'p.userId', 'user.id');
|
|
3752
|
+
* ```
|
|
3753
|
+
*
|
|
3754
|
+
* @param as - alias for the table of this query
|
|
3755
|
+
*/
|
|
3756
|
+
as(as) {
|
|
3757
|
+
return _queryAs(_clone(this), as);
|
|
3758
|
+
}
|
|
3759
|
+
}
|
|
3760
|
+
|
|
3761
|
+
function queryFrom(self, arg) {
|
|
3762
|
+
const data = self.q;
|
|
3763
|
+
if (typeof arg === "string") {
|
|
3764
|
+
data.as || (data.as = arg);
|
|
3765
|
+
const w = data.withShapes?.[arg];
|
|
3766
|
+
data.shape = w?.shape ?? emptyObject;
|
|
3767
|
+
data.computeds = w?.computeds;
|
|
3768
|
+
} else if (isExpression(arg)) {
|
|
3769
|
+
data.as || (data.as = "t");
|
|
3770
|
+
} else if (Array.isArray(arg)) {
|
|
3771
|
+
const { shape } = data;
|
|
3772
|
+
let clonedParsers = false;
|
|
3773
|
+
for (const item of arg) {
|
|
3774
|
+
if (typeof item === "string") {
|
|
3775
|
+
const w = data.withShapes[item];
|
|
3776
|
+
Object.assign(shape, w.shape);
|
|
3777
|
+
if (w.computeds) data.computeds = { ...data.computeds, ...w.computeds };
|
|
3778
|
+
for (const key in w.shape) {
|
|
3779
|
+
addColumnParserToQuery(
|
|
3780
|
+
self,
|
|
3781
|
+
key,
|
|
3782
|
+
w.shape[key]
|
|
3783
|
+
);
|
|
3784
|
+
}
|
|
3785
|
+
} else if (!isExpression(item)) {
|
|
3786
|
+
Object.assign(shape, getShapeFromSelect(item, true));
|
|
3787
|
+
if (!clonedParsers) {
|
|
3788
|
+
data.parsers = { ...data.parsers };
|
|
3789
|
+
clonedParsers = true;
|
|
3790
|
+
}
|
|
3791
|
+
Object.assign(data.parsers, item.q.parsers);
|
|
3792
|
+
}
|
|
3793
|
+
}
|
|
3794
|
+
} else {
|
|
3795
|
+
const q = arg;
|
|
3796
|
+
data.as || (data.as = q.q.as || q.table || "t");
|
|
3797
|
+
data.shape = getShapeFromSelect(q, true);
|
|
3798
|
+
data.parsers = q.q.parsers;
|
|
3799
|
+
data.batchParsers = q.q.batchParsers;
|
|
3800
|
+
}
|
|
3801
|
+
data.from = arg;
|
|
3802
|
+
data.selectAllColumns = data.scopes = void 0;
|
|
3803
|
+
return self;
|
|
3804
|
+
}
|
|
3805
|
+
function queryFromSql(self, args) {
|
|
3806
|
+
const data = self.q;
|
|
3807
|
+
data.as || (data.as = "t");
|
|
3808
|
+
data.from = sqlQueryArgsToExpression(args);
|
|
3809
|
+
data.selectAllColumns = void 0;
|
|
3810
|
+
return self;
|
|
3811
|
+
}
|
|
3812
|
+
class FromMethods {
|
|
3813
|
+
/**
|
|
3814
|
+
* Set the `FROM` value, by default the table name is used.
|
|
3815
|
+
*
|
|
3816
|
+
* `from` determines a set of available tables and columns withing the query,
|
|
3817
|
+
* and thus it must not follow `select`, use `select` only after `from`.
|
|
3818
|
+
*
|
|
3819
|
+
* ```ts
|
|
3820
|
+
* // accepts sub-query:
|
|
3821
|
+
* db.table.from(db.otherTable.select('foo', 'bar'));
|
|
3822
|
+
*
|
|
3823
|
+
* // accepts alias of `WITH` expression:
|
|
3824
|
+
* q.with('withTable', db.table.select('id', 'name'))
|
|
3825
|
+
* .from('withTable')
|
|
3826
|
+
* // `select` is after `from`
|
|
3827
|
+
* .select('id', 'name');
|
|
3828
|
+
* ```
|
|
3829
|
+
*
|
|
3830
|
+
* `from` can accept multiple sources:
|
|
3831
|
+
*
|
|
3832
|
+
* ```ts
|
|
3833
|
+
* db.table
|
|
3834
|
+
* // add a `WITH` statement called `withTable
|
|
3835
|
+
* .with('withTable', db.table.select('one'))
|
|
3836
|
+
* // select from `withTable` and from `otherTable`
|
|
3837
|
+
* .from('withTable', db.otherTable.select('two'))
|
|
3838
|
+
* // source names and column names are properly typed when selecting
|
|
3839
|
+
* .select('withTable.one', 'otherTable.two');
|
|
3840
|
+
* ```
|
|
3841
|
+
*
|
|
3842
|
+
* @param arg - query or name of CTE table
|
|
3843
|
+
*/
|
|
3844
|
+
from(arg) {
|
|
3845
|
+
return queryFrom(_clone(this), arg);
|
|
3846
|
+
}
|
|
3847
|
+
/**
|
|
3848
|
+
* Set the `FROM` value with custom SQL:
|
|
3849
|
+
*
|
|
3850
|
+
* ```ts
|
|
3851
|
+
* const value = 123;
|
|
3852
|
+
* db.table.fromSql`value = ${value}`;
|
|
3853
|
+
* ```
|
|
3854
|
+
*
|
|
3855
|
+
* @param args - SQL expression
|
|
3856
|
+
*/
|
|
3857
|
+
fromSql(...args) {
|
|
3858
|
+
return queryFromSql(_clone(this), args);
|
|
3859
|
+
}
|
|
3860
|
+
/**
|
|
3861
|
+
* Adds `ONLY` SQL keyword to the `FROM`.
|
|
3862
|
+
* When selecting from a parent table that has a table inheritance,
|
|
3863
|
+
* setting `only` will make it to select rows only from the parent table.
|
|
3864
|
+
*
|
|
3865
|
+
* ```ts
|
|
3866
|
+
* db.table.only();
|
|
3867
|
+
*
|
|
3868
|
+
* // disabling `only` after being enabled
|
|
3869
|
+
* db.table.only().only(false);
|
|
3870
|
+
* ```
|
|
3871
|
+
*
|
|
3872
|
+
* @param only - can be disabled by passing `false` if was enabled previously.
|
|
3873
|
+
*/
|
|
3874
|
+
only(only = true) {
|
|
3875
|
+
const q = _clone(this);
|
|
3876
|
+
q.q.only = only;
|
|
3877
|
+
return q;
|
|
3878
|
+
}
|
|
3879
|
+
}
|
|
3880
|
+
|
|
3881
|
+
function queryWrap(self, query, as = "t") {
|
|
3882
|
+
return _queryAs(queryFrom(query, self), as);
|
|
3883
|
+
}
|
|
3884
|
+
function cloneQueryBaseUnscoped(query) {
|
|
3885
|
+
const q = query.baseQuery.clone();
|
|
3886
|
+
q.q.or = q.q.and = q.q.scopes = void 0;
|
|
3887
|
+
return q;
|
|
3888
|
+
}
|
|
3889
|
+
|
|
3718
3890
|
const addParserForRawExpression = (q, key, raw) => {
|
|
3719
3891
|
if (raw.result.value) addColumnParserToQuery(q.q, key, raw.result.value);
|
|
3720
3892
|
};
|
|
@@ -3962,7 +4134,7 @@ const processSelectArg = (q, as, arg, columnAs) => {
|
|
|
3962
4134
|
query = value.json(false);
|
|
3963
4135
|
value.q.coalesceValue = emptyArrSQL;
|
|
3964
4136
|
} else if (returnType === "pluck") {
|
|
3965
|
-
query = value.q.select ? value.wrap(value
|
|
4137
|
+
query = value.q.select ? value.wrap(cloneQueryBaseUnscoped(value)).jsonAgg(value.q.select[0]) : value.json(false);
|
|
3966
4138
|
value.q.coalesceValue = emptyArrSQL;
|
|
3967
4139
|
} else {
|
|
3968
4140
|
if (returnType === "value" || returnType === "valueOrThrow") {
|
|
@@ -4292,171 +4464,6 @@ function _queryGetOptional(self, arg) {
|
|
|
4292
4464
|
return _get(self, "value", arg);
|
|
4293
4465
|
}
|
|
4294
4466
|
|
|
4295
|
-
const _queryAs = (self, as) => {
|
|
4296
|
-
const { q } = self;
|
|
4297
|
-
q.as = as;
|
|
4298
|
-
q.aliases = {
|
|
4299
|
-
...q.aliases,
|
|
4300
|
-
[as]: q.aliases ? _queryResolveAlias(q.aliases, as) : as
|
|
4301
|
-
};
|
|
4302
|
-
return self;
|
|
4303
|
-
};
|
|
4304
|
-
const _queryResolveAlias = (aliases, as) => {
|
|
4305
|
-
if (!aliases[as]) return as;
|
|
4306
|
-
let suffix = 2;
|
|
4307
|
-
let privateAs;
|
|
4308
|
-
while (aliases[privateAs = as + suffix]) {
|
|
4309
|
-
suffix++;
|
|
4310
|
-
}
|
|
4311
|
-
return privateAs;
|
|
4312
|
-
};
|
|
4313
|
-
class AsMethods {
|
|
4314
|
-
/**
|
|
4315
|
-
* Sets table alias:
|
|
4316
|
-
*
|
|
4317
|
-
* ```ts
|
|
4318
|
-
* db.table.as('u').select('u.name');
|
|
4319
|
-
*
|
|
4320
|
-
* // Can be used in the join:
|
|
4321
|
-
* db.table.join(Profile.as('p'), 'p.userId', 'user.id');
|
|
4322
|
-
* ```
|
|
4323
|
-
*
|
|
4324
|
-
* @param as - alias for the table of this query
|
|
4325
|
-
*/
|
|
4326
|
-
as(as) {
|
|
4327
|
-
return _queryAs(_clone(this), as);
|
|
4328
|
-
}
|
|
4329
|
-
}
|
|
4330
|
-
|
|
4331
|
-
function queryFrom(self, arg) {
|
|
4332
|
-
const data = self.q;
|
|
4333
|
-
if (typeof arg === "string") {
|
|
4334
|
-
data.as || (data.as = arg);
|
|
4335
|
-
const w = data.withShapes?.[arg];
|
|
4336
|
-
data.shape = w?.shape ?? emptyObject;
|
|
4337
|
-
data.computeds = w?.computeds;
|
|
4338
|
-
} else if (isExpression(arg)) {
|
|
4339
|
-
data.as || (data.as = "t");
|
|
4340
|
-
} else if (Array.isArray(arg)) {
|
|
4341
|
-
const { shape } = data;
|
|
4342
|
-
let clonedParsers = false;
|
|
4343
|
-
for (const item of arg) {
|
|
4344
|
-
if (typeof item === "string") {
|
|
4345
|
-
const w = data.withShapes[item];
|
|
4346
|
-
Object.assign(shape, w.shape);
|
|
4347
|
-
if (w.computeds) data.computeds = { ...data.computeds, ...w.computeds };
|
|
4348
|
-
for (const key in w.shape) {
|
|
4349
|
-
addColumnParserToQuery(
|
|
4350
|
-
self,
|
|
4351
|
-
key,
|
|
4352
|
-
w.shape[key]
|
|
4353
|
-
);
|
|
4354
|
-
}
|
|
4355
|
-
} else if (!isExpression(item)) {
|
|
4356
|
-
Object.assign(shape, getShapeFromSelect(item, true));
|
|
4357
|
-
if (!clonedParsers) {
|
|
4358
|
-
data.parsers = { ...data.parsers };
|
|
4359
|
-
clonedParsers = true;
|
|
4360
|
-
}
|
|
4361
|
-
Object.assign(data.parsers, item.q.parsers);
|
|
4362
|
-
}
|
|
4363
|
-
}
|
|
4364
|
-
} else {
|
|
4365
|
-
const q = arg;
|
|
4366
|
-
data.as || (data.as = q.q.as || q.table || "t");
|
|
4367
|
-
data.shape = getShapeFromSelect(q, true);
|
|
4368
|
-
data.parsers = q.q.parsers;
|
|
4369
|
-
data.batchParsers = q.q.batchParsers;
|
|
4370
|
-
}
|
|
4371
|
-
data.from = arg;
|
|
4372
|
-
data.selectAllColumns = data.scopes = void 0;
|
|
4373
|
-
return self;
|
|
4374
|
-
}
|
|
4375
|
-
function queryFromSql(self, args) {
|
|
4376
|
-
const data = self.q;
|
|
4377
|
-
data.as || (data.as = "t");
|
|
4378
|
-
data.from = sqlQueryArgsToExpression(args);
|
|
4379
|
-
data.selectAllColumns = void 0;
|
|
4380
|
-
return self;
|
|
4381
|
-
}
|
|
4382
|
-
class FromMethods {
|
|
4383
|
-
/**
|
|
4384
|
-
* Set the `FROM` value, by default the table name is used.
|
|
4385
|
-
*
|
|
4386
|
-
* `from` determines a set of available tables and columns withing the query,
|
|
4387
|
-
* and thus it must not follow `select`, use `select` only after `from`.
|
|
4388
|
-
*
|
|
4389
|
-
* ```ts
|
|
4390
|
-
* // accepts sub-query:
|
|
4391
|
-
* db.table.from(db.otherTable.select('foo', 'bar'));
|
|
4392
|
-
*
|
|
4393
|
-
* // accepts alias of `WITH` expression:
|
|
4394
|
-
* q.with('withTable', db.table.select('id', 'name'))
|
|
4395
|
-
* .from('withTable')
|
|
4396
|
-
* // `select` is after `from`
|
|
4397
|
-
* .select('id', 'name');
|
|
4398
|
-
* ```
|
|
4399
|
-
*
|
|
4400
|
-
* `from` can accept multiple sources:
|
|
4401
|
-
*
|
|
4402
|
-
* ```ts
|
|
4403
|
-
* db.table
|
|
4404
|
-
* // add a `WITH` statement called `withTable
|
|
4405
|
-
* .with('withTable', db.table.select('one'))
|
|
4406
|
-
* // select from `withTable` and from `otherTable`
|
|
4407
|
-
* .from('withTable', db.otherTable.select('two'))
|
|
4408
|
-
* // source names and column names are properly typed when selecting
|
|
4409
|
-
* .select('withTable.one', 'otherTable.two');
|
|
4410
|
-
* ```
|
|
4411
|
-
*
|
|
4412
|
-
* @param arg - query or name of CTE table
|
|
4413
|
-
*/
|
|
4414
|
-
from(arg) {
|
|
4415
|
-
return queryFrom(_clone(this), arg);
|
|
4416
|
-
}
|
|
4417
|
-
/**
|
|
4418
|
-
* Set the `FROM` value with custom SQL:
|
|
4419
|
-
*
|
|
4420
|
-
* ```ts
|
|
4421
|
-
* const value = 123;
|
|
4422
|
-
* db.table.fromSql`value = ${value}`;
|
|
4423
|
-
* ```
|
|
4424
|
-
*
|
|
4425
|
-
* @param args - SQL expression
|
|
4426
|
-
*/
|
|
4427
|
-
fromSql(...args) {
|
|
4428
|
-
return queryFromSql(_clone(this), args);
|
|
4429
|
-
}
|
|
4430
|
-
/**
|
|
4431
|
-
* Adds `ONLY` SQL keyword to the `FROM`.
|
|
4432
|
-
* When selecting from a parent table that has a table inheritance,
|
|
4433
|
-
* setting `only` will make it to select rows only from the parent table.
|
|
4434
|
-
*
|
|
4435
|
-
* ```ts
|
|
4436
|
-
* db.table.only();
|
|
4437
|
-
*
|
|
4438
|
-
* // disabling `only` after being enabled
|
|
4439
|
-
* db.table.only().only(false);
|
|
4440
|
-
* ```
|
|
4441
|
-
*
|
|
4442
|
-
* @param only - can be disabled by passing `false` if was enabled previously.
|
|
4443
|
-
*/
|
|
4444
|
-
only(only = true) {
|
|
4445
|
-
const q = _clone(this);
|
|
4446
|
-
q.q.only = only;
|
|
4447
|
-
return q;
|
|
4448
|
-
}
|
|
4449
|
-
}
|
|
4450
|
-
|
|
4451
|
-
function queryWrap(self, query, as = "t") {
|
|
4452
|
-
return _queryAs(queryFrom(query, self), as);
|
|
4453
|
-
}
|
|
4454
|
-
function cloneQueryBaseUnscoped(query) {
|
|
4455
|
-
const q = query.baseQuery.clone();
|
|
4456
|
-
q.q.or = q.q.and = q.q.scopes = void 0;
|
|
4457
|
-
return q;
|
|
4458
|
-
}
|
|
4459
|
-
|
|
4460
4467
|
class RowToJsonExpression extends Expression {
|
|
4461
4468
|
constructor(from, one, coalesce) {
|
|
4462
4469
|
super();
|
|
@@ -4494,10 +4501,7 @@ class RowToJsonExpression extends Expression {
|
|
|
4494
4501
|
}
|
|
4495
4502
|
function queryJson(self, coalesce) {
|
|
4496
4503
|
const inner = self.clone();
|
|
4497
|
-
const q = queryWrap(
|
|
4498
|
-
inner,
|
|
4499
|
-
cloneQueryBaseUnscoped(self)
|
|
4500
|
-
);
|
|
4504
|
+
const q = queryWrap(inner, cloneQueryBaseUnscoped(inner));
|
|
4501
4505
|
_queryGetOptional(
|
|
4502
4506
|
q,
|
|
4503
4507
|
new RowToJsonExpression(
|
|
@@ -4936,18 +4940,23 @@ const selectToSql = (ctx, table, query, quotedAs, hookSelect = query.hookSelect,
|
|
|
4936
4940
|
let quotedTable;
|
|
4937
4941
|
let columnName;
|
|
4938
4942
|
let col;
|
|
4939
|
-
|
|
4940
|
-
|
|
4941
|
-
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
-
|
|
4943
|
+
if (typeof select === "string") {
|
|
4944
|
+
const index = select.indexOf(".");
|
|
4945
|
+
if (index !== -1) {
|
|
4946
|
+
const tableName = select.slice(0, index);
|
|
4947
|
+
quotedTable = `"${tableName}"`;
|
|
4948
|
+
columnName = select.slice(index + 1);
|
|
4949
|
+
col = table.q.joinedShapes?.[tableName]?.[columnName];
|
|
4950
|
+
sql = col?.data.computed ? col.data.computed.toSQL(ctx, `"${tableName}"`) : `"${tableName}"."${col?.data.name || columnName}"`;
|
|
4951
|
+
} else {
|
|
4952
|
+
quotedTable = quotedAs;
|
|
4953
|
+
columnName = select;
|
|
4954
|
+
col = query.shape[select];
|
|
4955
|
+
sql = simpleColumnToSQL(ctx, query, select, col, quotedAs);
|
|
4956
|
+
}
|
|
4946
4957
|
} else {
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
col = query.shape[select];
|
|
4950
|
-
sql = simpleColumnToSQL(ctx, query, select, col, quotedAs);
|
|
4958
|
+
columnName = column;
|
|
4959
|
+
sql = select.sql;
|
|
4951
4960
|
}
|
|
4952
4961
|
let name = columnName;
|
|
4953
4962
|
if (selected?.[columnName]) {
|
|
@@ -4959,7 +4968,7 @@ const selectToSql = (ctx, table, query, quotedAs, hookSelect = query.hookSelect,
|
|
|
4959
4968
|
while (selected[name = `${column}${i}`]) i++;
|
|
4960
4969
|
item.as = name;
|
|
4961
4970
|
sql += ` "${name}"`;
|
|
4962
|
-
} else if (col?.data.name) {
|
|
4971
|
+
} else if (col?.data.name || typeof select === "object") {
|
|
4963
4972
|
sql += ` "${columnName}"`;
|
|
4964
4973
|
}
|
|
4965
4974
|
if (jsonList) jsonList[name] = col;
|
|
@@ -5188,6 +5197,7 @@ const queryKeysOfNotSimpleQuery = [
|
|
|
5188
5197
|
"for"
|
|
5189
5198
|
];
|
|
5190
5199
|
|
|
5200
|
+
let fromQuery;
|
|
5191
5201
|
const pushFromAndAs = (ctx, table, data, quotedAs) => {
|
|
5192
5202
|
let sql = "FROM ";
|
|
5193
5203
|
const from = getFrom(ctx, table, data, quotedAs);
|
|
@@ -5224,8 +5234,15 @@ const pushFromAndAs = (ctx, table, data, quotedAs) => {
|
|
|
5224
5234
|
sql += `, ${fn}(${lang}, ${querySql}) "${as}"`;
|
|
5225
5235
|
}
|
|
5226
5236
|
ctx.sql.push(sql);
|
|
5237
|
+
if (fromQuery) {
|
|
5238
|
+
const fq = fromQuery;
|
|
5239
|
+
fromQuery = void 0;
|
|
5240
|
+
return fq;
|
|
5241
|
+
}
|
|
5242
|
+
return;
|
|
5227
5243
|
};
|
|
5228
5244
|
const getFrom = (ctx, table, data, quotedAs) => {
|
|
5245
|
+
fromQuery = void 0;
|
|
5229
5246
|
if (data.from) {
|
|
5230
5247
|
const { from } = data;
|
|
5231
5248
|
if (Array.isArray(from)) {
|
|
@@ -5252,6 +5269,7 @@ const fromToSql = (ctx, data, from, quotedAs) => {
|
|
|
5252
5269
|
} else {
|
|
5253
5270
|
sql = quoteSchemaAndTable(from.q.schema, from.table);
|
|
5254
5271
|
}
|
|
5272
|
+
fromQuery = from;
|
|
5255
5273
|
}
|
|
5256
5274
|
} else {
|
|
5257
5275
|
sql = quoteSchemaAndTable(data.schema, from);
|
|
@@ -5522,6 +5540,7 @@ const toSQL = (table, options) => {
|
|
|
5522
5540
|
if (query.with) {
|
|
5523
5541
|
pushWithSql(ctx, query.with);
|
|
5524
5542
|
}
|
|
5543
|
+
let fromQuery;
|
|
5525
5544
|
if (query.type && query.type !== "upsert") {
|
|
5526
5545
|
const tableName = table.table ?? query.as;
|
|
5527
5546
|
if (!tableName) throw new Error(`Table is missing for ${query.type}`);
|
|
@@ -5571,9 +5590,7 @@ const toSQL = (table, options) => {
|
|
|
5571
5590
|
}
|
|
5572
5591
|
const aliases = query.group ? [] : void 0;
|
|
5573
5592
|
pushSelectSql(ctx, table, query, quotedAs, aliases);
|
|
5574
|
-
|
|
5575
|
-
pushFromAndAs(ctx, table, query, quotedAs);
|
|
5576
|
-
}
|
|
5593
|
+
fromQuery = (table.table || query.from) && pushFromAndAs(ctx, table, query, quotedAs) || void 0;
|
|
5577
5594
|
if (query.join) {
|
|
5578
5595
|
pushJoinSql(
|
|
5579
5596
|
ctx,
|
|
@@ -5612,9 +5629,19 @@ const toSQL = (table, options) => {
|
|
|
5612
5629
|
if (query.order) {
|
|
5613
5630
|
pushOrderBySql(ctx, query, quotedAs, query.order);
|
|
5614
5631
|
}
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5632
|
+
if (query.useFromLimitOffset) {
|
|
5633
|
+
const q = fromQuery?.q;
|
|
5634
|
+
if (q.limit) {
|
|
5635
|
+
sql.push(`LIMIT ${addValue(values, q.limit)}`);
|
|
5636
|
+
}
|
|
5637
|
+
if (q.offset) {
|
|
5638
|
+
sql.push(`OFFSET ${addValue(values, q.offset)}`);
|
|
5639
|
+
}
|
|
5640
|
+
} else {
|
|
5641
|
+
pushLimitSQL(sql, values, query);
|
|
5642
|
+
if (query.offset && !query.returnsOne) {
|
|
5643
|
+
sql.push(`OFFSET ${addValue(values, query.offset)}`);
|
|
5644
|
+
}
|
|
5618
5645
|
}
|
|
5619
5646
|
if (query.for) {
|
|
5620
5647
|
sql.push("FOR", query.for.type);
|
|
@@ -7019,7 +7046,9 @@ const _chain = (fromQuery, toQuery, rel) => {
|
|
|
7019
7046
|
if (
|
|
7020
7047
|
// `select({ q => q.rel })`: on the first relation it doesn't matter if the parent has chainMultiple
|
|
7021
7048
|
self.q.subQuery > 1 && self.q.chainMultiple
|
|
7022
|
-
)
|
|
7049
|
+
) {
|
|
7050
|
+
q.returnType = q.returnsOne = q.limit = void 0;
|
|
7051
|
+
} else if (!rel.query.q.returnsOne) {
|
|
7023
7052
|
q.chainMultiple = true;
|
|
7024
7053
|
}
|
|
7025
7054
|
} else {
|
|
@@ -10264,7 +10293,7 @@ class JsonMethods {
|
|
|
10264
10293
|
* @param coalesce
|
|
10265
10294
|
*/
|
|
10266
10295
|
json(coalesce) {
|
|
10267
|
-
return queryJson(
|
|
10296
|
+
return queryJson(this, coalesce);
|
|
10268
10297
|
}
|
|
10269
10298
|
}
|
|
10270
10299
|
|