@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 +49 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +49 -22
- package/dist/index.js.map +1 -1
- package/dist/optimizer/genalgo.d.ts +1 -0
- package/dist/optimizer/genalgo.d.ts.map +1 -1
- package/dist/sql/builder.d.ts +2 -1
- package/dist/sql/builder.d.ts.map +1 -1
- package/dist/sql/pg-identifier.d.ts +1 -1
- package/dist/sql/pg-identifier.d.ts.map +1 -1
- package/package.json +1 -1
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) =>
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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(
|
|
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(
|
|
1264
|
+
toDefinition({
|
|
1265
|
+
schema,
|
|
1266
|
+
table,
|
|
1267
|
+
columns
|
|
1268
|
+
}) {
|
|
1254
1269
|
const make = (col, order, where, keyword) => {
|
|
1255
1270
|
let fullyQualifiedTable;
|
|
1256
|
-
if (
|
|
1257
|
-
fullyQualifiedTable =
|
|
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}(${
|
|
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
|
-
|
|
1393
|
-
const indexName =
|
|
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
|
-
|
|
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;
|