@query-doctor/core 0.2.0 → 0.2.2

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.cjs CHANGED
@@ -929,7 +929,13 @@ var _PgIdentifier = class _PgIdentifier {
929
929
  */
930
930
  static fromParts(...identifiers) {
931
931
  return new _PgIdentifier(
932
- identifiers.map((identifier) => _PgIdentifier.fromString(identifier)).join("."),
932
+ identifiers.map((identifier) => {
933
+ if (typeof identifier === "string") {
934
+ return _PgIdentifier.fromString(identifier);
935
+ } else {
936
+ return identifier;
937
+ }
938
+ }).join("."),
933
939
  false
934
940
  );
935
941
  }
@@ -1142,7 +1148,7 @@ var _IndexOptimizer = class _IndexOptimizer {
1142
1148
  }
1143
1149
  for (const permutation of toCreate) {
1144
1150
  const createIndex = PostgresQueryBuilder.createIndex(
1145
- this.toDefinition(permutation).raw,
1151
+ permutation.definition,
1146
1152
  permutation.name
1147
1153
  ).introspect().build();
1148
1154
  await tx.exec(createIndex);
@@ -1166,13 +1172,17 @@ var _IndexOptimizer = class _IndexOptimizer {
1166
1172
  }
1167
1173
  const baseIndexes = this.findUsedIndexes(baseExplain.Plan);
1168
1174
  const finalIndexes = this.findUsedIndexes(finalExplain.Plan);
1175
+ const triedIndexes = new Map(
1176
+ toCreate.map((index) => [index.name.toString(), index])
1177
+ );
1178
+ this.replaceUsedIndexesWithDefinition(finalExplain.Plan, triedIndexes);
1169
1179
  return {
1170
1180
  kind: "ok",
1171
1181
  baseCost,
1172
1182
  finalCost,
1173
1183
  newIndexes: finalIndexes.newIndexes,
1174
1184
  existingIndexes: baseIndexes.existingIndexes,
1175
- triedIndexes: new Map(toCreate.map((index) => [index.name, index])),
1185
+ triedIndexes,
1176
1186
  baseExplainPlan: baseExplain.Plan,
1177
1187
  explainPlan: finalExplain.Plan
1178
1188
  };
@@ -1206,7 +1216,8 @@ var _IndexOptimizer = class _IndexOptimizer {
1206
1216
  * overflow that limit.
1207
1217
  */
1208
1218
  indexName() {
1209
- return _IndexOptimizer.prefix + Math.random().toString(36).substring(2, 16);
1219
+ const indexName = _IndexOptimizer.prefix + Math.random().toString(36).substring(2, 16);
1220
+ return PgIdentifier.fromString(indexName);
1210
1221
  }
1211
1222
  // TODO: this doesn't belong in the optimizer
1212
1223
  indexAlreadyExists(table, columns) {
@@ -1237,7 +1248,7 @@ var _IndexOptimizer = class _IndexOptimizer {
1237
1248
  continue;
1238
1249
  }
1239
1250
  const indexName = this.indexName();
1240
- const definition = this.toDefinition(permutation).raw;
1251
+ const definition = this.toDefinition({ table, schema, columns: columns2 }).raw;
1241
1252
  iter = permutations.next(PROCEED);
1242
1253
  nextStage.push({
1243
1254
  name: indexName,
@@ -1250,18 +1261,19 @@ var _IndexOptimizer = class _IndexOptimizer {
1250
1261
  }
1251
1262
  return nextStage;
1252
1263
  }
1253
- toDefinition(permuted) {
1264
+ toDefinition({
1265
+ schema,
1266
+ table,
1267
+ columns
1268
+ }) {
1254
1269
  const make = (col, order, where, keyword) => {
1255
1270
  let fullyQualifiedTable;
1256
- if (permuted.schema.toString() === "public") {
1257
- fullyQualifiedTable = PgIdentifier.fromString(permuted.table);
1271
+ if (schema.toString() === "public") {
1272
+ fullyQualifiedTable = table;
1258
1273
  } else {
1259
- fullyQualifiedTable = PgIdentifier.fromParts(
1260
- permuted.schema,
1261
- permuted.table
1262
- );
1274
+ fullyQualifiedTable = PgIdentifier.fromParts(schema, table);
1263
1275
  }
1264
- const baseColumn = `${fullyQualifiedTable}(${permuted.columns.map((c) => {
1276
+ const baseColumn = `${fullyQualifiedTable}(${columns.map((c) => {
1265
1277
  const column = PgIdentifier.fromString(c.column);
1266
1278
  const direction = c.sort && this.sortDirection(c.sort);
1267
1279
  const nulls = c.sort && this.nullsOrder(c.sort);
@@ -1389,8 +1401,8 @@ var _IndexOptimizer = class _IndexOptimizer {
1389
1401
  const newIndexes = /* @__PURE__ */ new Set();
1390
1402
  const existingIndexes = /* @__PURE__ */ new Set();
1391
1403
  const prefix = _IndexOptimizer.prefix;
1392
- function go(plan) {
1393
- const indexName = plan["Index Name"];
1404
+ walkExplain(explain, (stage) => {
1405
+ const indexName = stage["Index Name"];
1394
1406
  if (indexName) {
1395
1407
  if (indexName.startsWith(prefix)) {
1396
1408
  newIndexes.add(indexName);
@@ -1401,21 +1413,36 @@ var _IndexOptimizer = class _IndexOptimizer {
1401
1413
  existingIndexes.add(indexName);
1402
1414
  }
1403
1415
  }
1404
- if (plan.Plans) {
1405
- for (const p of plan.Plans) {
1406
- go(p);
1407
- }
1408
- }
1409
- }
1410
- go(explain);
1416
+ });
1411
1417
  return {
1412
1418
  newIndexes,
1413
1419
  existingIndexes
1414
1420
  };
1415
1421
  }
1422
+ replaceUsedIndexesWithDefinition(explain, triedIndexes) {
1423
+ walkExplain(explain, (stage) => {
1424
+ const indexName = stage["Index Name"];
1425
+ if (indexName) {
1426
+ const recommendation = triedIndexes.get(indexName);
1427
+ if (recommendation) {
1428
+ stage["Index Name"] = recommendation.definition;
1429
+ }
1430
+ }
1431
+ });
1432
+ }
1416
1433
  };
1417
1434
  __publicField(_IndexOptimizer, "prefix", "__qd_");
1418
1435
  var IndexOptimizer = _IndexOptimizer;
1436
+ function walkExplain(explain, f) {
1437
+ function go(plan) {
1438
+ f(plan);
1439
+ if (plan.Plans) {
1440
+ for (const p of plan.Plans) {
1441
+ go(p);
1442
+ }
1443
+ }
1444
+ }
1445
+ }
1419
1446
  var RollbackError = class {
1420
1447
  constructor(value) {
1421
1448
  this.value = value;