@carbonorm/carbonnode 3.10.0 → 3.11.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/api/C6Constants.d.ts +20 -0
- package/dist/api/orm/builders/ConditionBuilder.d.ts +5 -0
- package/dist/api/orm/builders/JoinBuilder.d.ts +9 -0
- package/dist/index.cjs.js +299 -2
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +299 -2
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/fixtures/c6.fixture.ts +3 -0
- package/src/__tests__/sakila-db/C6.js +1 -1
- package/src/__tests__/sakila-db/C6.ts +1 -1
- package/src/__tests__/sqlBuilders.complex.test.ts +85 -0
- package/src/api/C6Constants.ts +12 -2
- package/src/api/orm/builders/ConditionBuilder.ts +173 -0
- package/src/api/orm/builders/JoinBuilder.ts +150 -1
- package/src/api/orm/queries/SelectQueryBuilder.ts +5 -0
|
@@ -27,10 +27,12 @@ export declare const C6Constants: {
|
|
|
27
27
|
DATE_FORMAT: string;
|
|
28
28
|
DESC: string;
|
|
29
29
|
DISTINCT: string;
|
|
30
|
+
EXISTS: string;
|
|
30
31
|
EXTRACT: string;
|
|
31
32
|
EQUAL: string;
|
|
32
33
|
EQUAL_NULL_SAFE: string;
|
|
33
34
|
FALSE: string;
|
|
35
|
+
FORCE: string;
|
|
34
36
|
FULL_OUTER: string;
|
|
35
37
|
FROM_DAYS: string;
|
|
36
38
|
FROM_UNIXTIME: string;
|
|
@@ -46,6 +48,7 @@ export declare const C6Constants: {
|
|
|
46
48
|
HOUR_SECOND: string;
|
|
47
49
|
HOUR_MINUTE: string;
|
|
48
50
|
IN: string;
|
|
51
|
+
INDEX: string;
|
|
49
52
|
IS: string;
|
|
50
53
|
IS_NOT: string;
|
|
51
54
|
INNER: string;
|
|
@@ -63,6 +66,7 @@ export declare const C6Constants: {
|
|
|
63
66
|
MAKEDATE: string;
|
|
64
67
|
MAKETIME: string;
|
|
65
68
|
MATCH_AGAINST: string;
|
|
69
|
+
MBRCONTAINS: string;
|
|
66
70
|
MONTHNAME: string;
|
|
67
71
|
MICROSECOND: string;
|
|
68
72
|
MINUTE: string;
|
|
@@ -78,8 +82,14 @@ export declare const C6Constants: {
|
|
|
78
82
|
NULL: string;
|
|
79
83
|
ORDER: string;
|
|
80
84
|
OR: string;
|
|
85
|
+
INDEX_HINTS: string;
|
|
86
|
+
FORCE_INDEX: string;
|
|
87
|
+
USE_INDEX: string;
|
|
88
|
+
IGNORE_INDEX: string;
|
|
81
89
|
PAGE: string;
|
|
82
90
|
PAGINATION: string;
|
|
91
|
+
POLYGON: string;
|
|
92
|
+
POINT: string;
|
|
83
93
|
RIGHT_OUTER: string;
|
|
84
94
|
SECOND: string;
|
|
85
95
|
SECOND_MICROSECOND: string;
|
|
@@ -188,10 +198,12 @@ export declare const C6C: {
|
|
|
188
198
|
DATE_FORMAT: string;
|
|
189
199
|
DESC: string;
|
|
190
200
|
DISTINCT: string;
|
|
201
|
+
EXISTS: string;
|
|
191
202
|
EXTRACT: string;
|
|
192
203
|
EQUAL: string;
|
|
193
204
|
EQUAL_NULL_SAFE: string;
|
|
194
205
|
FALSE: string;
|
|
206
|
+
FORCE: string;
|
|
195
207
|
FULL_OUTER: string;
|
|
196
208
|
FROM_DAYS: string;
|
|
197
209
|
FROM_UNIXTIME: string;
|
|
@@ -207,6 +219,7 @@ export declare const C6C: {
|
|
|
207
219
|
HOUR_SECOND: string;
|
|
208
220
|
HOUR_MINUTE: string;
|
|
209
221
|
IN: string;
|
|
222
|
+
INDEX: string;
|
|
210
223
|
IS: string;
|
|
211
224
|
IS_NOT: string;
|
|
212
225
|
INNER: string;
|
|
@@ -224,6 +237,7 @@ export declare const C6C: {
|
|
|
224
237
|
MAKEDATE: string;
|
|
225
238
|
MAKETIME: string;
|
|
226
239
|
MATCH_AGAINST: string;
|
|
240
|
+
MBRCONTAINS: string;
|
|
227
241
|
MONTHNAME: string;
|
|
228
242
|
MICROSECOND: string;
|
|
229
243
|
MINUTE: string;
|
|
@@ -239,8 +253,14 @@ export declare const C6C: {
|
|
|
239
253
|
NULL: string;
|
|
240
254
|
ORDER: string;
|
|
241
255
|
OR: string;
|
|
256
|
+
INDEX_HINTS: string;
|
|
257
|
+
FORCE_INDEX: string;
|
|
258
|
+
USE_INDEX: string;
|
|
259
|
+
IGNORE_INDEX: string;
|
|
242
260
|
PAGE: string;
|
|
243
261
|
PAGINATION: string;
|
|
262
|
+
POLYGON: string;
|
|
263
|
+
POINT: string;
|
|
244
264
|
RIGHT_OUTER: string;
|
|
245
265
|
SECOND: string;
|
|
246
266
|
SECOND_MICROSECOND: string;
|
|
@@ -13,6 +13,7 @@ export declare abstract class ConditionBuilder<G extends OrmGenerics> extends Ag
|
|
|
13
13
|
execute(): Promise<DetermineResponseDataType<G['RequestMethod'], G['RestTableInterface']>>;
|
|
14
14
|
private readonly BOOLEAN_OPERATORS;
|
|
15
15
|
private readonly OPERATOR_ALIASES;
|
|
16
|
+
private readonly BOOLEAN_FUNCTION_KEYS;
|
|
16
17
|
private isTableReference;
|
|
17
18
|
addParam(params: any[] | Record<string, any>, column: string, value: any): string;
|
|
18
19
|
private normalizeOperatorKey;
|
|
@@ -24,6 +25,10 @@ export declare abstract class ConditionBuilder<G extends OrmGenerics> extends Ag
|
|
|
24
25
|
private normalizeFunctionField;
|
|
25
26
|
private buildFunctionCall;
|
|
26
27
|
private serializeOperand;
|
|
28
|
+
private ensurePlainObject;
|
|
29
|
+
private resolveExistsInnerColumn;
|
|
30
|
+
private normalizeExistsSpec;
|
|
31
|
+
private buildExistsExpression;
|
|
27
32
|
private buildOperatorExpression;
|
|
28
33
|
private buildLegacyColumnCondition;
|
|
29
34
|
private buildBooleanExpression;
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
import { OrmGenerics } from "../../types/ormGenerics";
|
|
2
2
|
import { ConditionBuilder } from "./ConditionBuilder";
|
|
3
3
|
export declare abstract class JoinBuilder<G extends OrmGenerics> extends ConditionBuilder<G> {
|
|
4
|
+
private indexHintCache?;
|
|
4
5
|
protected createSelectBuilder(_request: any): {
|
|
5
6
|
build(table: string, isSubSelect: boolean): {
|
|
6
7
|
sql: string;
|
|
7
8
|
params: any[] | Record<string, any>;
|
|
8
9
|
};
|
|
9
10
|
};
|
|
11
|
+
protected resetIndexHints(): void;
|
|
12
|
+
private normalizeIndexHintKey;
|
|
13
|
+
private normalizeHintTargetKey;
|
|
14
|
+
private hasIndexHintKeys;
|
|
15
|
+
private normalizeHintSpec;
|
|
16
|
+
private formatIndexHintClause;
|
|
17
|
+
private normalizeIndexHints;
|
|
18
|
+
protected getIndexHintClause(table: string, alias?: string): string;
|
|
10
19
|
buildJoinClauses(joinArgs: any, params: any[] | Record<string, any>): string;
|
|
11
20
|
protected integrateSubSelectParams(subSql: string, subParams: any[] | Record<string, any>, target: any[] | Record<string, any>): string;
|
|
12
21
|
protected buildScalarSubSelect(subRequest: any, params: any[] | Record<string, any>): string;
|
package/dist/index.cjs.js
CHANGED
|
@@ -38,10 +38,12 @@ var C6Constants = {
|
|
|
38
38
|
DATE_FORMAT: 'DATE_FORMAT',
|
|
39
39
|
DESC: 'DESC',
|
|
40
40
|
DISTINCT: 'DISTINCT',
|
|
41
|
+
EXISTS: 'EXISTS',
|
|
41
42
|
EXTRACT: 'EXTRACT',
|
|
42
43
|
EQUAL: '=',
|
|
43
44
|
EQUAL_NULL_SAFE: '<=>',
|
|
44
45
|
FALSE: 'FALSE',
|
|
46
|
+
FORCE: 'FORCE',
|
|
45
47
|
FULL_OUTER: 'FULL_OUTER',
|
|
46
48
|
FROM_DAYS: 'FROM_DAYS',
|
|
47
49
|
FROM_UNIXTIME: 'FROM_UNIXTIME',
|
|
@@ -57,6 +59,7 @@ var C6Constants = {
|
|
|
57
59
|
HOUR_SECOND: 'HOUR_SECOND',
|
|
58
60
|
HOUR_MINUTE: 'HOUR_MINUTE',
|
|
59
61
|
IN: 'IN',
|
|
62
|
+
INDEX: 'INDEX',
|
|
60
63
|
IS: 'IS',
|
|
61
64
|
IS_NOT: 'IS_NOT',
|
|
62
65
|
INNER: 'INNER',
|
|
@@ -74,6 +77,7 @@ var C6Constants = {
|
|
|
74
77
|
MAKEDATE: 'MAKEDATE',
|
|
75
78
|
MAKETIME: 'MAKETIME',
|
|
76
79
|
MATCH_AGAINST: 'MATCH_AGAINST',
|
|
80
|
+
MBRCONTAINS: 'MBRContains',
|
|
77
81
|
MONTHNAME: 'MONTHNAME',
|
|
78
82
|
MICROSECOND: 'MICROSECOND',
|
|
79
83
|
MINUTE: 'MINUTE',
|
|
@@ -89,8 +93,14 @@ var C6Constants = {
|
|
|
89
93
|
NULL: 'NULL',
|
|
90
94
|
ORDER: 'ORDER',
|
|
91
95
|
OR: 'OR',
|
|
96
|
+
INDEX_HINTS: 'INDEX_HINTS',
|
|
97
|
+
FORCE_INDEX: 'FORCE INDEX',
|
|
98
|
+
USE_INDEX: 'USE INDEX',
|
|
99
|
+
IGNORE_INDEX: 'IGNORE INDEX',
|
|
92
100
|
PAGE: 'PAGE',
|
|
93
101
|
PAGINATION: 'PAGINATION',
|
|
102
|
+
POLYGON: 'POLYGON',
|
|
103
|
+
POINT: 'POINT',
|
|
94
104
|
RIGHT_OUTER: 'RIGHT_OUTER',
|
|
95
105
|
SECOND: 'SECOND',
|
|
96
106
|
SECOND_MICROSECOND: 'SECOND_MICROSECOND',
|
|
@@ -1451,7 +1461,8 @@ var stContains = function (envelope, shape) {
|
|
|
1451
1461
|
var ConditionBuilder = /** @class */ (function (_super) {
|
|
1452
1462
|
tslib.__extends(ConditionBuilder, _super);
|
|
1453
1463
|
function ConditionBuilder() {
|
|
1454
|
-
var
|
|
1464
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
1465
|
+
var _this = _super.apply(this, arguments) || this;
|
|
1455
1466
|
_this.aliasMap = {};
|
|
1456
1467
|
_this.derivedAliases = new Set();
|
|
1457
1468
|
_this.BOOLEAN_OPERATORS = new Map([
|
|
@@ -1490,8 +1501,16 @@ var ConditionBuilder = /** @class */ (function (_super) {
|
|
|
1490
1501
|
[C6C.BETWEEN, C6C.BETWEEN],
|
|
1491
1502
|
['BETWEEN', C6C.BETWEEN],
|
|
1492
1503
|
['NOT BETWEEN', 'NOT BETWEEN'],
|
|
1504
|
+
[C6C.EXISTS, C6C.EXISTS],
|
|
1505
|
+
['EXISTS', C6C.EXISTS],
|
|
1506
|
+
['NOT EXISTS', 'NOT EXISTS'],
|
|
1493
1507
|
[C6C.MATCH_AGAINST, C6C.MATCH_AGAINST],
|
|
1494
1508
|
]);
|
|
1509
|
+
_this.BOOLEAN_FUNCTION_KEYS = new Set([
|
|
1510
|
+
(_c = (_b = (_a = C6C.ST_CONTAINS) === null || _a === void 0 ? void 0 : _a.toUpperCase) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : 'ST_CONTAINS',
|
|
1511
|
+
(_f = (_e = (_d = C6C.ST_WITHIN) === null || _d === void 0 ? void 0 : _d.toUpperCase) === null || _e === void 0 ? void 0 : _e.call(_d)) !== null && _f !== void 0 ? _f : 'ST_WITHIN',
|
|
1512
|
+
(_j = (_h = (_g = C6C.MBRCONTAINS) === null || _g === void 0 ? void 0 : _g.toUpperCase) === null || _h === void 0 ? void 0 : _h.call(_g)) !== null && _j !== void 0 ? _j : 'MBRCONTAINS',
|
|
1513
|
+
]);
|
|
1495
1514
|
return _this;
|
|
1496
1515
|
}
|
|
1497
1516
|
ConditionBuilder.prototype.initAlias = function (baseTable, joins) {
|
|
@@ -1726,6 +1745,9 @@ var ConditionBuilder = /** @class */ (function (_super) {
|
|
|
1726
1745
|
if (operand === null || typeof operand === 'number' || typeof operand === 'boolean') {
|
|
1727
1746
|
return { sql: asParam(operand), isReference: false, isExpression: false, isSubSelect: false };
|
|
1728
1747
|
}
|
|
1748
|
+
if (typeof Buffer !== 'undefined' && Buffer.isBuffer && Buffer.isBuffer(operand)) {
|
|
1749
|
+
return { sql: asParam(operand), isReference: false, isExpression: false, isSubSelect: false };
|
|
1750
|
+
}
|
|
1729
1751
|
if (typeof operand === 'string') {
|
|
1730
1752
|
if (this.isTableReference(operand) || this.isColumnRef(operand)) {
|
|
1731
1753
|
return { sql: operand, isReference: true, isExpression: false, isSubSelect: false };
|
|
@@ -1769,10 +1791,129 @@ var ConditionBuilder = /** @class */ (function (_super) {
|
|
|
1769
1791
|
}
|
|
1770
1792
|
throw new Error('Unsupported operand type in SQL expression.');
|
|
1771
1793
|
};
|
|
1794
|
+
ConditionBuilder.prototype.ensurePlainObject = function (value) {
|
|
1795
|
+
if (value instanceof Map) {
|
|
1796
|
+
return Object.fromEntries(value);
|
|
1797
|
+
}
|
|
1798
|
+
return value;
|
|
1799
|
+
};
|
|
1800
|
+
ConditionBuilder.prototype.resolveExistsInnerColumn = function (subRequest, provided) {
|
|
1801
|
+
var _a, _b;
|
|
1802
|
+
if (provided) {
|
|
1803
|
+
if (typeof provided !== 'string' || provided.trim() === '') {
|
|
1804
|
+
throw new Error('EXISTS correlation column must be a non-empty string.');
|
|
1805
|
+
}
|
|
1806
|
+
return provided;
|
|
1807
|
+
}
|
|
1808
|
+
var selectClause = this.ensurePlainObject(subRequest === null || subRequest === void 0 ? void 0 : subRequest[C6C.SELECT]);
|
|
1809
|
+
if (Array.isArray(selectClause) && selectClause.length > 0) {
|
|
1810
|
+
var candidate = selectClause[0];
|
|
1811
|
+
if (typeof candidate === 'string' && candidate.trim() !== '') {
|
|
1812
|
+
return candidate;
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
var fromTable = subRequest === null || subRequest === void 0 ? void 0 : subRequest[C6C.FROM];
|
|
1816
|
+
if (typeof fromTable === 'string' && fromTable.trim() !== '') {
|
|
1817
|
+
var table = (_b = (_a = this.config.C6) === null || _a === void 0 ? void 0 : _a.TABLES) === null || _b === void 0 ? void 0 : _b[fromTable.trim()];
|
|
1818
|
+
var primary = table === null || table === void 0 ? void 0 : table.PRIMARY;
|
|
1819
|
+
if (Array.isArray(primary) && primary.length > 0) {
|
|
1820
|
+
return String(primary[0]);
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
throw new Error('EXISTS requires a correlation column to be provided or inferable from the subselect.');
|
|
1824
|
+
};
|
|
1825
|
+
ConditionBuilder.prototype.normalizeExistsSpec = function (spec) {
|
|
1826
|
+
var normalized = this.ensurePlainObject(spec);
|
|
1827
|
+
if (!Array.isArray(normalized) || normalized.length < 2) {
|
|
1828
|
+
throw new Error('EXISTS expects an array like [outerColumn, subselect, innerColumn?].');
|
|
1829
|
+
}
|
|
1830
|
+
var outerRaw = normalized[0], payloadRaw = normalized[1], innerRaw = normalized[2];
|
|
1831
|
+
if (typeof outerRaw !== 'string' || outerRaw.trim() === '') {
|
|
1832
|
+
throw new Error('EXISTS requires the first element to be an outer column reference string.');
|
|
1833
|
+
}
|
|
1834
|
+
var payload = this.ensurePlainObject(payloadRaw);
|
|
1835
|
+
var subSelect;
|
|
1836
|
+
if (payload && typeof payload === 'object' && C6C.SUBSELECT in payload) {
|
|
1837
|
+
subSelect = this.ensurePlainObject(payload[C6C.SUBSELECT]);
|
|
1838
|
+
}
|
|
1839
|
+
else if (payload && typeof payload === 'object') {
|
|
1840
|
+
subSelect = payload;
|
|
1841
|
+
}
|
|
1842
|
+
else {
|
|
1843
|
+
throw new Error('EXISTS requires a subselect payload as the second element.');
|
|
1844
|
+
}
|
|
1845
|
+
if (!subSelect || typeof subSelect !== 'object') {
|
|
1846
|
+
throw new Error('EXISTS subselect payload must be an object.');
|
|
1847
|
+
}
|
|
1848
|
+
var innerColumn = typeof innerRaw === 'string' ? innerRaw : undefined;
|
|
1849
|
+
return {
|
|
1850
|
+
outerColumn: outerRaw,
|
|
1851
|
+
subRequest: tslib.__assign({}, subSelect),
|
|
1852
|
+
innerColumn: innerColumn,
|
|
1853
|
+
};
|
|
1854
|
+
};
|
|
1855
|
+
ConditionBuilder.prototype.buildExistsExpression = function (spec, operator, params) {
|
|
1856
|
+
var _a, _b, _c, _d;
|
|
1857
|
+
var _this = this;
|
|
1858
|
+
var _e;
|
|
1859
|
+
var _f = this.normalizeExistsSpec(spec), outerColumn = _f.outerColumn, subRequest = _f.subRequest, innerColumn = _f.innerColumn;
|
|
1860
|
+
var fromTableRaw = subRequest[C6C.FROM];
|
|
1861
|
+
if (typeof fromTableRaw !== 'string' || fromTableRaw.trim() === '') {
|
|
1862
|
+
throw new Error('EXISTS subselect requires a table specified with C6C.FROM.');
|
|
1863
|
+
}
|
|
1864
|
+
var fromTable = fromTableRaw.trim();
|
|
1865
|
+
this.assertValidIdentifier(outerColumn, 'EXISTS correlation column');
|
|
1866
|
+
var correlationColumn = this.resolveExistsInnerColumn(subRequest, innerColumn);
|
|
1867
|
+
if (!this.isColumnRef(correlationColumn) && !this.isTableReference(correlationColumn)) {
|
|
1868
|
+
throw new Error("Unknown column reference '".concat(correlationColumn, "' used in EXISTS subquery correlation column."));
|
|
1869
|
+
}
|
|
1870
|
+
var existingWhereRaw = this.ensurePlainObject(subRequest[C6C.WHERE]);
|
|
1871
|
+
var correlationCondition = (_a = {}, _a[correlationColumn] = [C6C.EQUAL, outerColumn], _a);
|
|
1872
|
+
var normalizedExistingWhere = existingWhereRaw && typeof existingWhereRaw === 'object'
|
|
1873
|
+
? Array.isArray(existingWhereRaw)
|
|
1874
|
+
? existingWhereRaw.slice()
|
|
1875
|
+
: tslib.__assign({}, existingWhereRaw)
|
|
1876
|
+
: existingWhereRaw;
|
|
1877
|
+
var hasExistingWhere = Array.isArray(normalizedExistingWhere)
|
|
1878
|
+
? normalizedExistingWhere.length > 0
|
|
1879
|
+
: normalizedExistingWhere && typeof normalizedExistingWhere === 'object'
|
|
1880
|
+
? Object.keys(normalizedExistingWhere).length > 0
|
|
1881
|
+
: normalizedExistingWhere != null;
|
|
1882
|
+
var whereClause;
|
|
1883
|
+
if (!hasExistingWhere) {
|
|
1884
|
+
whereClause = correlationCondition;
|
|
1885
|
+
}
|
|
1886
|
+
else if (normalizedExistingWhere && typeof normalizedExistingWhere === 'object' &&
|
|
1887
|
+
Object.keys(normalizedExistingWhere).some(function (key) { return _this.BOOLEAN_OPERATORS.has(key); })) {
|
|
1888
|
+
whereClause = (_b = {}, _b[C6C.AND] = [normalizedExistingWhere, correlationCondition], _b);
|
|
1889
|
+
}
|
|
1890
|
+
else if (normalizedExistingWhere && typeof normalizedExistingWhere === 'object') {
|
|
1891
|
+
whereClause = tslib.__assign(tslib.__assign({}, normalizedExistingWhere), correlationCondition);
|
|
1892
|
+
}
|
|
1893
|
+
else {
|
|
1894
|
+
whereClause = (_c = {}, _c[C6C.AND] = [normalizedExistingWhere, correlationCondition], _c);
|
|
1895
|
+
}
|
|
1896
|
+
var subRequestWithCorrelation = tslib.__assign(tslib.__assign({}, subRequest), (_d = {}, _d[C6C.FROM] = fromTable, _d[C6C.WHERE] = whereClause, _d[C6C.SELECT] = (_e = subRequest[C6C.SELECT]) !== null && _e !== void 0 ? _e : ['1'], _d));
|
|
1897
|
+
var buildScalarSubSelect = this.buildScalarSubSelect;
|
|
1898
|
+
if (typeof buildScalarSubSelect !== 'function') {
|
|
1899
|
+
throw new Error('EXISTS operator requires SelectQueryBuilder context.');
|
|
1900
|
+
}
|
|
1901
|
+
var scalar = buildScalarSubSelect.call(this, subRequestWithCorrelation, params);
|
|
1902
|
+
var keyword = operator === 'NOT EXISTS' ? 'NOT EXISTS' : C6C.EXISTS;
|
|
1903
|
+
return "".concat(keyword, " ").concat(scalar);
|
|
1904
|
+
};
|
|
1772
1905
|
ConditionBuilder.prototype.buildOperatorExpression = function (op, rawOperands, params, contextColumn) {
|
|
1773
1906
|
var _a, _b;
|
|
1774
1907
|
var _this = this;
|
|
1775
1908
|
var operator = this.formatOperator(op);
|
|
1909
|
+
if (operator === C6C.EXISTS || operator === 'NOT EXISTS') {
|
|
1910
|
+
var operands_1 = Array.isArray(rawOperands) ? rawOperands : [rawOperands];
|
|
1911
|
+
if (!operands_1.length) {
|
|
1912
|
+
throw new Error("".concat(operator, " requires at least one subselect specification."));
|
|
1913
|
+
}
|
|
1914
|
+
var clauses = operands_1.map(function (spec) { return _this.buildExistsExpression(spec, operator, params); });
|
|
1915
|
+
return this.joinBooleanParts(clauses, 'AND');
|
|
1916
|
+
}
|
|
1776
1917
|
if (operator === C6C.MATCH_AGAINST) {
|
|
1777
1918
|
if (!Array.isArray(rawOperands) || rawOperands.length !== 2) {
|
|
1778
1919
|
throw new Error('MATCH_AGAINST requires an array of two operands.');
|
|
@@ -1882,6 +2023,18 @@ var ConditionBuilder = /** @class */ (function (_super) {
|
|
|
1882
2023
|
if (value instanceof Map) {
|
|
1883
2024
|
value = Object.fromEntries(value);
|
|
1884
2025
|
}
|
|
2026
|
+
if (typeof column === 'string') {
|
|
2027
|
+
var normalizedColumn = column.trim().toUpperCase();
|
|
2028
|
+
if (this.BOOLEAN_FUNCTION_KEYS.has(normalizedColumn)) {
|
|
2029
|
+
if (!Array.isArray(value)) {
|
|
2030
|
+
throw new Error("".concat(column, " expects an array of arguments."));
|
|
2031
|
+
}
|
|
2032
|
+
return this.buildFunctionCall(column, value, params);
|
|
2033
|
+
}
|
|
2034
|
+
}
|
|
2035
|
+
if (typeof Buffer !== 'undefined' && Buffer.isBuffer && Buffer.isBuffer(value)) {
|
|
2036
|
+
return this.buildOperatorExpression(C6C.EQUAL, [column, value], params, column);
|
|
2037
|
+
}
|
|
1885
2038
|
if (Array.isArray(value)) {
|
|
1886
2039
|
if (value.length >= 2 && typeof value[0] === 'string') {
|
|
1887
2040
|
var op = value[0], rest = value.slice(1);
|
|
@@ -2054,6 +2207,143 @@ var JoinBuilder = /** @class */ (function (_super) {
|
|
|
2054
2207
|
JoinBuilder.prototype.createSelectBuilder = function (_request) {
|
|
2055
2208
|
throw new Error('Subclasses must implement createSelectBuilder to support derived table serialization.');
|
|
2056
2209
|
};
|
|
2210
|
+
JoinBuilder.prototype.resetIndexHints = function () {
|
|
2211
|
+
this.indexHintCache = undefined;
|
|
2212
|
+
};
|
|
2213
|
+
JoinBuilder.prototype.normalizeIndexHintKey = function (key) {
|
|
2214
|
+
return key
|
|
2215
|
+
.replace(/`/g, '')
|
|
2216
|
+
.replace(/_/g, ' ')
|
|
2217
|
+
.trim()
|
|
2218
|
+
.replace(/\s+/g, ' ')
|
|
2219
|
+
.toUpperCase();
|
|
2220
|
+
};
|
|
2221
|
+
JoinBuilder.prototype.normalizeHintTargetKey = function (target) {
|
|
2222
|
+
return target.replace(/`/g, '').trim();
|
|
2223
|
+
};
|
|
2224
|
+
JoinBuilder.prototype.hasIndexHintKeys = function (obj) {
|
|
2225
|
+
var _this = this;
|
|
2226
|
+
var keys = Object.keys(obj !== null && obj !== void 0 ? obj : {});
|
|
2227
|
+
if (!keys.length)
|
|
2228
|
+
return false;
|
|
2229
|
+
var forceKey = this.normalizeIndexHintKey(C6C.FORCE_INDEX);
|
|
2230
|
+
var useKey = this.normalizeIndexHintKey(C6C.USE_INDEX);
|
|
2231
|
+
var ignoreKey = this.normalizeIndexHintKey(C6C.IGNORE_INDEX);
|
|
2232
|
+
return keys.some(function (key) {
|
|
2233
|
+
var normalized = _this.normalizeIndexHintKey(key);
|
|
2234
|
+
return normalized === forceKey || normalized === useKey || normalized === ignoreKey;
|
|
2235
|
+
});
|
|
2236
|
+
};
|
|
2237
|
+
JoinBuilder.prototype.normalizeHintSpec = function (spec) {
|
|
2238
|
+
var _a;
|
|
2239
|
+
if (spec instanceof Map) {
|
|
2240
|
+
spec = Object.fromEntries(spec);
|
|
2241
|
+
}
|
|
2242
|
+
if (Array.isArray(spec) || typeof spec === 'string') {
|
|
2243
|
+
return _a = {}, _a[C6C.FORCE_INDEX] = spec, _a;
|
|
2244
|
+
}
|
|
2245
|
+
if (!spec || typeof spec !== 'object') {
|
|
2246
|
+
return undefined;
|
|
2247
|
+
}
|
|
2248
|
+
if (!this.hasIndexHintKeys(spec)) {
|
|
2249
|
+
return undefined;
|
|
2250
|
+
}
|
|
2251
|
+
return spec;
|
|
2252
|
+
};
|
|
2253
|
+
JoinBuilder.prototype.formatIndexHintClause = function (spec) {
|
|
2254
|
+
var normalizedSpec = this.normalizeHintSpec(spec);
|
|
2255
|
+
if (!normalizedSpec)
|
|
2256
|
+
return '';
|
|
2257
|
+
var clauses = [];
|
|
2258
|
+
var forceKey = this.normalizeIndexHintKey(C6C.FORCE_INDEX);
|
|
2259
|
+
var useKey = this.normalizeIndexHintKey(C6C.USE_INDEX);
|
|
2260
|
+
var ignoreKey = this.normalizeIndexHintKey(C6C.IGNORE_INDEX);
|
|
2261
|
+
var pushClause = function (keyword, rawValue) {
|
|
2262
|
+
var values = Array.isArray(rawValue) ? rawValue : [rawValue];
|
|
2263
|
+
var indexes = values
|
|
2264
|
+
.map(function (value) { return String(value !== null && value !== void 0 ? value : '').trim(); })
|
|
2265
|
+
.filter(Boolean)
|
|
2266
|
+
.map(function (value) { return "`".concat(value.replace(/`/g, '``'), "`"); });
|
|
2267
|
+
if (!indexes.length)
|
|
2268
|
+
return;
|
|
2269
|
+
clauses.push("".concat(keyword, " (").concat(indexes.join(', '), ")"));
|
|
2270
|
+
};
|
|
2271
|
+
for (var _i = 0, _a = Object.entries(normalizedSpec); _i < _a.length; _i++) {
|
|
2272
|
+
var _b = _a[_i], key = _b[0], rawValue = _b[1];
|
|
2273
|
+
var normalizedKey = this.normalizeIndexHintKey(key);
|
|
2274
|
+
if (normalizedKey === forceKey) {
|
|
2275
|
+
pushClause('FORCE INDEX', rawValue);
|
|
2276
|
+
}
|
|
2277
|
+
else if (normalizedKey === useKey) {
|
|
2278
|
+
pushClause('USE INDEX', rawValue);
|
|
2279
|
+
}
|
|
2280
|
+
else if (normalizedKey === ignoreKey) {
|
|
2281
|
+
pushClause('IGNORE INDEX', rawValue);
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
return clauses.join(' ');
|
|
2285
|
+
};
|
|
2286
|
+
JoinBuilder.prototype.normalizeIndexHints = function (raw) {
|
|
2287
|
+
var _this = this;
|
|
2288
|
+
if (raw instanceof Map) {
|
|
2289
|
+
raw = Object.fromEntries(raw);
|
|
2290
|
+
}
|
|
2291
|
+
var cache = new Map();
|
|
2292
|
+
var addEntry = function (target, spec) {
|
|
2293
|
+
var clause = _this.formatIndexHintClause(spec);
|
|
2294
|
+
if (!clause)
|
|
2295
|
+
return;
|
|
2296
|
+
var normalizedTarget = target === '__base__'
|
|
2297
|
+
? '__base__'
|
|
2298
|
+
: _this.normalizeHintTargetKey(target);
|
|
2299
|
+
cache.set(normalizedTarget, clause);
|
|
2300
|
+
};
|
|
2301
|
+
if (Array.isArray(raw) || typeof raw === 'string') {
|
|
2302
|
+
addEntry('__base__', raw);
|
|
2303
|
+
}
|
|
2304
|
+
else if (raw && typeof raw === 'object') {
|
|
2305
|
+
if (this.hasIndexHintKeys(raw)) {
|
|
2306
|
+
addEntry('__base__', raw);
|
|
2307
|
+
}
|
|
2308
|
+
else {
|
|
2309
|
+
for (var _i = 0, _a = Object.entries(raw); _i < _a.length; _i++) {
|
|
2310
|
+
var _b = _a[_i], key = _b[0], value = _b[1];
|
|
2311
|
+
var normalizedKey = this.normalizeHintTargetKey(key);
|
|
2312
|
+
if (!normalizedKey)
|
|
2313
|
+
continue;
|
|
2314
|
+
addEntry(normalizedKey, value);
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
}
|
|
2318
|
+
return cache.size ? cache : undefined;
|
|
2319
|
+
};
|
|
2320
|
+
JoinBuilder.prototype.getIndexHintClause = function (table, alias) {
|
|
2321
|
+
var _a;
|
|
2322
|
+
if (!this.indexHintCache) {
|
|
2323
|
+
var rawHints = (_a = this.request) === null || _a === void 0 ? void 0 : _a[C6C.INDEX_HINTS];
|
|
2324
|
+
this.indexHintCache = this.normalizeIndexHints(rawHints);
|
|
2325
|
+
}
|
|
2326
|
+
var hints = this.indexHintCache;
|
|
2327
|
+
if (!hints || hints.size === 0)
|
|
2328
|
+
return '';
|
|
2329
|
+
var normalizedTable = this.normalizeHintTargetKey(table);
|
|
2330
|
+
var normalizedAlias = alias ? this.normalizeHintTargetKey(alias) : undefined;
|
|
2331
|
+
var candidates = [
|
|
2332
|
+
normalizedAlias,
|
|
2333
|
+
normalizedAlias ? "".concat(normalizedTable, " ").concat(normalizedAlias) : undefined,
|
|
2334
|
+
normalizedTable,
|
|
2335
|
+
'__base__',
|
|
2336
|
+
];
|
|
2337
|
+
for (var _i = 0, candidates_1 = candidates; _i < candidates_1.length; _i++) {
|
|
2338
|
+
var candidate = candidates_1[_i];
|
|
2339
|
+
if (!candidate)
|
|
2340
|
+
continue;
|
|
2341
|
+
var clause = hints.get(candidate);
|
|
2342
|
+
if (clause)
|
|
2343
|
+
return clause;
|
|
2344
|
+
}
|
|
2345
|
+
return '';
|
|
2346
|
+
};
|
|
2057
2347
|
JoinBuilder.prototype.buildJoinClauses = function (joinArgs, params) {
|
|
2058
2348
|
var sql = '';
|
|
2059
2349
|
var joinTypeEntries = joinArgs instanceof Map
|
|
@@ -2117,7 +2407,9 @@ var JoinBuilder = /** @class */ (function (_super) {
|
|
|
2117
2407
|
if (alias) {
|
|
2118
2408
|
this_1.registerAlias(alias, table);
|
|
2119
2409
|
}
|
|
2120
|
-
var
|
|
2410
|
+
var hintClause = this_1.getIndexHintClause(table, alias);
|
|
2411
|
+
var baseJoinSql = alias ? "`".concat(table, "` AS `").concat(alias, "`") : "`".concat(table, "`");
|
|
2412
|
+
var joinSql = hintClause ? "".concat(baseJoinSql, " ").concat(hintClause) : baseJoinSql;
|
|
2121
2413
|
var onClause = this_1.buildBooleanJoinedConditions(conditions, true, params);
|
|
2122
2414
|
sql += " ".concat(joinKind, " JOIN ").concat(joinSql);
|
|
2123
2415
|
if (onClause) {
|
|
@@ -2271,6 +2563,7 @@ var SelectQueryBuilder = /** @class */ (function (_super) {
|
|
|
2271
2563
|
// @ts-ignore
|
|
2272
2564
|
if (this.selectAliases && this.selectAliases.clear)
|
|
2273
2565
|
this.selectAliases.clear();
|
|
2566
|
+
this.resetIndexHints();
|
|
2274
2567
|
var args = this.request;
|
|
2275
2568
|
this.initAlias(table, args.JOIN);
|
|
2276
2569
|
var params = this.useNamedParams ? {} : [];
|
|
@@ -2279,6 +2572,10 @@ var SelectQueryBuilder = /** @class */ (function (_super) {
|
|
|
2279
2572
|
.map(function (f) { return _this.buildAggregateField(f, params); })
|
|
2280
2573
|
.join(', ');
|
|
2281
2574
|
var sql = "SELECT ".concat(selectFields, " FROM `").concat(table, "`");
|
|
2575
|
+
var baseIndexHint = this.getIndexHintClause(table);
|
|
2576
|
+
if (baseIndexHint) {
|
|
2577
|
+
sql += " ".concat(baseIndexHint);
|
|
2578
|
+
}
|
|
2282
2579
|
if (args.JOIN) {
|
|
2283
2580
|
sql += this.buildJoinClauses(args.JOIN, params);
|
|
2284
2581
|
}
|