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.js
CHANGED
|
@@ -1943,9 +1943,9 @@ const collectPrimaryKeys = (q) => {
|
|
|
1943
1943
|
primaryKeys.push(key);
|
|
1944
1944
|
}
|
|
1945
1945
|
}
|
|
1946
|
-
const
|
|
1947
|
-
if (
|
|
1948
|
-
primaryKeys.push(...
|
|
1946
|
+
const pkey = q.internal.tableData.primaryKey;
|
|
1947
|
+
if (pkey) {
|
|
1948
|
+
primaryKeys.push(...pkey.columns);
|
|
1949
1949
|
}
|
|
1950
1950
|
return primaryKeys;
|
|
1951
1951
|
};
|
|
@@ -2226,11 +2226,18 @@ const _join = (query, require, type, first, args) => {
|
|
|
2226
2226
|
let joinSubQuery = false;
|
|
2227
2227
|
first = preprocessJoinArg(query, first);
|
|
2228
2228
|
if (typeof first === "object") {
|
|
2229
|
+
let isInternalJoin;
|
|
2230
|
+
if ("_internalJoin" in first) {
|
|
2231
|
+
isInternalJoin = true;
|
|
2232
|
+
first = first._internalJoin;
|
|
2233
|
+
}
|
|
2229
2234
|
if (require && isQueryNone(first)) {
|
|
2230
2235
|
return _queryNone(query);
|
|
2231
2236
|
}
|
|
2232
2237
|
const q = first;
|
|
2233
|
-
|
|
2238
|
+
if (!isInternalJoin) {
|
|
2239
|
+
joinSubQuery = getIsJoinSubQuery(q);
|
|
2240
|
+
}
|
|
2234
2241
|
joinKey = q.q.as || q.table;
|
|
2235
2242
|
if (joinKey) {
|
|
2236
2243
|
shape = getShapeFromSelect(q, joinSubQuery && !!q.q.select);
|
|
@@ -3717,6 +3724,171 @@ const filterAllResult = (result, tempColumns, hasAfterHook) => {
|
|
|
3717
3724
|
return result;
|
|
3718
3725
|
};
|
|
3719
3726
|
|
|
3727
|
+
const _queryAs = (self, as) => {
|
|
3728
|
+
const { q } = self;
|
|
3729
|
+
q.as = as;
|
|
3730
|
+
q.aliases = {
|
|
3731
|
+
...q.aliases,
|
|
3732
|
+
[as]: q.aliases ? _queryResolveAlias(q.aliases, as) : as
|
|
3733
|
+
};
|
|
3734
|
+
return self;
|
|
3735
|
+
};
|
|
3736
|
+
const _queryResolveAlias = (aliases, as) => {
|
|
3737
|
+
if (!aliases[as]) return as;
|
|
3738
|
+
let suffix = 2;
|
|
3739
|
+
let privateAs;
|
|
3740
|
+
while (aliases[privateAs = as + suffix]) {
|
|
3741
|
+
suffix++;
|
|
3742
|
+
}
|
|
3743
|
+
return privateAs;
|
|
3744
|
+
};
|
|
3745
|
+
class AsMethods {
|
|
3746
|
+
/**
|
|
3747
|
+
* Sets table alias:
|
|
3748
|
+
*
|
|
3749
|
+
* ```ts
|
|
3750
|
+
* db.table.as('u').select('u.name');
|
|
3751
|
+
*
|
|
3752
|
+
* // Can be used in the join:
|
|
3753
|
+
* db.table.join(Profile.as('p'), 'p.userId', 'user.id');
|
|
3754
|
+
* ```
|
|
3755
|
+
*
|
|
3756
|
+
* @param as - alias for the table of this query
|
|
3757
|
+
*/
|
|
3758
|
+
as(as) {
|
|
3759
|
+
return _queryAs(_clone(this), as);
|
|
3760
|
+
}
|
|
3761
|
+
}
|
|
3762
|
+
|
|
3763
|
+
function queryFrom(self, arg) {
|
|
3764
|
+
const data = self.q;
|
|
3765
|
+
if (typeof arg === "string") {
|
|
3766
|
+
data.as || (data.as = arg);
|
|
3767
|
+
const w = data.withShapes?.[arg];
|
|
3768
|
+
data.shape = w?.shape ?? orchidCore.emptyObject;
|
|
3769
|
+
data.computeds = w?.computeds;
|
|
3770
|
+
} else if (orchidCore.isExpression(arg)) {
|
|
3771
|
+
data.as || (data.as = "t");
|
|
3772
|
+
} else if (Array.isArray(arg)) {
|
|
3773
|
+
const { shape } = data;
|
|
3774
|
+
let clonedParsers = false;
|
|
3775
|
+
for (const item of arg) {
|
|
3776
|
+
if (typeof item === "string") {
|
|
3777
|
+
const w = data.withShapes[item];
|
|
3778
|
+
Object.assign(shape, w.shape);
|
|
3779
|
+
if (w.computeds) data.computeds = { ...data.computeds, ...w.computeds };
|
|
3780
|
+
for (const key in w.shape) {
|
|
3781
|
+
addColumnParserToQuery(
|
|
3782
|
+
self,
|
|
3783
|
+
key,
|
|
3784
|
+
w.shape[key]
|
|
3785
|
+
);
|
|
3786
|
+
}
|
|
3787
|
+
} else if (!orchidCore.isExpression(item)) {
|
|
3788
|
+
Object.assign(shape, getShapeFromSelect(item, true));
|
|
3789
|
+
if (!clonedParsers) {
|
|
3790
|
+
data.parsers = { ...data.parsers };
|
|
3791
|
+
clonedParsers = true;
|
|
3792
|
+
}
|
|
3793
|
+
Object.assign(data.parsers, item.q.parsers);
|
|
3794
|
+
}
|
|
3795
|
+
}
|
|
3796
|
+
} else {
|
|
3797
|
+
const q = arg;
|
|
3798
|
+
data.as || (data.as = q.q.as || q.table || "t");
|
|
3799
|
+
data.shape = getShapeFromSelect(q, true);
|
|
3800
|
+
data.parsers = q.q.parsers;
|
|
3801
|
+
data.batchParsers = q.q.batchParsers;
|
|
3802
|
+
}
|
|
3803
|
+
data.from = arg;
|
|
3804
|
+
data.selectAllColumns = data.scopes = void 0;
|
|
3805
|
+
return self;
|
|
3806
|
+
}
|
|
3807
|
+
function queryFromSql(self, args) {
|
|
3808
|
+
const data = self.q;
|
|
3809
|
+
data.as || (data.as = "t");
|
|
3810
|
+
data.from = sqlQueryArgsToExpression(args);
|
|
3811
|
+
data.selectAllColumns = void 0;
|
|
3812
|
+
return self;
|
|
3813
|
+
}
|
|
3814
|
+
class FromMethods {
|
|
3815
|
+
/**
|
|
3816
|
+
* Set the `FROM` value, by default the table name is used.
|
|
3817
|
+
*
|
|
3818
|
+
* `from` determines a set of available tables and columns withing the query,
|
|
3819
|
+
* and thus it must not follow `select`, use `select` only after `from`.
|
|
3820
|
+
*
|
|
3821
|
+
* ```ts
|
|
3822
|
+
* // accepts sub-query:
|
|
3823
|
+
* db.table.from(db.otherTable.select('foo', 'bar'));
|
|
3824
|
+
*
|
|
3825
|
+
* // accepts alias of `WITH` expression:
|
|
3826
|
+
* q.with('withTable', db.table.select('id', 'name'))
|
|
3827
|
+
* .from('withTable')
|
|
3828
|
+
* // `select` is after `from`
|
|
3829
|
+
* .select('id', 'name');
|
|
3830
|
+
* ```
|
|
3831
|
+
*
|
|
3832
|
+
* `from` can accept multiple sources:
|
|
3833
|
+
*
|
|
3834
|
+
* ```ts
|
|
3835
|
+
* db.table
|
|
3836
|
+
* // add a `WITH` statement called `withTable
|
|
3837
|
+
* .with('withTable', db.table.select('one'))
|
|
3838
|
+
* // select from `withTable` and from `otherTable`
|
|
3839
|
+
* .from('withTable', db.otherTable.select('two'))
|
|
3840
|
+
* // source names and column names are properly typed when selecting
|
|
3841
|
+
* .select('withTable.one', 'otherTable.two');
|
|
3842
|
+
* ```
|
|
3843
|
+
*
|
|
3844
|
+
* @param arg - query or name of CTE table
|
|
3845
|
+
*/
|
|
3846
|
+
from(arg) {
|
|
3847
|
+
return queryFrom(_clone(this), arg);
|
|
3848
|
+
}
|
|
3849
|
+
/**
|
|
3850
|
+
* Set the `FROM` value with custom SQL:
|
|
3851
|
+
*
|
|
3852
|
+
* ```ts
|
|
3853
|
+
* const value = 123;
|
|
3854
|
+
* db.table.fromSql`value = ${value}`;
|
|
3855
|
+
* ```
|
|
3856
|
+
*
|
|
3857
|
+
* @param args - SQL expression
|
|
3858
|
+
*/
|
|
3859
|
+
fromSql(...args) {
|
|
3860
|
+
return queryFromSql(_clone(this), args);
|
|
3861
|
+
}
|
|
3862
|
+
/**
|
|
3863
|
+
* Adds `ONLY` SQL keyword to the `FROM`.
|
|
3864
|
+
* When selecting from a parent table that has a table inheritance,
|
|
3865
|
+
* setting `only` will make it to select rows only from the parent table.
|
|
3866
|
+
*
|
|
3867
|
+
* ```ts
|
|
3868
|
+
* db.table.only();
|
|
3869
|
+
*
|
|
3870
|
+
* // disabling `only` after being enabled
|
|
3871
|
+
* db.table.only().only(false);
|
|
3872
|
+
* ```
|
|
3873
|
+
*
|
|
3874
|
+
* @param only - can be disabled by passing `false` if was enabled previously.
|
|
3875
|
+
*/
|
|
3876
|
+
only(only = true) {
|
|
3877
|
+
const q = _clone(this);
|
|
3878
|
+
q.q.only = only;
|
|
3879
|
+
return q;
|
|
3880
|
+
}
|
|
3881
|
+
}
|
|
3882
|
+
|
|
3883
|
+
function queryWrap(self, query, as = "t") {
|
|
3884
|
+
return _queryAs(queryFrom(query, self), as);
|
|
3885
|
+
}
|
|
3886
|
+
function cloneQueryBaseUnscoped(query) {
|
|
3887
|
+
const q = query.baseQuery.clone();
|
|
3888
|
+
q.q.or = q.q.and = q.q.scopes = void 0;
|
|
3889
|
+
return q;
|
|
3890
|
+
}
|
|
3891
|
+
|
|
3720
3892
|
const addParserForRawExpression = (q, key, raw) => {
|
|
3721
3893
|
if (raw.result.value) addColumnParserToQuery(q.q, key, raw.result.value);
|
|
3722
3894
|
};
|
|
@@ -3964,7 +4136,7 @@ const processSelectArg = (q, as, arg, columnAs) => {
|
|
|
3964
4136
|
query = value.json(false);
|
|
3965
4137
|
value.q.coalesceValue = emptyArrSQL;
|
|
3966
4138
|
} else if (returnType === "pluck") {
|
|
3967
|
-
query = value.q.select ? value.wrap(value
|
|
4139
|
+
query = value.q.select ? value.wrap(cloneQueryBaseUnscoped(value)).jsonAgg(value.q.select[0]) : value.json(false);
|
|
3968
4140
|
value.q.coalesceValue = emptyArrSQL;
|
|
3969
4141
|
} else {
|
|
3970
4142
|
if (returnType === "value" || returnType === "valueOrThrow") {
|
|
@@ -4076,7 +4248,16 @@ const handleComputed = (q, computeds, column) => {
|
|
|
4076
4248
|
};
|
|
4077
4249
|
const getShapeFromSelect = (q, isSubQuery) => {
|
|
4078
4250
|
const query = q.q;
|
|
4079
|
-
const {
|
|
4251
|
+
const { shape } = query;
|
|
4252
|
+
let select;
|
|
4253
|
+
if (query.selectedComputeds) {
|
|
4254
|
+
select = query.select ? [...query.select] : [];
|
|
4255
|
+
for (const key in query.selectedComputeds) {
|
|
4256
|
+
select.push(...query.selectedComputeds[key].deps);
|
|
4257
|
+
}
|
|
4258
|
+
} else {
|
|
4259
|
+
select = query.select;
|
|
4260
|
+
}
|
|
4080
4261
|
let result;
|
|
4081
4262
|
if (!select) {
|
|
4082
4263
|
if (isSubQuery) {
|
|
@@ -4135,18 +4316,33 @@ const addColumnToShapeFromSelect = (q, arg, shape, query, result, isSubQuery, ke
|
|
|
4135
4316
|
result[key || column] = shape[column];
|
|
4136
4317
|
} else {
|
|
4137
4318
|
const it = query.joinedShapes?.[table]?.[column];
|
|
4138
|
-
if (it)
|
|
4319
|
+
if (it)
|
|
4320
|
+
result[key || column] = mapSubSelectColumn(
|
|
4321
|
+
it,
|
|
4322
|
+
isSubQuery
|
|
4323
|
+
);
|
|
4139
4324
|
}
|
|
4140
4325
|
} else if (arg === "*") {
|
|
4141
4326
|
for (const key2 in shape) {
|
|
4142
|
-
result[key2] =
|
|
4327
|
+
result[key2] = mapSubSelectColumn(
|
|
4328
|
+
shape[key2],
|
|
4329
|
+
isSubQuery
|
|
4330
|
+
);
|
|
4143
4331
|
}
|
|
4144
4332
|
} else {
|
|
4145
|
-
result[key || arg] =
|
|
4333
|
+
result[key || arg] = mapSubSelectColumn(
|
|
4334
|
+
shape[arg],
|
|
4335
|
+
isSubQuery
|
|
4336
|
+
);
|
|
4146
4337
|
}
|
|
4147
4338
|
};
|
|
4148
|
-
const
|
|
4149
|
-
|
|
4339
|
+
const mapSubSelectColumn = (column, isSubQuery) => {
|
|
4340
|
+
if (!isSubQuery || !column || !column.data.name && !column.data.explicitSelect) {
|
|
4341
|
+
return column;
|
|
4342
|
+
}
|
|
4343
|
+
const cloned = Object.create(column);
|
|
4344
|
+
cloned.data = { ...column.data, name: void 0, explicitSelect: void 0 };
|
|
4345
|
+
return cloned;
|
|
4150
4346
|
};
|
|
4151
4347
|
function _querySelect(q, args) {
|
|
4152
4348
|
var _a;
|
|
@@ -4270,171 +4466,6 @@ function _queryGetOptional(self, arg) {
|
|
|
4270
4466
|
return _get(self, "value", arg);
|
|
4271
4467
|
}
|
|
4272
4468
|
|
|
4273
|
-
const _queryAs = (self, as) => {
|
|
4274
|
-
const { q } = self;
|
|
4275
|
-
q.as = as;
|
|
4276
|
-
q.aliases = {
|
|
4277
|
-
...q.aliases,
|
|
4278
|
-
[as]: q.aliases ? _queryResolveAlias(q.aliases, as) : as
|
|
4279
|
-
};
|
|
4280
|
-
return self;
|
|
4281
|
-
};
|
|
4282
|
-
const _queryResolveAlias = (aliases, as) => {
|
|
4283
|
-
if (!aliases[as]) return as;
|
|
4284
|
-
let suffix = 2;
|
|
4285
|
-
let privateAs;
|
|
4286
|
-
while (aliases[privateAs = as + suffix]) {
|
|
4287
|
-
suffix++;
|
|
4288
|
-
}
|
|
4289
|
-
return privateAs;
|
|
4290
|
-
};
|
|
4291
|
-
class AsMethods {
|
|
4292
|
-
/**
|
|
4293
|
-
* Sets table alias:
|
|
4294
|
-
*
|
|
4295
|
-
* ```ts
|
|
4296
|
-
* db.table.as('u').select('u.name');
|
|
4297
|
-
*
|
|
4298
|
-
* // Can be used in the join:
|
|
4299
|
-
* db.table.join(Profile.as('p'), 'p.userId', 'user.id');
|
|
4300
|
-
* ```
|
|
4301
|
-
*
|
|
4302
|
-
* @param as - alias for the table of this query
|
|
4303
|
-
*/
|
|
4304
|
-
as(as) {
|
|
4305
|
-
return _queryAs(_clone(this), as);
|
|
4306
|
-
}
|
|
4307
|
-
}
|
|
4308
|
-
|
|
4309
|
-
function queryFrom(self, arg) {
|
|
4310
|
-
const data = self.q;
|
|
4311
|
-
if (typeof arg === "string") {
|
|
4312
|
-
data.as || (data.as = arg);
|
|
4313
|
-
const w = data.withShapes?.[arg];
|
|
4314
|
-
data.shape = w?.shape ?? orchidCore.emptyObject;
|
|
4315
|
-
data.computeds = w?.computeds;
|
|
4316
|
-
} else if (orchidCore.isExpression(arg)) {
|
|
4317
|
-
data.as || (data.as = "t");
|
|
4318
|
-
} else if (Array.isArray(arg)) {
|
|
4319
|
-
const { shape } = data;
|
|
4320
|
-
let clonedParsers = false;
|
|
4321
|
-
for (const item of arg) {
|
|
4322
|
-
if (typeof item === "string") {
|
|
4323
|
-
const w = data.withShapes[item];
|
|
4324
|
-
Object.assign(shape, w.shape);
|
|
4325
|
-
if (w.computeds) data.computeds = { ...data.computeds, ...w.computeds };
|
|
4326
|
-
for (const key in w.shape) {
|
|
4327
|
-
addColumnParserToQuery(
|
|
4328
|
-
self,
|
|
4329
|
-
key,
|
|
4330
|
-
w.shape[key]
|
|
4331
|
-
);
|
|
4332
|
-
}
|
|
4333
|
-
} else if (!orchidCore.isExpression(item)) {
|
|
4334
|
-
Object.assign(shape, getShapeFromSelect(item, true));
|
|
4335
|
-
if (!clonedParsers) {
|
|
4336
|
-
data.parsers = { ...data.parsers };
|
|
4337
|
-
clonedParsers = true;
|
|
4338
|
-
}
|
|
4339
|
-
Object.assign(data.parsers, item.q.parsers);
|
|
4340
|
-
}
|
|
4341
|
-
}
|
|
4342
|
-
} else {
|
|
4343
|
-
const q = arg;
|
|
4344
|
-
data.as || (data.as = q.q.as || q.table || "t");
|
|
4345
|
-
data.shape = getShapeFromSelect(q, true);
|
|
4346
|
-
data.parsers = q.q.parsers;
|
|
4347
|
-
data.batchParsers = q.q.batchParsers;
|
|
4348
|
-
}
|
|
4349
|
-
data.from = arg;
|
|
4350
|
-
data.selectAllColumns = data.scopes = void 0;
|
|
4351
|
-
return self;
|
|
4352
|
-
}
|
|
4353
|
-
function queryFromSql(self, args) {
|
|
4354
|
-
const data = self.q;
|
|
4355
|
-
data.as || (data.as = "t");
|
|
4356
|
-
data.from = sqlQueryArgsToExpression(args);
|
|
4357
|
-
data.selectAllColumns = void 0;
|
|
4358
|
-
return self;
|
|
4359
|
-
}
|
|
4360
|
-
class FromMethods {
|
|
4361
|
-
/**
|
|
4362
|
-
* Set the `FROM` value, by default the table name is used.
|
|
4363
|
-
*
|
|
4364
|
-
* `from` determines a set of available tables and columns withing the query,
|
|
4365
|
-
* and thus it must not follow `select`, use `select` only after `from`.
|
|
4366
|
-
*
|
|
4367
|
-
* ```ts
|
|
4368
|
-
* // accepts sub-query:
|
|
4369
|
-
* db.table.from(db.otherTable.select('foo', 'bar'));
|
|
4370
|
-
*
|
|
4371
|
-
* // accepts alias of `WITH` expression:
|
|
4372
|
-
* q.with('withTable', db.table.select('id', 'name'))
|
|
4373
|
-
* .from('withTable')
|
|
4374
|
-
* // `select` is after `from`
|
|
4375
|
-
* .select('id', 'name');
|
|
4376
|
-
* ```
|
|
4377
|
-
*
|
|
4378
|
-
* `from` can accept multiple sources:
|
|
4379
|
-
*
|
|
4380
|
-
* ```ts
|
|
4381
|
-
* db.table
|
|
4382
|
-
* // add a `WITH` statement called `withTable
|
|
4383
|
-
* .with('withTable', db.table.select('one'))
|
|
4384
|
-
* // select from `withTable` and from `otherTable`
|
|
4385
|
-
* .from('withTable', db.otherTable.select('two'))
|
|
4386
|
-
* // source names and column names are properly typed when selecting
|
|
4387
|
-
* .select('withTable.one', 'otherTable.two');
|
|
4388
|
-
* ```
|
|
4389
|
-
*
|
|
4390
|
-
* @param arg - query or name of CTE table
|
|
4391
|
-
*/
|
|
4392
|
-
from(arg) {
|
|
4393
|
-
return queryFrom(_clone(this), arg);
|
|
4394
|
-
}
|
|
4395
|
-
/**
|
|
4396
|
-
* Set the `FROM` value with custom SQL:
|
|
4397
|
-
*
|
|
4398
|
-
* ```ts
|
|
4399
|
-
* const value = 123;
|
|
4400
|
-
* db.table.fromSql`value = ${value}`;
|
|
4401
|
-
* ```
|
|
4402
|
-
*
|
|
4403
|
-
* @param args - SQL expression
|
|
4404
|
-
*/
|
|
4405
|
-
fromSql(...args) {
|
|
4406
|
-
return queryFromSql(_clone(this), args);
|
|
4407
|
-
}
|
|
4408
|
-
/**
|
|
4409
|
-
* Adds `ONLY` SQL keyword to the `FROM`.
|
|
4410
|
-
* When selecting from a parent table that has a table inheritance,
|
|
4411
|
-
* setting `only` will make it to select rows only from the parent table.
|
|
4412
|
-
*
|
|
4413
|
-
* ```ts
|
|
4414
|
-
* db.table.only();
|
|
4415
|
-
*
|
|
4416
|
-
* // disabling `only` after being enabled
|
|
4417
|
-
* db.table.only().only(false);
|
|
4418
|
-
* ```
|
|
4419
|
-
*
|
|
4420
|
-
* @param only - can be disabled by passing `false` if was enabled previously.
|
|
4421
|
-
*/
|
|
4422
|
-
only(only = true) {
|
|
4423
|
-
const q = _clone(this);
|
|
4424
|
-
q.q.only = only;
|
|
4425
|
-
return q;
|
|
4426
|
-
}
|
|
4427
|
-
}
|
|
4428
|
-
|
|
4429
|
-
function queryWrap(self, query, as = "t") {
|
|
4430
|
-
return _queryAs(queryFrom(query, self), as);
|
|
4431
|
-
}
|
|
4432
|
-
function cloneQueryBaseUnscoped(query) {
|
|
4433
|
-
const q = query.baseQuery.clone();
|
|
4434
|
-
q.q.or = q.q.and = q.q.scopes = void 0;
|
|
4435
|
-
return q;
|
|
4436
|
-
}
|
|
4437
|
-
|
|
4438
4469
|
class RowToJsonExpression extends orchidCore.Expression {
|
|
4439
4470
|
constructor(from, one, coalesce) {
|
|
4440
4471
|
super();
|
|
@@ -4472,10 +4503,7 @@ class RowToJsonExpression extends orchidCore.Expression {
|
|
|
4472
4503
|
}
|
|
4473
4504
|
function queryJson(self, coalesce) {
|
|
4474
4505
|
const inner = self.clone();
|
|
4475
|
-
const q = queryWrap(
|
|
4476
|
-
inner,
|
|
4477
|
-
cloneQueryBaseUnscoped(self)
|
|
4478
|
-
);
|
|
4506
|
+
const q = queryWrap(inner, cloneQueryBaseUnscoped(inner));
|
|
4479
4507
|
_queryGetOptional(
|
|
4480
4508
|
q,
|
|
4481
4509
|
new RowToJsonExpression(
|
|
@@ -4914,18 +4942,23 @@ const selectToSql = (ctx, table, query, quotedAs, hookSelect = query.hookSelect,
|
|
|
4914
4942
|
let quotedTable;
|
|
4915
4943
|
let columnName;
|
|
4916
4944
|
let col;
|
|
4917
|
-
|
|
4918
|
-
|
|
4919
|
-
|
|
4920
|
-
|
|
4921
|
-
|
|
4922
|
-
|
|
4923
|
-
|
|
4945
|
+
if (typeof select === "string") {
|
|
4946
|
+
const index = select.indexOf(".");
|
|
4947
|
+
if (index !== -1) {
|
|
4948
|
+
const tableName = select.slice(0, index);
|
|
4949
|
+
quotedTable = `"${tableName}"`;
|
|
4950
|
+
columnName = select.slice(index + 1);
|
|
4951
|
+
col = table.q.joinedShapes?.[tableName]?.[columnName];
|
|
4952
|
+
sql = col?.data.computed ? col.data.computed.toSQL(ctx, `"${tableName}"`) : `"${tableName}"."${col?.data.name || columnName}"`;
|
|
4953
|
+
} else {
|
|
4954
|
+
quotedTable = quotedAs;
|
|
4955
|
+
columnName = select;
|
|
4956
|
+
col = query.shape[select];
|
|
4957
|
+
sql = simpleColumnToSQL(ctx, query, select, col, quotedAs);
|
|
4958
|
+
}
|
|
4924
4959
|
} else {
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
col = query.shape[select];
|
|
4928
|
-
sql = simpleColumnToSQL(ctx, query, select, col, quotedAs);
|
|
4960
|
+
columnName = column;
|
|
4961
|
+
sql = select.sql;
|
|
4929
4962
|
}
|
|
4930
4963
|
let name = columnName;
|
|
4931
4964
|
if (selected?.[columnName]) {
|
|
@@ -4937,7 +4970,7 @@ const selectToSql = (ctx, table, query, quotedAs, hookSelect = query.hookSelect,
|
|
|
4937
4970
|
while (selected[name = `${column}${i}`]) i++;
|
|
4938
4971
|
item.as = name;
|
|
4939
4972
|
sql += ` "${name}"`;
|
|
4940
|
-
} else if (col?.data.name) {
|
|
4973
|
+
} else if (col?.data.name || typeof select === "object") {
|
|
4941
4974
|
sql += ` "${columnName}"`;
|
|
4942
4975
|
}
|
|
4943
4976
|
if (jsonList) jsonList[name] = col;
|
|
@@ -5166,6 +5199,7 @@ const queryKeysOfNotSimpleQuery = [
|
|
|
5166
5199
|
"for"
|
|
5167
5200
|
];
|
|
5168
5201
|
|
|
5202
|
+
let fromQuery;
|
|
5169
5203
|
const pushFromAndAs = (ctx, table, data, quotedAs) => {
|
|
5170
5204
|
let sql = "FROM ";
|
|
5171
5205
|
const from = getFrom(ctx, table, data, quotedAs);
|
|
@@ -5202,8 +5236,15 @@ const pushFromAndAs = (ctx, table, data, quotedAs) => {
|
|
|
5202
5236
|
sql += `, ${fn}(${lang}, ${querySql}) "${as}"`;
|
|
5203
5237
|
}
|
|
5204
5238
|
ctx.sql.push(sql);
|
|
5239
|
+
if (fromQuery) {
|
|
5240
|
+
const fq = fromQuery;
|
|
5241
|
+
fromQuery = void 0;
|
|
5242
|
+
return fq;
|
|
5243
|
+
}
|
|
5244
|
+
return;
|
|
5205
5245
|
};
|
|
5206
5246
|
const getFrom = (ctx, table, data, quotedAs) => {
|
|
5247
|
+
fromQuery = void 0;
|
|
5207
5248
|
if (data.from) {
|
|
5208
5249
|
const { from } = data;
|
|
5209
5250
|
if (Array.isArray(from)) {
|
|
@@ -5230,6 +5271,7 @@ const fromToSql = (ctx, data, from, quotedAs) => {
|
|
|
5230
5271
|
} else {
|
|
5231
5272
|
sql = quoteSchemaAndTable(from.q.schema, from.table);
|
|
5232
5273
|
}
|
|
5274
|
+
fromQuery = from;
|
|
5233
5275
|
}
|
|
5234
5276
|
} else {
|
|
5235
5277
|
sql = quoteSchemaAndTable(data.schema, from);
|
|
@@ -5500,6 +5542,7 @@ const toSQL = (table, options) => {
|
|
|
5500
5542
|
if (query.with) {
|
|
5501
5543
|
pushWithSql(ctx, query.with);
|
|
5502
5544
|
}
|
|
5545
|
+
let fromQuery;
|
|
5503
5546
|
if (query.type && query.type !== "upsert") {
|
|
5504
5547
|
const tableName = table.table ?? query.as;
|
|
5505
5548
|
if (!tableName) throw new Error(`Table is missing for ${query.type}`);
|
|
@@ -5549,9 +5592,7 @@ const toSQL = (table, options) => {
|
|
|
5549
5592
|
}
|
|
5550
5593
|
const aliases = query.group ? [] : void 0;
|
|
5551
5594
|
pushSelectSql(ctx, table, query, quotedAs, aliases);
|
|
5552
|
-
|
|
5553
|
-
pushFromAndAs(ctx, table, query, quotedAs);
|
|
5554
|
-
}
|
|
5595
|
+
fromQuery = (table.table || query.from) && pushFromAndAs(ctx, table, query, quotedAs) || void 0;
|
|
5555
5596
|
if (query.join) {
|
|
5556
5597
|
pushJoinSql(
|
|
5557
5598
|
ctx,
|
|
@@ -5590,9 +5631,19 @@ const toSQL = (table, options) => {
|
|
|
5590
5631
|
if (query.order) {
|
|
5591
5632
|
pushOrderBySql(ctx, query, quotedAs, query.order);
|
|
5592
5633
|
}
|
|
5593
|
-
|
|
5594
|
-
|
|
5595
|
-
|
|
5634
|
+
if (query.useFromLimitOffset) {
|
|
5635
|
+
const q = fromQuery?.q;
|
|
5636
|
+
if (q.limit) {
|
|
5637
|
+
sql.push(`LIMIT ${orchidCore.addValue(values, q.limit)}`);
|
|
5638
|
+
}
|
|
5639
|
+
if (q.offset) {
|
|
5640
|
+
sql.push(`OFFSET ${orchidCore.addValue(values, q.offset)}`);
|
|
5641
|
+
}
|
|
5642
|
+
} else {
|
|
5643
|
+
pushLimitSQL(sql, values, query);
|
|
5644
|
+
if (query.offset && !query.returnsOne) {
|
|
5645
|
+
sql.push(`OFFSET ${orchidCore.addValue(values, query.offset)}`);
|
|
5646
|
+
}
|
|
5596
5647
|
}
|
|
5597
5648
|
if (query.for) {
|
|
5598
5649
|
sql.push("FOR", query.for.type);
|
|
@@ -6997,7 +7048,9 @@ const _chain = (fromQuery, toQuery, rel) => {
|
|
|
6997
7048
|
if (
|
|
6998
7049
|
// `select({ q => q.rel })`: on the first relation it doesn't matter if the parent has chainMultiple
|
|
6999
7050
|
self.q.subQuery > 1 && self.q.chainMultiple
|
|
7000
|
-
)
|
|
7051
|
+
) {
|
|
7052
|
+
q.returnType = q.returnsOne = q.limit = void 0;
|
|
7053
|
+
} else if (!rel.query.q.returnsOne) {
|
|
7001
7054
|
q.chainMultiple = true;
|
|
7002
7055
|
}
|
|
7003
7056
|
} else {
|
|
@@ -10242,7 +10295,7 @@ class JsonMethods {
|
|
|
10242
10295
|
* @param coalesce
|
|
10243
10296
|
*/
|
|
10244
10297
|
json(coalesce) {
|
|
10245
|
-
return queryJson(
|
|
10298
|
+
return queryJson(this, coalesce);
|
|
10246
10299
|
}
|
|
10247
10300
|
}
|
|
10248
10301
|
|