@query-doctor/core 0.2.4 → 0.2.5

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.js CHANGED
@@ -866,7 +866,9 @@ var _PgIdentifier = class _PgIdentifier {
866
866
  const identifierRegex = /^[a-z_][a-zA-Z0-9_]*$/;
867
867
  const match = identifier.match(/^"(.+)"$/);
868
868
  if (match) {
869
- return new _PgIdentifier(match[1], true);
869
+ const value = match[1];
870
+ const quoted2 = !identifierRegex.test(value) || this.reservedKeywords.has(value.toLowerCase());
871
+ return new _PgIdentifier(value, quoted2);
870
872
  }
871
873
  const quoted = !identifierRegex.test(identifier) || this.reservedKeywords.has(identifier.toLowerCase());
872
874
  return new _PgIdentifier(identifier, quoted);
@@ -1071,6 +1073,24 @@ var PgIdentifier = _PgIdentifier;
1071
1073
 
1072
1074
  // src/optimizer/genalgo.ts
1073
1075
  import { blue as blue2, gray, green, magenta, red, yellow } from "colorette";
1076
+
1077
+ // src/sql/permutations.ts
1078
+ function permutationsWithDescendingLength(arr) {
1079
+ const collected = [];
1080
+ function collect(path, rest) {
1081
+ for (let i = 0; i < rest.length; i++) {
1082
+ const nextRest = [...rest.slice(0, i), ...rest.slice(i + 1)];
1083
+ const nextPath = [...path, rest[i]];
1084
+ collected.push(nextPath);
1085
+ collect(nextPath, nextRest);
1086
+ }
1087
+ }
1088
+ collect([], arr);
1089
+ collected.sort((a, b) => b.length - a.length);
1090
+ return collected;
1091
+ }
1092
+
1093
+ // src/optimizer/genalgo.ts
1074
1094
  var _IndexOptimizer = class _IndexOptimizer {
1075
1095
  constructor(db, statistics, existingIndexes, config = {}) {
1076
1096
  this.db = db;
@@ -1203,14 +1223,12 @@ var _IndexOptimizer = class _IndexOptimizer {
1203
1223
  * Derive the list of indexes [tableA(X, Y, Z), tableB(H, I, J)]
1204
1224
  **/
1205
1225
  indexesToCreate(rootCandidates) {
1206
- const permutedIndexes = this.tableColumnIndexCandidates(rootCandidates);
1226
+ const permutedIndexes = this.groupPotentialIndexColumnsByTable(rootCandidates);
1207
1227
  const nextStage = [];
1208
1228
  for (const permutation of permutedIndexes.values()) {
1209
1229
  const { table: rawTable, schema: rawSchema, columns } = permutation;
1210
- const permutations = permuteWithFeedback(columns);
1211
- let iter = permutations.next(PROCEED);
1212
- while (!iter.done) {
1213
- const columns2 = iter.value;
1230
+ const permutations = permutationsWithDescendingLength(columns);
1231
+ for (const columns2 of permutations) {
1214
1232
  const schema = PgIdentifier.fromString(rawSchema);
1215
1233
  const table = PgIdentifier.fromString(rawTable);
1216
1234
  const existingIndex = this.indexAlreadyExists(
@@ -1218,12 +1236,10 @@ var _IndexOptimizer = class _IndexOptimizer {
1218
1236
  columns2
1219
1237
  );
1220
1238
  if (existingIndex) {
1221
- iter = permutations.next(PROCEED);
1222
1239
  continue;
1223
1240
  }
1224
1241
  const indexName = this.indexName();
1225
1242
  const definition = this.toDefinition({ table, schema, columns: columns2 }).raw;
1226
- iter = permutations.next(PROCEED);
1227
1243
  nextStage.push({
1228
1244
  name: indexName,
1229
1245
  schema: schema.toString(),
@@ -1355,7 +1371,7 @@ var _IndexOptimizer = class _IndexOptimizer {
1355
1371
  }
1356
1372
  throw new Error("Unreachable");
1357
1373
  }
1358
- tableColumnIndexCandidates(indexes) {
1374
+ groupPotentialIndexColumnsByTable(indexes) {
1359
1375
  const tableColumns = /* @__PURE__ */ new Map();
1360
1376
  for (const index of indexes) {
1361
1377
  const existing = tableColumns.get(`${index.schema}.${index.table}`);
@@ -1425,21 +1441,6 @@ var RollbackError = class {
1425
1441
  };
1426
1442
  var PROCEED = Symbol("PROCEED");
1427
1443
  var SKIP = Symbol("SKIP");
1428
- function* permuteWithFeedback(arr) {
1429
- function* helper(path, rest) {
1430
- let i = 0;
1431
- while (i < rest.length) {
1432
- const nextPath = [...path, rest[i]];
1433
- const nextRest = [...rest.slice(0, i), ...rest.slice(i + 1)];
1434
- const input = yield nextPath;
1435
- if (input === PROCEED) {
1436
- yield* helper(nextPath, nextRest);
1437
- }
1438
- i++;
1439
- }
1440
- }
1441
- yield* helper([], arr);
1442
- }
1443
1444
 
1444
1445
  // src/optimizer/statistics.ts
1445
1446
  import { gray as gray2 } from "colorette";
@@ -2155,7 +2156,6 @@ export {
2155
2156
  ignoredIdentifier,
2156
2157
  isIndexProbablyDroppable,
2157
2158
  isIndexSupported,
2158
- parseNudges,
2159
- permuteWithFeedback
2159
+ parseNudges
2160
2160
  };
2161
2161
  //# sourceMappingURL=index.js.map