@carbonorm/carbonnode 3.9.6 → 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 +309 -3
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +309 -3
- 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/__tests__/sqlBuilders.expressions.test.ts +30 -1
- package/src/api/C6Constants.ts +12 -2
- package/src/api/orm/builders/ConditionBuilder.ts +184 -1
- package/src/api/orm/builders/JoinBuilder.ts +150 -1
- package/src/api/orm/queries/SelectQueryBuilder.ts +5 -0
package/dist/index.esm.js
CHANGED
|
@@ -35,10 +35,12 @@ var C6Constants = {
|
|
|
35
35
|
DATE_FORMAT: 'DATE_FORMAT',
|
|
36
36
|
DESC: 'DESC',
|
|
37
37
|
DISTINCT: 'DISTINCT',
|
|
38
|
+
EXISTS: 'EXISTS',
|
|
38
39
|
EXTRACT: 'EXTRACT',
|
|
39
40
|
EQUAL: '=',
|
|
40
41
|
EQUAL_NULL_SAFE: '<=>',
|
|
41
42
|
FALSE: 'FALSE',
|
|
43
|
+
FORCE: 'FORCE',
|
|
42
44
|
FULL_OUTER: 'FULL_OUTER',
|
|
43
45
|
FROM_DAYS: 'FROM_DAYS',
|
|
44
46
|
FROM_UNIXTIME: 'FROM_UNIXTIME',
|
|
@@ -54,6 +56,7 @@ var C6Constants = {
|
|
|
54
56
|
HOUR_SECOND: 'HOUR_SECOND',
|
|
55
57
|
HOUR_MINUTE: 'HOUR_MINUTE',
|
|
56
58
|
IN: 'IN',
|
|
59
|
+
INDEX: 'INDEX',
|
|
57
60
|
IS: 'IS',
|
|
58
61
|
IS_NOT: 'IS_NOT',
|
|
59
62
|
INNER: 'INNER',
|
|
@@ -71,6 +74,7 @@ var C6Constants = {
|
|
|
71
74
|
MAKEDATE: 'MAKEDATE',
|
|
72
75
|
MAKETIME: 'MAKETIME',
|
|
73
76
|
MATCH_AGAINST: 'MATCH_AGAINST',
|
|
77
|
+
MBRCONTAINS: 'MBRContains',
|
|
74
78
|
MONTHNAME: 'MONTHNAME',
|
|
75
79
|
MICROSECOND: 'MICROSECOND',
|
|
76
80
|
MINUTE: 'MINUTE',
|
|
@@ -86,8 +90,14 @@ var C6Constants = {
|
|
|
86
90
|
NULL: 'NULL',
|
|
87
91
|
ORDER: 'ORDER',
|
|
88
92
|
OR: 'OR',
|
|
93
|
+
INDEX_HINTS: 'INDEX_HINTS',
|
|
94
|
+
FORCE_INDEX: 'FORCE INDEX',
|
|
95
|
+
USE_INDEX: 'USE INDEX',
|
|
96
|
+
IGNORE_INDEX: 'IGNORE INDEX',
|
|
89
97
|
PAGE: 'PAGE',
|
|
90
98
|
PAGINATION: 'PAGINATION',
|
|
99
|
+
POLYGON: 'POLYGON',
|
|
100
|
+
POINT: 'POINT',
|
|
91
101
|
RIGHT_OUTER: 'RIGHT_OUTER',
|
|
92
102
|
SECOND: 'SECOND',
|
|
93
103
|
SECOND_MICROSECOND: 'SECOND_MICROSECOND',
|
|
@@ -1448,7 +1458,8 @@ var stContains = function (envelope, shape) {
|
|
|
1448
1458
|
var ConditionBuilder = /** @class */ (function (_super) {
|
|
1449
1459
|
__extends(ConditionBuilder, _super);
|
|
1450
1460
|
function ConditionBuilder() {
|
|
1451
|
-
var
|
|
1461
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
1462
|
+
var _this = _super.apply(this, arguments) || this;
|
|
1452
1463
|
_this.aliasMap = {};
|
|
1453
1464
|
_this.derivedAliases = new Set();
|
|
1454
1465
|
_this.BOOLEAN_OPERATORS = new Map([
|
|
@@ -1487,8 +1498,16 @@ var ConditionBuilder = /** @class */ (function (_super) {
|
|
|
1487
1498
|
[C6C.BETWEEN, C6C.BETWEEN],
|
|
1488
1499
|
['BETWEEN', C6C.BETWEEN],
|
|
1489
1500
|
['NOT BETWEEN', 'NOT BETWEEN'],
|
|
1501
|
+
[C6C.EXISTS, C6C.EXISTS],
|
|
1502
|
+
['EXISTS', C6C.EXISTS],
|
|
1503
|
+
['NOT EXISTS', 'NOT EXISTS'],
|
|
1490
1504
|
[C6C.MATCH_AGAINST, C6C.MATCH_AGAINST],
|
|
1491
1505
|
]);
|
|
1506
|
+
_this.BOOLEAN_FUNCTION_KEYS = new Set([
|
|
1507
|
+
(_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',
|
|
1508
|
+
(_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',
|
|
1509
|
+
(_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',
|
|
1510
|
+
]);
|
|
1492
1511
|
return _this;
|
|
1493
1512
|
}
|
|
1494
1513
|
ConditionBuilder.prototype.initAlias = function (baseTable, joins) {
|
|
@@ -1723,6 +1742,9 @@ var ConditionBuilder = /** @class */ (function (_super) {
|
|
|
1723
1742
|
if (operand === null || typeof operand === 'number' || typeof operand === 'boolean') {
|
|
1724
1743
|
return { sql: asParam(operand), isReference: false, isExpression: false, isSubSelect: false };
|
|
1725
1744
|
}
|
|
1745
|
+
if (typeof Buffer !== 'undefined' && Buffer.isBuffer && Buffer.isBuffer(operand)) {
|
|
1746
|
+
return { sql: asParam(operand), isReference: false, isExpression: false, isSubSelect: false };
|
|
1747
|
+
}
|
|
1726
1748
|
if (typeof operand === 'string') {
|
|
1727
1749
|
if (this.isTableReference(operand) || this.isColumnRef(operand)) {
|
|
1728
1750
|
return { sql: operand, isReference: true, isExpression: false, isSubSelect: false };
|
|
@@ -1766,10 +1788,129 @@ var ConditionBuilder = /** @class */ (function (_super) {
|
|
|
1766
1788
|
}
|
|
1767
1789
|
throw new Error('Unsupported operand type in SQL expression.');
|
|
1768
1790
|
};
|
|
1791
|
+
ConditionBuilder.prototype.ensurePlainObject = function (value) {
|
|
1792
|
+
if (value instanceof Map) {
|
|
1793
|
+
return Object.fromEntries(value);
|
|
1794
|
+
}
|
|
1795
|
+
return value;
|
|
1796
|
+
};
|
|
1797
|
+
ConditionBuilder.prototype.resolveExistsInnerColumn = function (subRequest, provided) {
|
|
1798
|
+
var _a, _b;
|
|
1799
|
+
if (provided) {
|
|
1800
|
+
if (typeof provided !== 'string' || provided.trim() === '') {
|
|
1801
|
+
throw new Error('EXISTS correlation column must be a non-empty string.');
|
|
1802
|
+
}
|
|
1803
|
+
return provided;
|
|
1804
|
+
}
|
|
1805
|
+
var selectClause = this.ensurePlainObject(subRequest === null || subRequest === void 0 ? void 0 : subRequest[C6C.SELECT]);
|
|
1806
|
+
if (Array.isArray(selectClause) && selectClause.length > 0) {
|
|
1807
|
+
var candidate = selectClause[0];
|
|
1808
|
+
if (typeof candidate === 'string' && candidate.trim() !== '') {
|
|
1809
|
+
return candidate;
|
|
1810
|
+
}
|
|
1811
|
+
}
|
|
1812
|
+
var fromTable = subRequest === null || subRequest === void 0 ? void 0 : subRequest[C6C.FROM];
|
|
1813
|
+
if (typeof fromTable === 'string' && fromTable.trim() !== '') {
|
|
1814
|
+
var table = (_b = (_a = this.config.C6) === null || _a === void 0 ? void 0 : _a.TABLES) === null || _b === void 0 ? void 0 : _b[fromTable.trim()];
|
|
1815
|
+
var primary = table === null || table === void 0 ? void 0 : table.PRIMARY;
|
|
1816
|
+
if (Array.isArray(primary) && primary.length > 0) {
|
|
1817
|
+
return String(primary[0]);
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
throw new Error('EXISTS requires a correlation column to be provided or inferable from the subselect.');
|
|
1821
|
+
};
|
|
1822
|
+
ConditionBuilder.prototype.normalizeExistsSpec = function (spec) {
|
|
1823
|
+
var normalized = this.ensurePlainObject(spec);
|
|
1824
|
+
if (!Array.isArray(normalized) || normalized.length < 2) {
|
|
1825
|
+
throw new Error('EXISTS expects an array like [outerColumn, subselect, innerColumn?].');
|
|
1826
|
+
}
|
|
1827
|
+
var outerRaw = normalized[0], payloadRaw = normalized[1], innerRaw = normalized[2];
|
|
1828
|
+
if (typeof outerRaw !== 'string' || outerRaw.trim() === '') {
|
|
1829
|
+
throw new Error('EXISTS requires the first element to be an outer column reference string.');
|
|
1830
|
+
}
|
|
1831
|
+
var payload = this.ensurePlainObject(payloadRaw);
|
|
1832
|
+
var subSelect;
|
|
1833
|
+
if (payload && typeof payload === 'object' && C6C.SUBSELECT in payload) {
|
|
1834
|
+
subSelect = this.ensurePlainObject(payload[C6C.SUBSELECT]);
|
|
1835
|
+
}
|
|
1836
|
+
else if (payload && typeof payload === 'object') {
|
|
1837
|
+
subSelect = payload;
|
|
1838
|
+
}
|
|
1839
|
+
else {
|
|
1840
|
+
throw new Error('EXISTS requires a subselect payload as the second element.');
|
|
1841
|
+
}
|
|
1842
|
+
if (!subSelect || typeof subSelect !== 'object') {
|
|
1843
|
+
throw new Error('EXISTS subselect payload must be an object.');
|
|
1844
|
+
}
|
|
1845
|
+
var innerColumn = typeof innerRaw === 'string' ? innerRaw : undefined;
|
|
1846
|
+
return {
|
|
1847
|
+
outerColumn: outerRaw,
|
|
1848
|
+
subRequest: __assign({}, subSelect),
|
|
1849
|
+
innerColumn: innerColumn,
|
|
1850
|
+
};
|
|
1851
|
+
};
|
|
1852
|
+
ConditionBuilder.prototype.buildExistsExpression = function (spec, operator, params) {
|
|
1853
|
+
var _a, _b, _c, _d;
|
|
1854
|
+
var _this = this;
|
|
1855
|
+
var _e;
|
|
1856
|
+
var _f = this.normalizeExistsSpec(spec), outerColumn = _f.outerColumn, subRequest = _f.subRequest, innerColumn = _f.innerColumn;
|
|
1857
|
+
var fromTableRaw = subRequest[C6C.FROM];
|
|
1858
|
+
if (typeof fromTableRaw !== 'string' || fromTableRaw.trim() === '') {
|
|
1859
|
+
throw new Error('EXISTS subselect requires a table specified with C6C.FROM.');
|
|
1860
|
+
}
|
|
1861
|
+
var fromTable = fromTableRaw.trim();
|
|
1862
|
+
this.assertValidIdentifier(outerColumn, 'EXISTS correlation column');
|
|
1863
|
+
var correlationColumn = this.resolveExistsInnerColumn(subRequest, innerColumn);
|
|
1864
|
+
if (!this.isColumnRef(correlationColumn) && !this.isTableReference(correlationColumn)) {
|
|
1865
|
+
throw new Error("Unknown column reference '".concat(correlationColumn, "' used in EXISTS subquery correlation column."));
|
|
1866
|
+
}
|
|
1867
|
+
var existingWhereRaw = this.ensurePlainObject(subRequest[C6C.WHERE]);
|
|
1868
|
+
var correlationCondition = (_a = {}, _a[correlationColumn] = [C6C.EQUAL, outerColumn], _a);
|
|
1869
|
+
var normalizedExistingWhere = existingWhereRaw && typeof existingWhereRaw === 'object'
|
|
1870
|
+
? Array.isArray(existingWhereRaw)
|
|
1871
|
+
? existingWhereRaw.slice()
|
|
1872
|
+
: __assign({}, existingWhereRaw)
|
|
1873
|
+
: existingWhereRaw;
|
|
1874
|
+
var hasExistingWhere = Array.isArray(normalizedExistingWhere)
|
|
1875
|
+
? normalizedExistingWhere.length > 0
|
|
1876
|
+
: normalizedExistingWhere && typeof normalizedExistingWhere === 'object'
|
|
1877
|
+
? Object.keys(normalizedExistingWhere).length > 0
|
|
1878
|
+
: normalizedExistingWhere != null;
|
|
1879
|
+
var whereClause;
|
|
1880
|
+
if (!hasExistingWhere) {
|
|
1881
|
+
whereClause = correlationCondition;
|
|
1882
|
+
}
|
|
1883
|
+
else if (normalizedExistingWhere && typeof normalizedExistingWhere === 'object' &&
|
|
1884
|
+
Object.keys(normalizedExistingWhere).some(function (key) { return _this.BOOLEAN_OPERATORS.has(key); })) {
|
|
1885
|
+
whereClause = (_b = {}, _b[C6C.AND] = [normalizedExistingWhere, correlationCondition], _b);
|
|
1886
|
+
}
|
|
1887
|
+
else if (normalizedExistingWhere && typeof normalizedExistingWhere === 'object') {
|
|
1888
|
+
whereClause = __assign(__assign({}, normalizedExistingWhere), correlationCondition);
|
|
1889
|
+
}
|
|
1890
|
+
else {
|
|
1891
|
+
whereClause = (_c = {}, _c[C6C.AND] = [normalizedExistingWhere, correlationCondition], _c);
|
|
1892
|
+
}
|
|
1893
|
+
var subRequestWithCorrelation = __assign(__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));
|
|
1894
|
+
var buildScalarSubSelect = this.buildScalarSubSelect;
|
|
1895
|
+
if (typeof buildScalarSubSelect !== 'function') {
|
|
1896
|
+
throw new Error('EXISTS operator requires SelectQueryBuilder context.');
|
|
1897
|
+
}
|
|
1898
|
+
var scalar = buildScalarSubSelect.call(this, subRequestWithCorrelation, params);
|
|
1899
|
+
var keyword = operator === 'NOT EXISTS' ? 'NOT EXISTS' : C6C.EXISTS;
|
|
1900
|
+
return "".concat(keyword, " ").concat(scalar);
|
|
1901
|
+
};
|
|
1769
1902
|
ConditionBuilder.prototype.buildOperatorExpression = function (op, rawOperands, params, contextColumn) {
|
|
1770
1903
|
var _a, _b;
|
|
1771
1904
|
var _this = this;
|
|
1772
1905
|
var operator = this.formatOperator(op);
|
|
1906
|
+
if (operator === C6C.EXISTS || operator === 'NOT EXISTS') {
|
|
1907
|
+
var operands_1 = Array.isArray(rawOperands) ? rawOperands : [rawOperands];
|
|
1908
|
+
if (!operands_1.length) {
|
|
1909
|
+
throw new Error("".concat(operator, " requires at least one subselect specification."));
|
|
1910
|
+
}
|
|
1911
|
+
var clauses = operands_1.map(function (spec) { return _this.buildExistsExpression(spec, operator, params); });
|
|
1912
|
+
return this.joinBooleanParts(clauses, 'AND');
|
|
1913
|
+
}
|
|
1773
1914
|
if (operator === C6C.MATCH_AGAINST) {
|
|
1774
1915
|
if (!Array.isArray(rawOperands) || rawOperands.length !== 2) {
|
|
1775
1916
|
throw new Error('MATCH_AGAINST requires an array of two operands.');
|
|
@@ -1879,6 +2020,18 @@ var ConditionBuilder = /** @class */ (function (_super) {
|
|
|
1879
2020
|
if (value instanceof Map) {
|
|
1880
2021
|
value = Object.fromEntries(value);
|
|
1881
2022
|
}
|
|
2023
|
+
if (typeof column === 'string') {
|
|
2024
|
+
var normalizedColumn = column.trim().toUpperCase();
|
|
2025
|
+
if (this.BOOLEAN_FUNCTION_KEYS.has(normalizedColumn)) {
|
|
2026
|
+
if (!Array.isArray(value)) {
|
|
2027
|
+
throw new Error("".concat(column, " expects an array of arguments."));
|
|
2028
|
+
}
|
|
2029
|
+
return this.buildFunctionCall(column, value, params);
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
if (typeof Buffer !== 'undefined' && Buffer.isBuffer && Buffer.isBuffer(value)) {
|
|
2033
|
+
return this.buildOperatorExpression(C6C.EQUAL, [column, value], params, column);
|
|
2034
|
+
}
|
|
1882
2035
|
if (Array.isArray(value)) {
|
|
1883
2036
|
if (value.length >= 2 && typeof value[0] === 'string') {
|
|
1884
2037
|
var op = value[0], rest = value.slice(1);
|
|
@@ -1920,8 +2073,17 @@ var ConditionBuilder = /** @class */ (function (_super) {
|
|
|
1920
2073
|
if (Array.isArray(node)) {
|
|
1921
2074
|
if (node.length === 0)
|
|
1922
2075
|
return '';
|
|
2076
|
+
// Support both [left, operator, right] and [operator, left, right]
|
|
1923
2077
|
if (node.length === 3 && typeof node[0] === 'string' && typeof node[1] === 'string') {
|
|
1924
|
-
|
|
2078
|
+
var opAsSecond = this.isOperator(node[1]);
|
|
2079
|
+
var opAsFirst = this.isOperator(node[0]);
|
|
2080
|
+
if (opAsSecond) {
|
|
2081
|
+
return this.buildOperatorExpression(node[1], [node[0], node[2]], params, node[0]);
|
|
2082
|
+
}
|
|
2083
|
+
if (opAsFirst) {
|
|
2084
|
+
return this.buildOperatorExpression(node[0], [node[1], node[2]], params, node[1]);
|
|
2085
|
+
}
|
|
2086
|
+
// fall-through to treat as grouped expressions
|
|
1925
2087
|
}
|
|
1926
2088
|
var parts_1 = node
|
|
1927
2089
|
.map(function (item) { return _this.buildBooleanExpression(item, params, 'OR'); })
|
|
@@ -2042,6 +2204,143 @@ var JoinBuilder = /** @class */ (function (_super) {
|
|
|
2042
2204
|
JoinBuilder.prototype.createSelectBuilder = function (_request) {
|
|
2043
2205
|
throw new Error('Subclasses must implement createSelectBuilder to support derived table serialization.');
|
|
2044
2206
|
};
|
|
2207
|
+
JoinBuilder.prototype.resetIndexHints = function () {
|
|
2208
|
+
this.indexHintCache = undefined;
|
|
2209
|
+
};
|
|
2210
|
+
JoinBuilder.prototype.normalizeIndexHintKey = function (key) {
|
|
2211
|
+
return key
|
|
2212
|
+
.replace(/`/g, '')
|
|
2213
|
+
.replace(/_/g, ' ')
|
|
2214
|
+
.trim()
|
|
2215
|
+
.replace(/\s+/g, ' ')
|
|
2216
|
+
.toUpperCase();
|
|
2217
|
+
};
|
|
2218
|
+
JoinBuilder.prototype.normalizeHintTargetKey = function (target) {
|
|
2219
|
+
return target.replace(/`/g, '').trim();
|
|
2220
|
+
};
|
|
2221
|
+
JoinBuilder.prototype.hasIndexHintKeys = function (obj) {
|
|
2222
|
+
var _this = this;
|
|
2223
|
+
var keys = Object.keys(obj !== null && obj !== void 0 ? obj : {});
|
|
2224
|
+
if (!keys.length)
|
|
2225
|
+
return false;
|
|
2226
|
+
var forceKey = this.normalizeIndexHintKey(C6C.FORCE_INDEX);
|
|
2227
|
+
var useKey = this.normalizeIndexHintKey(C6C.USE_INDEX);
|
|
2228
|
+
var ignoreKey = this.normalizeIndexHintKey(C6C.IGNORE_INDEX);
|
|
2229
|
+
return keys.some(function (key) {
|
|
2230
|
+
var normalized = _this.normalizeIndexHintKey(key);
|
|
2231
|
+
return normalized === forceKey || normalized === useKey || normalized === ignoreKey;
|
|
2232
|
+
});
|
|
2233
|
+
};
|
|
2234
|
+
JoinBuilder.prototype.normalizeHintSpec = function (spec) {
|
|
2235
|
+
var _a;
|
|
2236
|
+
if (spec instanceof Map) {
|
|
2237
|
+
spec = Object.fromEntries(spec);
|
|
2238
|
+
}
|
|
2239
|
+
if (Array.isArray(spec) || typeof spec === 'string') {
|
|
2240
|
+
return _a = {}, _a[C6C.FORCE_INDEX] = spec, _a;
|
|
2241
|
+
}
|
|
2242
|
+
if (!spec || typeof spec !== 'object') {
|
|
2243
|
+
return undefined;
|
|
2244
|
+
}
|
|
2245
|
+
if (!this.hasIndexHintKeys(spec)) {
|
|
2246
|
+
return undefined;
|
|
2247
|
+
}
|
|
2248
|
+
return spec;
|
|
2249
|
+
};
|
|
2250
|
+
JoinBuilder.prototype.formatIndexHintClause = function (spec) {
|
|
2251
|
+
var normalizedSpec = this.normalizeHintSpec(spec);
|
|
2252
|
+
if (!normalizedSpec)
|
|
2253
|
+
return '';
|
|
2254
|
+
var clauses = [];
|
|
2255
|
+
var forceKey = this.normalizeIndexHintKey(C6C.FORCE_INDEX);
|
|
2256
|
+
var useKey = this.normalizeIndexHintKey(C6C.USE_INDEX);
|
|
2257
|
+
var ignoreKey = this.normalizeIndexHintKey(C6C.IGNORE_INDEX);
|
|
2258
|
+
var pushClause = function (keyword, rawValue) {
|
|
2259
|
+
var values = Array.isArray(rawValue) ? rawValue : [rawValue];
|
|
2260
|
+
var indexes = values
|
|
2261
|
+
.map(function (value) { return String(value !== null && value !== void 0 ? value : '').trim(); })
|
|
2262
|
+
.filter(Boolean)
|
|
2263
|
+
.map(function (value) { return "`".concat(value.replace(/`/g, '``'), "`"); });
|
|
2264
|
+
if (!indexes.length)
|
|
2265
|
+
return;
|
|
2266
|
+
clauses.push("".concat(keyword, " (").concat(indexes.join(', '), ")"));
|
|
2267
|
+
};
|
|
2268
|
+
for (var _i = 0, _a = Object.entries(normalizedSpec); _i < _a.length; _i++) {
|
|
2269
|
+
var _b = _a[_i], key = _b[0], rawValue = _b[1];
|
|
2270
|
+
var normalizedKey = this.normalizeIndexHintKey(key);
|
|
2271
|
+
if (normalizedKey === forceKey) {
|
|
2272
|
+
pushClause('FORCE INDEX', rawValue);
|
|
2273
|
+
}
|
|
2274
|
+
else if (normalizedKey === useKey) {
|
|
2275
|
+
pushClause('USE INDEX', rawValue);
|
|
2276
|
+
}
|
|
2277
|
+
else if (normalizedKey === ignoreKey) {
|
|
2278
|
+
pushClause('IGNORE INDEX', rawValue);
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
2281
|
+
return clauses.join(' ');
|
|
2282
|
+
};
|
|
2283
|
+
JoinBuilder.prototype.normalizeIndexHints = function (raw) {
|
|
2284
|
+
var _this = this;
|
|
2285
|
+
if (raw instanceof Map) {
|
|
2286
|
+
raw = Object.fromEntries(raw);
|
|
2287
|
+
}
|
|
2288
|
+
var cache = new Map();
|
|
2289
|
+
var addEntry = function (target, spec) {
|
|
2290
|
+
var clause = _this.formatIndexHintClause(spec);
|
|
2291
|
+
if (!clause)
|
|
2292
|
+
return;
|
|
2293
|
+
var normalizedTarget = target === '__base__'
|
|
2294
|
+
? '__base__'
|
|
2295
|
+
: _this.normalizeHintTargetKey(target);
|
|
2296
|
+
cache.set(normalizedTarget, clause);
|
|
2297
|
+
};
|
|
2298
|
+
if (Array.isArray(raw) || typeof raw === 'string') {
|
|
2299
|
+
addEntry('__base__', raw);
|
|
2300
|
+
}
|
|
2301
|
+
else if (raw && typeof raw === 'object') {
|
|
2302
|
+
if (this.hasIndexHintKeys(raw)) {
|
|
2303
|
+
addEntry('__base__', raw);
|
|
2304
|
+
}
|
|
2305
|
+
else {
|
|
2306
|
+
for (var _i = 0, _a = Object.entries(raw); _i < _a.length; _i++) {
|
|
2307
|
+
var _b = _a[_i], key = _b[0], value = _b[1];
|
|
2308
|
+
var normalizedKey = this.normalizeHintTargetKey(key);
|
|
2309
|
+
if (!normalizedKey)
|
|
2310
|
+
continue;
|
|
2311
|
+
addEntry(normalizedKey, value);
|
|
2312
|
+
}
|
|
2313
|
+
}
|
|
2314
|
+
}
|
|
2315
|
+
return cache.size ? cache : undefined;
|
|
2316
|
+
};
|
|
2317
|
+
JoinBuilder.prototype.getIndexHintClause = function (table, alias) {
|
|
2318
|
+
var _a;
|
|
2319
|
+
if (!this.indexHintCache) {
|
|
2320
|
+
var rawHints = (_a = this.request) === null || _a === void 0 ? void 0 : _a[C6C.INDEX_HINTS];
|
|
2321
|
+
this.indexHintCache = this.normalizeIndexHints(rawHints);
|
|
2322
|
+
}
|
|
2323
|
+
var hints = this.indexHintCache;
|
|
2324
|
+
if (!hints || hints.size === 0)
|
|
2325
|
+
return '';
|
|
2326
|
+
var normalizedTable = this.normalizeHintTargetKey(table);
|
|
2327
|
+
var normalizedAlias = alias ? this.normalizeHintTargetKey(alias) : undefined;
|
|
2328
|
+
var candidates = [
|
|
2329
|
+
normalizedAlias,
|
|
2330
|
+
normalizedAlias ? "".concat(normalizedTable, " ").concat(normalizedAlias) : undefined,
|
|
2331
|
+
normalizedTable,
|
|
2332
|
+
'__base__',
|
|
2333
|
+
];
|
|
2334
|
+
for (var _i = 0, candidates_1 = candidates; _i < candidates_1.length; _i++) {
|
|
2335
|
+
var candidate = candidates_1[_i];
|
|
2336
|
+
if (!candidate)
|
|
2337
|
+
continue;
|
|
2338
|
+
var clause = hints.get(candidate);
|
|
2339
|
+
if (clause)
|
|
2340
|
+
return clause;
|
|
2341
|
+
}
|
|
2342
|
+
return '';
|
|
2343
|
+
};
|
|
2045
2344
|
JoinBuilder.prototype.buildJoinClauses = function (joinArgs, params) {
|
|
2046
2345
|
var sql = '';
|
|
2047
2346
|
var joinTypeEntries = joinArgs instanceof Map
|
|
@@ -2105,7 +2404,9 @@ var JoinBuilder = /** @class */ (function (_super) {
|
|
|
2105
2404
|
if (alias) {
|
|
2106
2405
|
this_1.registerAlias(alias, table);
|
|
2107
2406
|
}
|
|
2108
|
-
var
|
|
2407
|
+
var hintClause = this_1.getIndexHintClause(table, alias);
|
|
2408
|
+
var baseJoinSql = alias ? "`".concat(table, "` AS `").concat(alias, "`") : "`".concat(table, "`");
|
|
2409
|
+
var joinSql = hintClause ? "".concat(baseJoinSql, " ").concat(hintClause) : baseJoinSql;
|
|
2109
2410
|
var onClause = this_1.buildBooleanJoinedConditions(conditions, true, params);
|
|
2110
2411
|
sql += " ".concat(joinKind, " JOIN ").concat(joinSql);
|
|
2111
2412
|
if (onClause) {
|
|
@@ -2259,6 +2560,7 @@ var SelectQueryBuilder = /** @class */ (function (_super) {
|
|
|
2259
2560
|
// @ts-ignore
|
|
2260
2561
|
if (this.selectAliases && this.selectAliases.clear)
|
|
2261
2562
|
this.selectAliases.clear();
|
|
2563
|
+
this.resetIndexHints();
|
|
2262
2564
|
var args = this.request;
|
|
2263
2565
|
this.initAlias(table, args.JOIN);
|
|
2264
2566
|
var params = this.useNamedParams ? {} : [];
|
|
@@ -2267,6 +2569,10 @@ var SelectQueryBuilder = /** @class */ (function (_super) {
|
|
|
2267
2569
|
.map(function (f) { return _this.buildAggregateField(f, params); })
|
|
2268
2570
|
.join(', ');
|
|
2269
2571
|
var sql = "SELECT ".concat(selectFields, " FROM `").concat(table, "`");
|
|
2572
|
+
var baseIndexHint = this.getIndexHintClause(table);
|
|
2573
|
+
if (baseIndexHint) {
|
|
2574
|
+
sql += " ".concat(baseIndexHint);
|
|
2575
|
+
}
|
|
2270
2576
|
if (args.JOIN) {
|
|
2271
2577
|
sql += this.buildJoinClauses(args.JOIN, params);
|
|
2272
2578
|
}
|