@query-doctor/core 0.1.7 → 0.1.10
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 +47 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +47 -5
- package/dist/index.js.map +1 -1
- package/dist/optimizer/genalgo.d.ts +14 -0
- package/dist/optimizer/genalgo.d.ts.map +1 -1
- package/dist/optimizer/statistics.d.ts.map +1 -1
- package/dist/sql/analyzer.d.ts.map +1 -1
- package/dist/sql/nudges.d.ts +1 -1
- package/dist/sql/nudges.d.ts.map +1 -1
- package/dist/sql/walker.d.ts.map +1 -1
- package/dist/sql/walker.test.d.ts +2 -0
- package/dist/sql/walker.test.d.ts.map +1 -0
- package/package.json +2 -3
- package/.eslintrc.cjs +0 -4
package/dist/index.cjs
CHANGED
|
@@ -189,6 +189,23 @@ function parseNudges(node, stack) {
|
|
|
189
189
|
});
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
|
+
if (is(node, "A_Expr")) {
|
|
193
|
+
if (node.A_Expr.kind === "AEXPR_IN") {
|
|
194
|
+
let list;
|
|
195
|
+
if (node.A_Expr.lexpr && is(node.A_Expr.lexpr, "List")) {
|
|
196
|
+
list = node.A_Expr.lexpr.List;
|
|
197
|
+
} else if (node.A_Expr.rexpr && is(node.A_Expr.rexpr, "List")) {
|
|
198
|
+
list = node.A_Expr.rexpr.List;
|
|
199
|
+
}
|
|
200
|
+
if (list?.items && list.items.length >= 10) {
|
|
201
|
+
nudges.push({
|
|
202
|
+
kind: "REPLACE_LARGE_IN_TUPLE_WITH_ANY_ARRAY",
|
|
203
|
+
message: "`in (...)` queries with large tuples can often be replaced with `= ANY($1)` using a single parameter",
|
|
204
|
+
severity: "INFO"
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
192
209
|
return nudges;
|
|
193
210
|
}
|
|
194
211
|
function containsColumnRef(args) {
|
|
@@ -344,9 +361,12 @@ var Walker = class _Walker {
|
|
|
344
361
|
part.schema = node.RangeVar.schemaname;
|
|
345
362
|
}
|
|
346
363
|
if (existingMapping) {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
364
|
+
const isSystemCatalog = node.RangeVar.relname?.startsWith("pg_") ?? false;
|
|
365
|
+
if (!isSystemCatalog) {
|
|
366
|
+
console.warn(
|
|
367
|
+
`Ignoring alias ${aliasName} as it shadows an existing mapping for ${existingMapping.text}. We currently do not support alias shadowing.`
|
|
368
|
+
);
|
|
369
|
+
}
|
|
350
370
|
this.shadowedAliases.push(part);
|
|
351
371
|
return;
|
|
352
372
|
}
|
|
@@ -744,7 +764,7 @@ var Analyzer = class {
|
|
|
744
764
|
return { tags: [], queryWithoutTags: trimmedQuery };
|
|
745
765
|
}
|
|
746
766
|
const queryWithoutTags = trimmedQuery.slice(0, startPosition);
|
|
747
|
-
const tagString = trimmedQuery.slice(startPosition + 2, endPosition);
|
|
767
|
+
const tagString = trimmedQuery.slice(startPosition + 2, endPosition).trim();
|
|
748
768
|
if (!tagString || typeof tagString !== "string") {
|
|
749
769
|
return { tags: [], queryWithoutTags };
|
|
750
770
|
}
|
|
@@ -752,7 +772,11 @@ var Analyzer = class {
|
|
|
752
772
|
for (const match of tagString.split(",")) {
|
|
753
773
|
const [key, value] = match.split("=");
|
|
754
774
|
if (!key || !value) {
|
|
755
|
-
|
|
775
|
+
if (tags.length > 0) {
|
|
776
|
+
console.warn(
|
|
777
|
+
`Invalid sqlcommenter tag: ${match} in comment: ${tagString}. Ignoring`
|
|
778
|
+
);
|
|
779
|
+
}
|
|
756
780
|
continue;
|
|
757
781
|
}
|
|
758
782
|
try {
|
|
@@ -1158,6 +1182,24 @@ var _IndexOptimizer = class _IndexOptimizer {
|
|
|
1158
1182
|
await this.dropExistingIndexes(tx);
|
|
1159
1183
|
});
|
|
1160
1184
|
}
|
|
1185
|
+
/**
|
|
1186
|
+
* Given the current indexes in the optimizer, transform them in some
|
|
1187
|
+
* way to change which indexes will be assumed to exist when optimizing
|
|
1188
|
+
*
|
|
1189
|
+
* @example
|
|
1190
|
+
* ```
|
|
1191
|
+
* // resets indexes
|
|
1192
|
+
* optimizer.transformIndexes(() => [])
|
|
1193
|
+
*
|
|
1194
|
+
* // adds new index
|
|
1195
|
+
* optimizer.transformIndexes(indexes => [...indexes, newIndex])
|
|
1196
|
+
* ```
|
|
1197
|
+
*/
|
|
1198
|
+
transformIndexes(f) {
|
|
1199
|
+
const newIndexes = f(this.existingIndexes);
|
|
1200
|
+
this.existingIndexes = newIndexes;
|
|
1201
|
+
return this;
|
|
1202
|
+
}
|
|
1161
1203
|
/**
|
|
1162
1204
|
* Postgres has a limit of 63 characters for index names.
|
|
1163
1205
|
* So we use this to make sure we don't derive it from a list of columns that can
|