pqb 0.49.0 → 0.50.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 +31 -20
- package/dist/index.js +253 -200
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +253 -200
- 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") {
|
|
@@ -4074,7 +4246,16 @@ const handleComputed = (q, computeds, column) => {
|
|
|
4074
4246
|
};
|
|
4075
4247
|
const getShapeFromSelect = (q, isSubQuery) => {
|
|
4076
4248
|
const query = q.q;
|
|
4077
|
-
const {
|
|
4249
|
+
const { shape } = query;
|
|
4250
|
+
let select;
|
|
4251
|
+
if (query.selectedComputeds) {
|
|
4252
|
+
select = query.select ? [...query.select] : [];
|
|
4253
|
+
for (const key in query.selectedComputeds) {
|
|
4254
|
+
select.push(...query.selectedComputeds[key].deps);
|
|
4255
|
+
}
|
|
4256
|
+
} else {
|
|
4257
|
+
select = query.select;
|
|
4258
|
+
}
|
|
4078
4259
|
let result;
|
|
4079
4260
|
if (!select) {
|
|
4080
4261
|
if (isSubQuery) {
|
|
@@ -4133,18 +4314,33 @@ const addColumnToShapeFromSelect = (q, arg, shape, query, result, isSubQuery, ke
|
|
|
4133
4314
|
result[key || column] = shape[column];
|
|
4134
4315
|
} else {
|
|
4135
4316
|
const it = query.joinedShapes?.[table]?.[column];
|
|
4136
|
-
if (it)
|
|
4317
|
+
if (it)
|
|
4318
|
+
result[key || column] = mapSubSelectColumn(
|
|
4319
|
+
it,
|
|
4320
|
+
isSubQuery
|
|
4321
|
+
);
|
|
4137
4322
|
}
|
|
4138
4323
|
} else if (arg === "*") {
|
|
4139
4324
|
for (const key2 in shape) {
|
|
4140
|
-
result[key2] =
|
|
4325
|
+
result[key2] = mapSubSelectColumn(
|
|
4326
|
+
shape[key2],
|
|
4327
|
+
isSubQuery
|
|
4328
|
+
);
|
|
4141
4329
|
}
|
|
4142
4330
|
} else {
|
|
4143
|
-
result[key || arg] =
|
|
4331
|
+
result[key || arg] = mapSubSelectColumn(
|
|
4332
|
+
shape[arg],
|
|
4333
|
+
isSubQuery
|
|
4334
|
+
);
|
|
4144
4335
|
}
|
|
4145
4336
|
};
|
|
4146
|
-
const
|
|
4147
|
-
|
|
4337
|
+
const mapSubSelectColumn = (column, isSubQuery) => {
|
|
4338
|
+
if (!isSubQuery || !column || !column.data.name && !column.data.explicitSelect) {
|
|
4339
|
+
return column;
|
|
4340
|
+
}
|
|
4341
|
+
const cloned = Object.create(column);
|
|
4342
|
+
cloned.data = { ...column.data, name: void 0, explicitSelect: void 0 };
|
|
4343
|
+
return cloned;
|
|
4148
4344
|
};
|
|
4149
4345
|
function _querySelect(q, args) {
|
|
4150
4346
|
var _a;
|
|
@@ -4268,171 +4464,6 @@ function _queryGetOptional(self, arg) {
|
|
|
4268
4464
|
return _get(self, "value", arg);
|
|
4269
4465
|
}
|
|
4270
4466
|
|
|
4271
|
-
const _queryAs = (self, as) => {
|
|
4272
|
-
const { q } = self;
|
|
4273
|
-
q.as = as;
|
|
4274
|
-
q.aliases = {
|
|
4275
|
-
...q.aliases,
|
|
4276
|
-
[as]: q.aliases ? _queryResolveAlias(q.aliases, as) : as
|
|
4277
|
-
};
|
|
4278
|
-
return self;
|
|
4279
|
-
};
|
|
4280
|
-
const _queryResolveAlias = (aliases, as) => {
|
|
4281
|
-
if (!aliases[as]) return as;
|
|
4282
|
-
let suffix = 2;
|
|
4283
|
-
let privateAs;
|
|
4284
|
-
while (aliases[privateAs = as + suffix]) {
|
|
4285
|
-
suffix++;
|
|
4286
|
-
}
|
|
4287
|
-
return privateAs;
|
|
4288
|
-
};
|
|
4289
|
-
class AsMethods {
|
|
4290
|
-
/**
|
|
4291
|
-
* Sets table alias:
|
|
4292
|
-
*
|
|
4293
|
-
* ```ts
|
|
4294
|
-
* db.table.as('u').select('u.name');
|
|
4295
|
-
*
|
|
4296
|
-
* // Can be used in the join:
|
|
4297
|
-
* db.table.join(Profile.as('p'), 'p.userId', 'user.id');
|
|
4298
|
-
* ```
|
|
4299
|
-
*
|
|
4300
|
-
* @param as - alias for the table of this query
|
|
4301
|
-
*/
|
|
4302
|
-
as(as) {
|
|
4303
|
-
return _queryAs(_clone(this), as);
|
|
4304
|
-
}
|
|
4305
|
-
}
|
|
4306
|
-
|
|
4307
|
-
function queryFrom(self, arg) {
|
|
4308
|
-
const data = self.q;
|
|
4309
|
-
if (typeof arg === "string") {
|
|
4310
|
-
data.as || (data.as = arg);
|
|
4311
|
-
const w = data.withShapes?.[arg];
|
|
4312
|
-
data.shape = w?.shape ?? emptyObject;
|
|
4313
|
-
data.computeds = w?.computeds;
|
|
4314
|
-
} else if (isExpression(arg)) {
|
|
4315
|
-
data.as || (data.as = "t");
|
|
4316
|
-
} else if (Array.isArray(arg)) {
|
|
4317
|
-
const { shape } = data;
|
|
4318
|
-
let clonedParsers = false;
|
|
4319
|
-
for (const item of arg) {
|
|
4320
|
-
if (typeof item === "string") {
|
|
4321
|
-
const w = data.withShapes[item];
|
|
4322
|
-
Object.assign(shape, w.shape);
|
|
4323
|
-
if (w.computeds) data.computeds = { ...data.computeds, ...w.computeds };
|
|
4324
|
-
for (const key in w.shape) {
|
|
4325
|
-
addColumnParserToQuery(
|
|
4326
|
-
self,
|
|
4327
|
-
key,
|
|
4328
|
-
w.shape[key]
|
|
4329
|
-
);
|
|
4330
|
-
}
|
|
4331
|
-
} else if (!isExpression(item)) {
|
|
4332
|
-
Object.assign(shape, getShapeFromSelect(item, true));
|
|
4333
|
-
if (!clonedParsers) {
|
|
4334
|
-
data.parsers = { ...data.parsers };
|
|
4335
|
-
clonedParsers = true;
|
|
4336
|
-
}
|
|
4337
|
-
Object.assign(data.parsers, item.q.parsers);
|
|
4338
|
-
}
|
|
4339
|
-
}
|
|
4340
|
-
} else {
|
|
4341
|
-
const q = arg;
|
|
4342
|
-
data.as || (data.as = q.q.as || q.table || "t");
|
|
4343
|
-
data.shape = getShapeFromSelect(q, true);
|
|
4344
|
-
data.parsers = q.q.parsers;
|
|
4345
|
-
data.batchParsers = q.q.batchParsers;
|
|
4346
|
-
}
|
|
4347
|
-
data.from = arg;
|
|
4348
|
-
data.selectAllColumns = data.scopes = void 0;
|
|
4349
|
-
return self;
|
|
4350
|
-
}
|
|
4351
|
-
function queryFromSql(self, args) {
|
|
4352
|
-
const data = self.q;
|
|
4353
|
-
data.as || (data.as = "t");
|
|
4354
|
-
data.from = sqlQueryArgsToExpression(args);
|
|
4355
|
-
data.selectAllColumns = void 0;
|
|
4356
|
-
return self;
|
|
4357
|
-
}
|
|
4358
|
-
class FromMethods {
|
|
4359
|
-
/**
|
|
4360
|
-
* Set the `FROM` value, by default the table name is used.
|
|
4361
|
-
*
|
|
4362
|
-
* `from` determines a set of available tables and columns withing the query,
|
|
4363
|
-
* and thus it must not follow `select`, use `select` only after `from`.
|
|
4364
|
-
*
|
|
4365
|
-
* ```ts
|
|
4366
|
-
* // accepts sub-query:
|
|
4367
|
-
* db.table.from(db.otherTable.select('foo', 'bar'));
|
|
4368
|
-
*
|
|
4369
|
-
* // accepts alias of `WITH` expression:
|
|
4370
|
-
* q.with('withTable', db.table.select('id', 'name'))
|
|
4371
|
-
* .from('withTable')
|
|
4372
|
-
* // `select` is after `from`
|
|
4373
|
-
* .select('id', 'name');
|
|
4374
|
-
* ```
|
|
4375
|
-
*
|
|
4376
|
-
* `from` can accept multiple sources:
|
|
4377
|
-
*
|
|
4378
|
-
* ```ts
|
|
4379
|
-
* db.table
|
|
4380
|
-
* // add a `WITH` statement called `withTable
|
|
4381
|
-
* .with('withTable', db.table.select('one'))
|
|
4382
|
-
* // select from `withTable` and from `otherTable`
|
|
4383
|
-
* .from('withTable', db.otherTable.select('two'))
|
|
4384
|
-
* // source names and column names are properly typed when selecting
|
|
4385
|
-
* .select('withTable.one', 'otherTable.two');
|
|
4386
|
-
* ```
|
|
4387
|
-
*
|
|
4388
|
-
* @param arg - query or name of CTE table
|
|
4389
|
-
*/
|
|
4390
|
-
from(arg) {
|
|
4391
|
-
return queryFrom(_clone(this), arg);
|
|
4392
|
-
}
|
|
4393
|
-
/**
|
|
4394
|
-
* Set the `FROM` value with custom SQL:
|
|
4395
|
-
*
|
|
4396
|
-
* ```ts
|
|
4397
|
-
* const value = 123;
|
|
4398
|
-
* db.table.fromSql`value = ${value}`;
|
|
4399
|
-
* ```
|
|
4400
|
-
*
|
|
4401
|
-
* @param args - SQL expression
|
|
4402
|
-
*/
|
|
4403
|
-
fromSql(...args) {
|
|
4404
|
-
return queryFromSql(_clone(this), args);
|
|
4405
|
-
}
|
|
4406
|
-
/**
|
|
4407
|
-
* Adds `ONLY` SQL keyword to the `FROM`.
|
|
4408
|
-
* When selecting from a parent table that has a table inheritance,
|
|
4409
|
-
* setting `only` will make it to select rows only from the parent table.
|
|
4410
|
-
*
|
|
4411
|
-
* ```ts
|
|
4412
|
-
* db.table.only();
|
|
4413
|
-
*
|
|
4414
|
-
* // disabling `only` after being enabled
|
|
4415
|
-
* db.table.only().only(false);
|
|
4416
|
-
* ```
|
|
4417
|
-
*
|
|
4418
|
-
* @param only - can be disabled by passing `false` if was enabled previously.
|
|
4419
|
-
*/
|
|
4420
|
-
only(only = true) {
|
|
4421
|
-
const q = _clone(this);
|
|
4422
|
-
q.q.only = only;
|
|
4423
|
-
return q;
|
|
4424
|
-
}
|
|
4425
|
-
}
|
|
4426
|
-
|
|
4427
|
-
function queryWrap(self, query, as = "t") {
|
|
4428
|
-
return _queryAs(queryFrom(query, self), as);
|
|
4429
|
-
}
|
|
4430
|
-
function cloneQueryBaseUnscoped(query) {
|
|
4431
|
-
const q = query.baseQuery.clone();
|
|
4432
|
-
q.q.or = q.q.and = q.q.scopes = void 0;
|
|
4433
|
-
return q;
|
|
4434
|
-
}
|
|
4435
|
-
|
|
4436
4467
|
class RowToJsonExpression extends Expression {
|
|
4437
4468
|
constructor(from, one, coalesce) {
|
|
4438
4469
|
super();
|
|
@@ -4470,10 +4501,7 @@ class RowToJsonExpression extends Expression {
|
|
|
4470
4501
|
}
|
|
4471
4502
|
function queryJson(self, coalesce) {
|
|
4472
4503
|
const inner = self.clone();
|
|
4473
|
-
const q = queryWrap(
|
|
4474
|
-
inner,
|
|
4475
|
-
cloneQueryBaseUnscoped(self)
|
|
4476
|
-
);
|
|
4504
|
+
const q = queryWrap(inner, cloneQueryBaseUnscoped(inner));
|
|
4477
4505
|
_queryGetOptional(
|
|
4478
4506
|
q,
|
|
4479
4507
|
new RowToJsonExpression(
|
|
@@ -4912,18 +4940,23 @@ const selectToSql = (ctx, table, query, quotedAs, hookSelect = query.hookSelect,
|
|
|
4912
4940
|
let quotedTable;
|
|
4913
4941
|
let columnName;
|
|
4914
4942
|
let col;
|
|
4915
|
-
|
|
4916
|
-
|
|
4917
|
-
|
|
4918
|
-
|
|
4919
|
-
|
|
4920
|
-
|
|
4921
|
-
|
|
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
|
+
}
|
|
4922
4957
|
} else {
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
col = query.shape[select];
|
|
4926
|
-
sql = simpleColumnToSQL(ctx, query, select, col, quotedAs);
|
|
4958
|
+
columnName = column;
|
|
4959
|
+
sql = select.sql;
|
|
4927
4960
|
}
|
|
4928
4961
|
let name = columnName;
|
|
4929
4962
|
if (selected?.[columnName]) {
|
|
@@ -4935,7 +4968,7 @@ const selectToSql = (ctx, table, query, quotedAs, hookSelect = query.hookSelect,
|
|
|
4935
4968
|
while (selected[name = `${column}${i}`]) i++;
|
|
4936
4969
|
item.as = name;
|
|
4937
4970
|
sql += ` "${name}"`;
|
|
4938
|
-
} else if (col?.data.name) {
|
|
4971
|
+
} else if (col?.data.name || typeof select === "object") {
|
|
4939
4972
|
sql += ` "${columnName}"`;
|
|
4940
4973
|
}
|
|
4941
4974
|
if (jsonList) jsonList[name] = col;
|
|
@@ -5164,6 +5197,7 @@ const queryKeysOfNotSimpleQuery = [
|
|
|
5164
5197
|
"for"
|
|
5165
5198
|
];
|
|
5166
5199
|
|
|
5200
|
+
let fromQuery;
|
|
5167
5201
|
const pushFromAndAs = (ctx, table, data, quotedAs) => {
|
|
5168
5202
|
let sql = "FROM ";
|
|
5169
5203
|
const from = getFrom(ctx, table, data, quotedAs);
|
|
@@ -5200,8 +5234,15 @@ const pushFromAndAs = (ctx, table, data, quotedAs) => {
|
|
|
5200
5234
|
sql += `, ${fn}(${lang}, ${querySql}) "${as}"`;
|
|
5201
5235
|
}
|
|
5202
5236
|
ctx.sql.push(sql);
|
|
5237
|
+
if (fromQuery) {
|
|
5238
|
+
const fq = fromQuery;
|
|
5239
|
+
fromQuery = void 0;
|
|
5240
|
+
return fq;
|
|
5241
|
+
}
|
|
5242
|
+
return;
|
|
5203
5243
|
};
|
|
5204
5244
|
const getFrom = (ctx, table, data, quotedAs) => {
|
|
5245
|
+
fromQuery = void 0;
|
|
5205
5246
|
if (data.from) {
|
|
5206
5247
|
const { from } = data;
|
|
5207
5248
|
if (Array.isArray(from)) {
|
|
@@ -5228,6 +5269,7 @@ const fromToSql = (ctx, data, from, quotedAs) => {
|
|
|
5228
5269
|
} else {
|
|
5229
5270
|
sql = quoteSchemaAndTable(from.q.schema, from.table);
|
|
5230
5271
|
}
|
|
5272
|
+
fromQuery = from;
|
|
5231
5273
|
}
|
|
5232
5274
|
} else {
|
|
5233
5275
|
sql = quoteSchemaAndTable(data.schema, from);
|
|
@@ -5498,6 +5540,7 @@ const toSQL = (table, options) => {
|
|
|
5498
5540
|
if (query.with) {
|
|
5499
5541
|
pushWithSql(ctx, query.with);
|
|
5500
5542
|
}
|
|
5543
|
+
let fromQuery;
|
|
5501
5544
|
if (query.type && query.type !== "upsert") {
|
|
5502
5545
|
const tableName = table.table ?? query.as;
|
|
5503
5546
|
if (!tableName) throw new Error(`Table is missing for ${query.type}`);
|
|
@@ -5547,9 +5590,7 @@ const toSQL = (table, options) => {
|
|
|
5547
5590
|
}
|
|
5548
5591
|
const aliases = query.group ? [] : void 0;
|
|
5549
5592
|
pushSelectSql(ctx, table, query, quotedAs, aliases);
|
|
5550
|
-
|
|
5551
|
-
pushFromAndAs(ctx, table, query, quotedAs);
|
|
5552
|
-
}
|
|
5593
|
+
fromQuery = (table.table || query.from) && pushFromAndAs(ctx, table, query, quotedAs) || void 0;
|
|
5553
5594
|
if (query.join) {
|
|
5554
5595
|
pushJoinSql(
|
|
5555
5596
|
ctx,
|
|
@@ -5588,9 +5629,19 @@ const toSQL = (table, options) => {
|
|
|
5588
5629
|
if (query.order) {
|
|
5589
5630
|
pushOrderBySql(ctx, query, quotedAs, query.order);
|
|
5590
5631
|
}
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
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
|
+
}
|
|
5594
5645
|
}
|
|
5595
5646
|
if (query.for) {
|
|
5596
5647
|
sql.push("FOR", query.for.type);
|
|
@@ -6995,7 +7046,9 @@ const _chain = (fromQuery, toQuery, rel) => {
|
|
|
6995
7046
|
if (
|
|
6996
7047
|
// `select({ q => q.rel })`: on the first relation it doesn't matter if the parent has chainMultiple
|
|
6997
7048
|
self.q.subQuery > 1 && self.q.chainMultiple
|
|
6998
|
-
)
|
|
7049
|
+
) {
|
|
7050
|
+
q.returnType = q.returnsOne = q.limit = void 0;
|
|
7051
|
+
} else if (!rel.query.q.returnsOne) {
|
|
6999
7052
|
q.chainMultiple = true;
|
|
7000
7053
|
}
|
|
7001
7054
|
} else {
|
|
@@ -10240,7 +10293,7 @@ class JsonMethods {
|
|
|
10240
10293
|
* @param coalesce
|
|
10241
10294
|
*/
|
|
10242
10295
|
json(coalesce) {
|
|
10243
|
-
return queryJson(
|
|
10296
|
+
return queryJson(this, coalesce);
|
|
10244
10297
|
}
|
|
10245
10298
|
}
|
|
10246
10299
|
|