@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/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 _this = _super !== null && _super.apply(this, arguments) || this;
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);
@@ -2051,6 +2204,143 @@ var JoinBuilder = /** @class */ (function (_super) {
2051
2204
  JoinBuilder.prototype.createSelectBuilder = function (_request) {
2052
2205
  throw new Error('Subclasses must implement createSelectBuilder to support derived table serialization.');
2053
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
+ };
2054
2344
  JoinBuilder.prototype.buildJoinClauses = function (joinArgs, params) {
2055
2345
  var sql = '';
2056
2346
  var joinTypeEntries = joinArgs instanceof Map
@@ -2114,7 +2404,9 @@ var JoinBuilder = /** @class */ (function (_super) {
2114
2404
  if (alias) {
2115
2405
  this_1.registerAlias(alias, table);
2116
2406
  }
2117
- var joinSql = alias ? "`".concat(table, "` AS `").concat(alias, "`") : "`".concat(table, "`");
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;
2118
2410
  var onClause = this_1.buildBooleanJoinedConditions(conditions, true, params);
2119
2411
  sql += " ".concat(joinKind, " JOIN ").concat(joinSql);
2120
2412
  if (onClause) {
@@ -2268,6 +2560,7 @@ var SelectQueryBuilder = /** @class */ (function (_super) {
2268
2560
  // @ts-ignore
2269
2561
  if (this.selectAliases && this.selectAliases.clear)
2270
2562
  this.selectAliases.clear();
2563
+ this.resetIndexHints();
2271
2564
  var args = this.request;
2272
2565
  this.initAlias(table, args.JOIN);
2273
2566
  var params = this.useNamedParams ? {} : [];
@@ -2276,6 +2569,10 @@ var SelectQueryBuilder = /** @class */ (function (_super) {
2276
2569
  .map(function (f) { return _this.buildAggregateField(f, params); })
2277
2570
  .join(', ');
2278
2571
  var sql = "SELECT ".concat(selectFields, " FROM `").concat(table, "`");
2572
+ var baseIndexHint = this.getIndexHintClause(table);
2573
+ if (baseIndexHint) {
2574
+ sql += " ".concat(baseIndexHint);
2575
+ }
2279
2576
  if (args.JOIN) {
2280
2577
  sql += this.buildJoinClauses(args.JOIN, params);
2281
2578
  }