@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.
@@ -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 _this = _super !== null && _super.apply(this, arguments) || this;
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 joinSql = alias ? "`".concat(table, "` AS `").concat(alias, "`") : "`".concat(table, "`");
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
  }