diff --git a/deno.json b/deno.json index 83d7ffe..7ea6f67 100644 --- a/deno.json +++ b/deno.json @@ -25,7 +25,7 @@ "@libpg-query/parser": "npm:@libpg-query/parser@^17.6.3", "@opentelemetry/api": "jsr:@opentelemetry/api@^1.9.0", "@pgsql/types": "npm:@pgsql/types@^17.6.1", - "@query-doctor/core": "npm:@query-doctor/core@^0.2.5", + "@query-doctor/core": "npm:@query-doctor/core@^0.3.0", "@rabbit-company/rate-limiter": "jsr:@rabbit-company/rate-limiter@^3.0.0", "@std/assert": "jsr:@std/assert@^1.0.14", "@std/collections": "jsr:@std/collections@^1.1.3", diff --git a/deno.lock b/deno.lock index 4300758..ed8045c 100644 --- a/deno.lock +++ b/deno.lock @@ -20,7 +20,7 @@ "npm:@actions/github@^6.0.1": "6.0.1_@octokit+core@5.2.2", "npm:@libpg-query/parser@^17.6.3": "17.6.3", "npm:@pgsql/types@^17.6.1": "17.6.2", - "npm:@query-doctor/core@~0.2.5": "0.2.5", + "npm:@query-doctor/core@0.3": "0.3.0", "npm:@testcontainers/postgresql@^11.9.0": "11.9.0", "npm:@types/node@^24.9.1": "24.10.1", "npm:@types/nunjucks@^3.2.6": "3.2.6", @@ -350,8 +350,8 @@ "@protobufjs/utf8@1.1.0": { "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, - "@query-doctor/core@0.2.5": { - "integrity": "sha512-ivlxt96NwptijnAniNMdGEMtxbh7+5xtj6vh07q6y7olb17BZRF0Gpik3r9X0RMis2LKgltJ2toBBrofhbyzMg==", + "@query-doctor/core@0.3.0": { + "integrity": "sha512-ybfqah0Hzr0grSi1jBnP3WFaOK9S7ZRaNoyDBsVcd6O/0M0yGj8xiS580Rqkoqnww2qa5BFxDMSltaNOCmZo7g==", "dependencies": [ "@pgsql/types", "colorette", @@ -1754,7 +1754,7 @@ "npm:@actions/github@^6.0.1", "npm:@libpg-query/parser@^17.6.3", "npm:@pgsql/types@^17.6.1", - "npm:@query-doctor/core@~0.2.5", + "npm:@query-doctor/core@0.3", "npm:@testcontainers/postgresql@^11.9.0", "npm:@types/node@^24.9.1", "npm:@types/nunjucks@^3.2.6", diff --git a/src/remote/query-optimizer.test.ts b/src/remote/query-optimizer.test.ts index d3a5576..0d6a4e7 100644 --- a/src/remote/query-optimizer.test.ts +++ b/src/remote/query-optimizer.test.ts @@ -51,11 +51,11 @@ Deno.test({ const conn = Connectable.fromString(pg.getConnectionUri()); const optimizer = new QueryOptimizer(manager, conn); - const expectedImprovements = ["select * from testing where a = $1"]; + const expectedImprovements = ["select * from testing where a = $1;"]; const expectedNoImprovements = [ - "select * from testing where b = $1", - "select * from testing where b > $1", - "select * from testing where b < $1", + "select * from testing where b = $1;", + "select * from testing where b > $1;", + "select * from testing where b < $1;", ]; let improvements: string[] = []; @@ -121,9 +121,9 @@ Deno.test({ new RecentQuery( { calls: "0", - formattedQuery: "select * from testing where a >= $1", + formattedQuery: "select * from testing where a >= $1;", meanTime: 100, - query: "select * from testing where a >= $1", + query: "select * from testing where a >= $1;", rows: "1", topLevel: true, username: "test", @@ -143,7 +143,7 @@ Deno.test({ ), ]); assertArrayIncludes( - [...expectedImprovements, "select * from testing where a >= $1"], + [...expectedImprovements, "select * from testing where a >= $1;"], improvements, ); assertArrayIncludes(expectedNoImprovements, noImprovements); diff --git a/src/remote/remote.test.ts b/src/remote/remote.test.ts index f818255..b200524 100644 --- a/src/remote/remote.test.ts +++ b/src/remote/remote.test.ts @@ -78,8 +78,8 @@ Deno.test({ const queries = optimizedQueries.map((f) => f.query); assertArrayIncludes(queries, [ - "create table testing(a int, b text)", - "select * from testing where a = $1", + "create table testing(a int, b text);", + "select * from testing where a = $1;", ]); assertOk(result.schema); @@ -407,10 +407,10 @@ Deno.test({ const queryStrings = queries.map((q) => q.query); assertArrayIncludes(queryStrings, [ - "select * from conditions where time < now()", + "select * from conditions where time < now();", ]); const indexesAfter = await t.exec( - "select indexname from pg_indexes where schemaname = 'public'", + "select indexname from pg_indexes where schemaname = 'public';", ); assertEquals( indexesAfter.length, @@ -490,9 +490,7 @@ Deno.test({ "fulfilled", "Schema poll should succeed", ); - const diffs = diffsResult.status === "fulfilled" - ? diffsResult.value - : []; + const diffs = diffsResult.status === "fulfilled" ? diffsResult.value : []; assertEquals( diffs.length, diff --git a/src/sql/recent-query.ts b/src/sql/recent-query.ts index fd93b66..b1e472f 100644 --- a/src/sql/recent-query.ts +++ b/src/sql/recent-query.ts @@ -6,6 +6,7 @@ import { Analyzer, DiscoveredColumnReference, Nudge, + PostgresQueryBuilder, PssRewriter, SQLCommenterTag, type TableReference, @@ -19,6 +20,7 @@ import type { LiveQueryOptimization } from "../remote/optimization.ts"; * and supplying the date the query was last seen */ export class RecentQuery { + private static HARDCODED_LIMIT = 50; private static rewriter = new PssRewriter(); readonly formattedQuery: string; @@ -70,8 +72,8 @@ export class RecentQuery { seenAt: number, ) { const analyzer = new Analyzer(parse); - const rewrittenQuery = RecentQuery.rewriter.rewrite(data.query); - const analysis = await analyzer.analyze(rewrittenQuery); + const query = this.rewriteQuery(data.query); + const analysis = await analyzer.analyze(query); const formattedQuery = await RecentQuery.formatQuery( analysis.queryWithoutTags, ); @@ -86,6 +88,13 @@ export class RecentQuery { ); } + private static rewriteQuery(rawQuery: string): string { + const query = new PostgresQueryBuilder(rawQuery).replaceLimit( + RecentQuery.HARDCODED_LIMIT, + ).build(); + return RecentQuery.rewriter.rewrite(query); + } + private static async formatQuery(query: string): Promise { try { return await prettier.format(query, {