@query-doctor/core 0.8.3 → 0.8.6
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/_virtual/_@oxc-project_runtime@0.122.0/helpers/defineProperty.cjs +13 -0
- package/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/defineProperty.mjs +13 -0
- package/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/toPrimitive.cjs +15 -0
- package/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/toPrimitive.mjs +15 -0
- package/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/toPropertyKey.cjs +10 -0
- package/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/toPropertyKey.mjs +10 -0
- package/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/typeof.cjs +17 -0
- package/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/typeof.mjs +12 -0
- package/dist/index.cjs +6 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +3 -2
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +3 -2
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +3 -2
- package/dist/index.mjs.map +1 -0
- package/dist/optimizer/dump.cjs +74 -0
- package/dist/optimizer/dump.cjs.map +1 -0
- package/dist/optimizer/dump.d.cts +101 -0
- package/dist/optimizer/dump.d.cts.map +1 -0
- package/dist/optimizer/dump.d.mts +101 -0
- package/dist/optimizer/dump.d.mts.map +1 -0
- package/dist/optimizer/dump.mjs +69 -0
- package/dist/optimizer/dump.mjs.map +1 -0
- package/dist/optimizer/statistics.cjs +110 -109
- package/dist/optimizer/statistics.cjs.map +1 -1
- package/dist/optimizer/statistics.d.cts +3 -2
- package/dist/optimizer/statistics.d.cts.map +1 -1
- package/dist/optimizer/statistics.d.mts +3 -2
- package/dist/optimizer/statistics.d.mts.map +1 -1
- package/dist/optimizer/statistics.mjs +110 -110
- package/dist/optimizer/statistics.mjs.map +1 -1
- package/dist/sql/walker.cjs +4 -0
- package/dist/sql/walker.cjs.map +1 -1
- package/dist/sql/walker.d.cts.map +1 -1
- package/dist/sql/walker.d.mts.map +1 -1
- package/dist/sql/walker.mjs +4 -0
- package/dist/sql/walker.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_pg_identifier = require("../sql/pg-identifier.cjs");
|
|
4
|
+
const require_statistics = require("./statistics.cjs");
|
|
5
|
+
let zod = require("zod");
|
|
6
|
+
let dedent = require("dedent");
|
|
7
|
+
dedent = require_runtime.__toESM(dedent, 1);
|
|
8
|
+
//#region src/optimizer/dump.ts
|
|
9
|
+
const ExportedQuery = zod.z.object({
|
|
10
|
+
username: zod.z.string(),
|
|
11
|
+
query: zod.z.string(),
|
|
12
|
+
meanTime: zod.z.number(),
|
|
13
|
+
calls: zod.z.coerce.string(),
|
|
14
|
+
rows: zod.z.coerce.string(),
|
|
15
|
+
topLevel: zod.z.boolean()
|
|
16
|
+
});
|
|
17
|
+
const CombinedExport = zod.z.object({
|
|
18
|
+
queries: zod.z.array(ExportedQuery).nullable().transform((v) => v ?? []),
|
|
19
|
+
stats: zod.z.array(require_statistics.ExportedStats)
|
|
20
|
+
});
|
|
21
|
+
function indent(sql, spaces) {
|
|
22
|
+
const pad = " ".repeat(spaces);
|
|
23
|
+
return sql.trim().split("\n").map((line) => pad + line).join("\n");
|
|
24
|
+
}
|
|
25
|
+
function dumpQueriesSql(schema, source = "pg_stat_statements") {
|
|
26
|
+
const quotedSchema = require_pg_identifier.PgIdentifier.fromString(schema).toString();
|
|
27
|
+
if (source === "pg_stat_monitor") return dedent.default`
|
|
28
|
+
SELECT
|
|
29
|
+
COALESCE(username, 'unknown_user') as "username",
|
|
30
|
+
query,
|
|
31
|
+
mean_exec_time as "meanTime",
|
|
32
|
+
calls,
|
|
33
|
+
rows,
|
|
34
|
+
toplevel as "topLevel"
|
|
35
|
+
FROM ${quotedSchema}.pg_stat_monitor
|
|
36
|
+
WHERE query NOT LIKE '%pg_stat_monitor%'
|
|
37
|
+
AND query NOT LIKE '%@qd_introspection%'
|
|
38
|
+
AND query NOT ILIKE 'explain%'
|
|
39
|
+
`;
|
|
40
|
+
return dedent.default`
|
|
41
|
+
SELECT
|
|
42
|
+
'unknown_user' as "username",
|
|
43
|
+
query,
|
|
44
|
+
mean_exec_time as "meanTime",
|
|
45
|
+
calls,
|
|
46
|
+
rows,
|
|
47
|
+
toplevel as "topLevel"
|
|
48
|
+
FROM ${quotedSchema}.pg_stat_statements
|
|
49
|
+
WHERE query NOT LIKE '%pg_stat_statements%'
|
|
50
|
+
AND query NOT LIKE '%@qd_introspection%'
|
|
51
|
+
AND query != '<insufficient privilege>'
|
|
52
|
+
AND query NOT ILIKE 'explain%'
|
|
53
|
+
`;
|
|
54
|
+
}
|
|
55
|
+
function combinedDumpSql(schema, source = "pg_stat_statements") {
|
|
56
|
+
const statsSql = indent(require_statistics.DUMP_STATS_SQL, 6);
|
|
57
|
+
return [
|
|
58
|
+
"SELECT json_build_object(",
|
|
59
|
+
` 'queries', (SELECT json_agg(q) FROM (`,
|
|
60
|
+
indent(dumpQueriesSql(schema, source), 8),
|
|
61
|
+
` ) q),`,
|
|
62
|
+
` 'stats', (`,
|
|
63
|
+
statsSql,
|
|
64
|
+
` )`,
|
|
65
|
+
`);`
|
|
66
|
+
].join("\n");
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
exports.CombinedExport = CombinedExport;
|
|
70
|
+
exports.ExportedQuery = ExportedQuery;
|
|
71
|
+
exports.combinedDumpSql = combinedDumpSql;
|
|
72
|
+
exports.dumpQueriesSql = dumpQueriesSql;
|
|
73
|
+
|
|
74
|
+
//# sourceMappingURL=dump.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dump.cjs","names":["z","ExportedStats","PgIdentifier","DUMP_STATS_SQL"],"sources":["../../src/optimizer/dump.ts"],"sourcesContent":["import dedent from \"dedent\";\nimport { z } from \"zod\";\nimport { PgIdentifier } from \"../sql/pg-identifier.js\";\nimport { DUMP_STATS_SQL, ExportedStats } from \"./statistics.js\";\n\nexport const ExportedQuery = z.object({\n username: z.string(),\n query: z.string(),\n meanTime: z.number(),\n calls: z.coerce.string(),\n rows: z.coerce.string(),\n topLevel: z.boolean(),\n});\n\nexport type ExportedQuery = z.infer<typeof ExportedQuery>;\n\nexport const CombinedExport = z.object({\n queries: z.array(ExportedQuery).nullable().transform((v) => v ?? []),\n stats: z.array(ExportedStats),\n});\n\nexport type CombinedExport = z.infer<typeof CombinedExport>;\n\nexport type QuerySource = \"pg_stat_statements\" | \"pg_stat_monitor\";\n\nfunction indent(sql: string, spaces: number): string {\n const pad = \" \".repeat(spaces);\n return sql\n .trim()\n .split(\"\\n\")\n .map((line) => pad + line)\n .join(\"\\n\");\n}\n\nexport function dumpQueriesSql(\n schema: string,\n source: QuerySource = \"pg_stat_statements\",\n): string {\n const quotedSchema = PgIdentifier.fromString(schema).toString();\n if (source === \"pg_stat_monitor\") {\n return dedent`\n SELECT\n COALESCE(username, 'unknown_user') as \"username\",\n query,\n mean_exec_time as \"meanTime\",\n calls,\n rows,\n toplevel as \"topLevel\"\n FROM ${quotedSchema}.pg_stat_monitor\n WHERE query NOT LIKE '%pg_stat_monitor%'\n AND query NOT LIKE '%@qd_introspection%'\n AND query NOT ILIKE 'explain%'\n `;\n }\n return dedent`\n SELECT\n 'unknown_user' as \"username\",\n query,\n mean_exec_time as \"meanTime\",\n calls,\n rows,\n toplevel as \"topLevel\"\n FROM ${quotedSchema}.pg_stat_statements\n WHERE query NOT LIKE '%pg_stat_statements%'\n AND query NOT LIKE '%@qd_introspection%'\n AND query != '<insufficient privilege>'\n AND query NOT ILIKE 'explain%'\n `;\n}\n\nexport function combinedDumpSql(\n schema: string,\n source: QuerySource = \"pg_stat_statements\",\n): string {\n const statsSql = indent(DUMP_STATS_SQL, 6);\n const queriesSql = indent(dumpQueriesSql(schema, source), 8);\n return [\n \"SELECT json_build_object(\",\n ` 'queries', (SELECT json_agg(q) FROM (`,\n queriesSql,\n ` ) q),`,\n ` 'stats', (`,\n statsSql,\n ` )`,\n `);`,\n ].join(\"\\n\");\n}\n"],"mappings":";;;;;;;;AAKA,MAAa,gBAAgBA,IAAAA,EAAE,OAAO;CACpC,UAAUA,IAAAA,EAAE,QAAQ;CACpB,OAAOA,IAAAA,EAAE,QAAQ;CACjB,UAAUA,IAAAA,EAAE,QAAQ;CACpB,OAAOA,IAAAA,EAAE,OAAO,QAAQ;CACxB,MAAMA,IAAAA,EAAE,OAAO,QAAQ;CACvB,UAAUA,IAAAA,EAAE,SAAS;CACtB,CAAC;AAIF,MAAa,iBAAiBA,IAAAA,EAAE,OAAO;CACrC,SAASA,IAAAA,EAAE,MAAM,cAAc,CAAC,UAAU,CAAC,WAAW,MAAM,KAAK,EAAE,CAAC;CACpE,OAAOA,IAAAA,EAAE,MAAMC,mBAAAA,cAAc;CAC9B,CAAC;AAMF,SAAS,OAAO,KAAa,QAAwB;CACnD,MAAM,MAAM,IAAI,OAAO,OAAO;AAC9B,QAAO,IACJ,MAAM,CACN,MAAM,KAAK,CACX,KAAK,SAAS,MAAM,KAAK,CACzB,KAAK,KAAK;;AAGf,SAAgB,eACd,QACA,SAAsB,sBACd;CACR,MAAM,eAAeC,sBAAAA,aAAa,WAAW,OAAO,CAAC,UAAU;AAC/D,KAAI,WAAW,kBACb,QAAO,OAAA,OAAM;;;;;;;;aAQJ,aAAa;;;;;AAMxB,QAAO,OAAA,OAAM;;;;;;;;WAQJ,aAAa;;;;;;;AAQxB,SAAgB,gBACd,QACA,SAAsB,sBACd;CACR,MAAM,WAAW,OAAOC,mBAAAA,gBAAgB,EAAE;AAE1C,QAAO;EACL;EACA;EAHiB,OAAO,eAAe,QAAQ,OAAO,EAAE,EAAE;EAK1D;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
//#region src/optimizer/dump.d.ts
|
|
6
|
+
declare const ExportedQuery: z.ZodObject<{
|
|
7
|
+
username: z.ZodString;
|
|
8
|
+
query: z.ZodString;
|
|
9
|
+
meanTime: z.ZodNumber;
|
|
10
|
+
calls: z.ZodCoercedString<unknown>;
|
|
11
|
+
rows: z.ZodCoercedString<unknown>;
|
|
12
|
+
topLevel: z.ZodBoolean;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
type ExportedQuery = z.infer<typeof ExportedQuery>;
|
|
15
|
+
declare const CombinedExport: z.ZodObject<{
|
|
16
|
+
queries: z.ZodPipe<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
17
|
+
username: z.ZodString;
|
|
18
|
+
query: z.ZodString;
|
|
19
|
+
meanTime: z.ZodNumber;
|
|
20
|
+
calls: z.ZodCoercedString<unknown>;
|
|
21
|
+
rows: z.ZodCoercedString<unknown>;
|
|
22
|
+
topLevel: z.ZodBoolean;
|
|
23
|
+
}, z.core.$strip>>>, z.ZodTransform<{
|
|
24
|
+
username: string;
|
|
25
|
+
query: string;
|
|
26
|
+
meanTime: number;
|
|
27
|
+
calls: string;
|
|
28
|
+
rows: string;
|
|
29
|
+
topLevel: boolean;
|
|
30
|
+
}[], {
|
|
31
|
+
username: string;
|
|
32
|
+
query: string;
|
|
33
|
+
meanTime: number;
|
|
34
|
+
calls: string;
|
|
35
|
+
rows: string;
|
|
36
|
+
topLevel: boolean;
|
|
37
|
+
}[] | null>>;
|
|
38
|
+
stats: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
39
|
+
tableName: z.ZodString;
|
|
40
|
+
schemaName: z.ZodString;
|
|
41
|
+
relpages: z.ZodNumber;
|
|
42
|
+
reltuples: z.ZodNumber;
|
|
43
|
+
relallvisible: z.ZodNumber;
|
|
44
|
+
relallfrozen: z.ZodOptional<z.ZodNumber>;
|
|
45
|
+
columns: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
46
|
+
columnName: z.ZodString;
|
|
47
|
+
attlen: z.ZodNullable<z.ZodNumber>;
|
|
48
|
+
dataType: z.ZodOptional<z.ZodString>;
|
|
49
|
+
stats: z.ZodNullable<z.ZodObject<{
|
|
50
|
+
stawidth: z.ZodNumber;
|
|
51
|
+
stainherit: z.ZodDefault<z.ZodBoolean>;
|
|
52
|
+
stadistinct: z.ZodNumber;
|
|
53
|
+
stanullfrac: z.ZodNumber;
|
|
54
|
+
stakind1: z.ZodNumber;
|
|
55
|
+
stakind2: z.ZodNumber;
|
|
56
|
+
stakind3: z.ZodNumber;
|
|
57
|
+
stakind4: z.ZodNumber;
|
|
58
|
+
stakind5: z.ZodNumber;
|
|
59
|
+
staop1: z.ZodString;
|
|
60
|
+
staop2: z.ZodString;
|
|
61
|
+
staop3: z.ZodString;
|
|
62
|
+
staop4: z.ZodString;
|
|
63
|
+
staop5: z.ZodString;
|
|
64
|
+
stacoll1: z.ZodString;
|
|
65
|
+
stacoll2: z.ZodString;
|
|
66
|
+
stacoll3: z.ZodString;
|
|
67
|
+
stacoll4: z.ZodString;
|
|
68
|
+
stacoll5: z.ZodString;
|
|
69
|
+
stanumbers1: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
|
|
70
|
+
stanumbers2: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
|
|
71
|
+
stanumbers3: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
|
|
72
|
+
stanumbers4: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
|
|
73
|
+
stanumbers5: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
|
|
74
|
+
stavalues1: z.ZodNullable<z.ZodArray<z.ZodAny>>;
|
|
75
|
+
stavalues2: z.ZodNullable<z.ZodArray<z.ZodAny>>;
|
|
76
|
+
stavalues3: z.ZodNullable<z.ZodArray<z.ZodAny>>;
|
|
77
|
+
stavalues4: z.ZodNullable<z.ZodArray<z.ZodAny>>;
|
|
78
|
+
stavalues5: z.ZodNullable<z.ZodArray<z.ZodAny>>;
|
|
79
|
+
}, z.core.$strip>>;
|
|
80
|
+
}, z.core.$strip>>>;
|
|
81
|
+
indexes: z.ZodArray<z.ZodObject<{
|
|
82
|
+
indexName: z.ZodString;
|
|
83
|
+
amname: z.ZodDefault<z.ZodString>;
|
|
84
|
+
relpages: z.ZodNumber;
|
|
85
|
+
reltuples: z.ZodNumber;
|
|
86
|
+
relallvisible: z.ZodNumber;
|
|
87
|
+
relallfrozen: z.ZodOptional<z.ZodNumber>;
|
|
88
|
+
fillfactor: z.ZodDefault<z.ZodNumber>;
|
|
89
|
+
columns: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
90
|
+
attlen: z.ZodNullable<z.ZodNumber>;
|
|
91
|
+
}, z.core.$strip>>>;
|
|
92
|
+
}, z.core.$strip>>;
|
|
93
|
+
}, z.core.$strip>]>>;
|
|
94
|
+
}, z.core.$strip>;
|
|
95
|
+
type CombinedExport = z.infer<typeof CombinedExport>;
|
|
96
|
+
type QuerySource = "pg_stat_statements" | "pg_stat_monitor";
|
|
97
|
+
declare function dumpQueriesSql(schema: string, source?: QuerySource): string;
|
|
98
|
+
declare function combinedDumpSql(schema: string, source?: QuerySource): string;
|
|
99
|
+
//#endregion
|
|
100
|
+
export { CombinedExport, ExportedQuery, QuerySource, combinedDumpSql, dumpQueriesSql };
|
|
101
|
+
//# sourceMappingURL=dump.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dump.d.cts","names":[],"sources":["../../src/optimizer/dump.ts"],"mappings":";;;;;cAKa,aAAA,EAAa,CAAA,CAAA,SAAA;;;;;;;;KASd,aAAA,GAAgB,CAAA,CAAE,KAAA,QAAa,aAAA;AAAA,cAE9B,cAAA,EAAc,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAKf,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,cAAA;AAAA,KAEhC,WAAA;AAAA,iBAWI,cAAA,CACd,MAAA,UACA,MAAA,GAAQ,WAAA;AAAA,iBAkCM,eAAA,CACd,MAAA,UACA,MAAA,GAAQ,WAAA"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
//#region src/optimizer/dump.d.ts
|
|
6
|
+
declare const ExportedQuery: z.ZodObject<{
|
|
7
|
+
username: z.ZodString;
|
|
8
|
+
query: z.ZodString;
|
|
9
|
+
meanTime: z.ZodNumber;
|
|
10
|
+
calls: z.ZodCoercedString<unknown>;
|
|
11
|
+
rows: z.ZodCoercedString<unknown>;
|
|
12
|
+
topLevel: z.ZodBoolean;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
type ExportedQuery = z.infer<typeof ExportedQuery>;
|
|
15
|
+
declare const CombinedExport: z.ZodObject<{
|
|
16
|
+
queries: z.ZodPipe<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
17
|
+
username: z.ZodString;
|
|
18
|
+
query: z.ZodString;
|
|
19
|
+
meanTime: z.ZodNumber;
|
|
20
|
+
calls: z.ZodCoercedString<unknown>;
|
|
21
|
+
rows: z.ZodCoercedString<unknown>;
|
|
22
|
+
topLevel: z.ZodBoolean;
|
|
23
|
+
}, z.core.$strip>>>, z.ZodTransform<{
|
|
24
|
+
username: string;
|
|
25
|
+
query: string;
|
|
26
|
+
meanTime: number;
|
|
27
|
+
calls: string;
|
|
28
|
+
rows: string;
|
|
29
|
+
topLevel: boolean;
|
|
30
|
+
}[], {
|
|
31
|
+
username: string;
|
|
32
|
+
query: string;
|
|
33
|
+
meanTime: number;
|
|
34
|
+
calls: string;
|
|
35
|
+
rows: string;
|
|
36
|
+
topLevel: boolean;
|
|
37
|
+
}[] | null>>;
|
|
38
|
+
stats: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
39
|
+
tableName: z.ZodString;
|
|
40
|
+
schemaName: z.ZodString;
|
|
41
|
+
relpages: z.ZodNumber;
|
|
42
|
+
reltuples: z.ZodNumber;
|
|
43
|
+
relallvisible: z.ZodNumber;
|
|
44
|
+
relallfrozen: z.ZodOptional<z.ZodNumber>;
|
|
45
|
+
columns: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
46
|
+
columnName: z.ZodString;
|
|
47
|
+
attlen: z.ZodNullable<z.ZodNumber>;
|
|
48
|
+
dataType: z.ZodOptional<z.ZodString>;
|
|
49
|
+
stats: z.ZodNullable<z.ZodObject<{
|
|
50
|
+
stawidth: z.ZodNumber;
|
|
51
|
+
stainherit: z.ZodDefault<z.ZodBoolean>;
|
|
52
|
+
stadistinct: z.ZodNumber;
|
|
53
|
+
stanullfrac: z.ZodNumber;
|
|
54
|
+
stakind1: z.ZodNumber;
|
|
55
|
+
stakind2: z.ZodNumber;
|
|
56
|
+
stakind3: z.ZodNumber;
|
|
57
|
+
stakind4: z.ZodNumber;
|
|
58
|
+
stakind5: z.ZodNumber;
|
|
59
|
+
staop1: z.ZodString;
|
|
60
|
+
staop2: z.ZodString;
|
|
61
|
+
staop3: z.ZodString;
|
|
62
|
+
staop4: z.ZodString;
|
|
63
|
+
staop5: z.ZodString;
|
|
64
|
+
stacoll1: z.ZodString;
|
|
65
|
+
stacoll2: z.ZodString;
|
|
66
|
+
stacoll3: z.ZodString;
|
|
67
|
+
stacoll4: z.ZodString;
|
|
68
|
+
stacoll5: z.ZodString;
|
|
69
|
+
stanumbers1: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
|
|
70
|
+
stanumbers2: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
|
|
71
|
+
stanumbers3: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
|
|
72
|
+
stanumbers4: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
|
|
73
|
+
stanumbers5: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
|
|
74
|
+
stavalues1: z.ZodNullable<z.ZodArray<z.ZodAny>>;
|
|
75
|
+
stavalues2: z.ZodNullable<z.ZodArray<z.ZodAny>>;
|
|
76
|
+
stavalues3: z.ZodNullable<z.ZodArray<z.ZodAny>>;
|
|
77
|
+
stavalues4: z.ZodNullable<z.ZodArray<z.ZodAny>>;
|
|
78
|
+
stavalues5: z.ZodNullable<z.ZodArray<z.ZodAny>>;
|
|
79
|
+
}, z.core.$strip>>;
|
|
80
|
+
}, z.core.$strip>>>;
|
|
81
|
+
indexes: z.ZodArray<z.ZodObject<{
|
|
82
|
+
indexName: z.ZodString;
|
|
83
|
+
amname: z.ZodDefault<z.ZodString>;
|
|
84
|
+
relpages: z.ZodNumber;
|
|
85
|
+
reltuples: z.ZodNumber;
|
|
86
|
+
relallvisible: z.ZodNumber;
|
|
87
|
+
relallfrozen: z.ZodOptional<z.ZodNumber>;
|
|
88
|
+
fillfactor: z.ZodDefault<z.ZodNumber>;
|
|
89
|
+
columns: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
90
|
+
attlen: z.ZodNullable<z.ZodNumber>;
|
|
91
|
+
}, z.core.$strip>>>;
|
|
92
|
+
}, z.core.$strip>>;
|
|
93
|
+
}, z.core.$strip>]>>;
|
|
94
|
+
}, z.core.$strip>;
|
|
95
|
+
type CombinedExport = z.infer<typeof CombinedExport>;
|
|
96
|
+
type QuerySource = "pg_stat_statements" | "pg_stat_monitor";
|
|
97
|
+
declare function dumpQueriesSql(schema: string, source?: QuerySource): string;
|
|
98
|
+
declare function combinedDumpSql(schema: string, source?: QuerySource): string;
|
|
99
|
+
//#endregion
|
|
100
|
+
export { CombinedExport, ExportedQuery, QuerySource, combinedDumpSql, dumpQueriesSql };
|
|
101
|
+
//# sourceMappingURL=dump.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dump.d.mts","names":[],"sources":["../../src/optimizer/dump.ts"],"mappings":";;;;;cAKa,aAAA,EAAa,CAAA,CAAA,SAAA;;;;;;;;KASd,aAAA,GAAgB,CAAA,CAAE,KAAA,QAAa,aAAA;AAAA,cAE9B,cAAA,EAAc,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAKf,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,cAAA;AAAA,KAEhC,WAAA;AAAA,iBAWI,cAAA,CACd,MAAA,UACA,MAAA,GAAQ,WAAA;AAAA,iBAkCM,eAAA,CACd,MAAA,UACA,MAAA,GAAQ,WAAA"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { PgIdentifier } from "../sql/pg-identifier.mjs";
|
|
3
|
+
import { DUMP_STATS_SQL, ExportedStats } from "./statistics.mjs";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import dedent from "dedent";
|
|
6
|
+
//#region src/optimizer/dump.ts
|
|
7
|
+
const ExportedQuery = z.object({
|
|
8
|
+
username: z.string(),
|
|
9
|
+
query: z.string(),
|
|
10
|
+
meanTime: z.number(),
|
|
11
|
+
calls: z.coerce.string(),
|
|
12
|
+
rows: z.coerce.string(),
|
|
13
|
+
topLevel: z.boolean()
|
|
14
|
+
});
|
|
15
|
+
const CombinedExport = z.object({
|
|
16
|
+
queries: z.array(ExportedQuery).nullable().transform((v) => v ?? []),
|
|
17
|
+
stats: z.array(ExportedStats)
|
|
18
|
+
});
|
|
19
|
+
function indent(sql, spaces) {
|
|
20
|
+
const pad = " ".repeat(spaces);
|
|
21
|
+
return sql.trim().split("\n").map((line) => pad + line).join("\n");
|
|
22
|
+
}
|
|
23
|
+
function dumpQueriesSql(schema, source = "pg_stat_statements") {
|
|
24
|
+
const quotedSchema = PgIdentifier.fromString(schema).toString();
|
|
25
|
+
if (source === "pg_stat_monitor") return dedent`
|
|
26
|
+
SELECT
|
|
27
|
+
COALESCE(username, 'unknown_user') as "username",
|
|
28
|
+
query,
|
|
29
|
+
mean_exec_time as "meanTime",
|
|
30
|
+
calls,
|
|
31
|
+
rows,
|
|
32
|
+
toplevel as "topLevel"
|
|
33
|
+
FROM ${quotedSchema}.pg_stat_monitor
|
|
34
|
+
WHERE query NOT LIKE '%pg_stat_monitor%'
|
|
35
|
+
AND query NOT LIKE '%@qd_introspection%'
|
|
36
|
+
AND query NOT ILIKE 'explain%'
|
|
37
|
+
`;
|
|
38
|
+
return dedent`
|
|
39
|
+
SELECT
|
|
40
|
+
'unknown_user' as "username",
|
|
41
|
+
query,
|
|
42
|
+
mean_exec_time as "meanTime",
|
|
43
|
+
calls,
|
|
44
|
+
rows,
|
|
45
|
+
toplevel as "topLevel"
|
|
46
|
+
FROM ${quotedSchema}.pg_stat_statements
|
|
47
|
+
WHERE query NOT LIKE '%pg_stat_statements%'
|
|
48
|
+
AND query NOT LIKE '%@qd_introspection%'
|
|
49
|
+
AND query != '<insufficient privilege>'
|
|
50
|
+
AND query NOT ILIKE 'explain%'
|
|
51
|
+
`;
|
|
52
|
+
}
|
|
53
|
+
function combinedDumpSql(schema, source = "pg_stat_statements") {
|
|
54
|
+
const statsSql = indent(DUMP_STATS_SQL, 6);
|
|
55
|
+
return [
|
|
56
|
+
"SELECT json_build_object(",
|
|
57
|
+
` 'queries', (SELECT json_agg(q) FROM (`,
|
|
58
|
+
indent(dumpQueriesSql(schema, source), 8),
|
|
59
|
+
` ) q),`,
|
|
60
|
+
` 'stats', (`,
|
|
61
|
+
statsSql,
|
|
62
|
+
` )`,
|
|
63
|
+
`);`
|
|
64
|
+
].join("\n");
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
export { CombinedExport, ExportedQuery, combinedDumpSql, dumpQueriesSql };
|
|
68
|
+
|
|
69
|
+
//# sourceMappingURL=dump.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dump.mjs","names":[],"sources":["../../src/optimizer/dump.ts"],"sourcesContent":["import dedent from \"dedent\";\nimport { z } from \"zod\";\nimport { PgIdentifier } from \"../sql/pg-identifier.js\";\nimport { DUMP_STATS_SQL, ExportedStats } from \"./statistics.js\";\n\nexport const ExportedQuery = z.object({\n username: z.string(),\n query: z.string(),\n meanTime: z.number(),\n calls: z.coerce.string(),\n rows: z.coerce.string(),\n topLevel: z.boolean(),\n});\n\nexport type ExportedQuery = z.infer<typeof ExportedQuery>;\n\nexport const CombinedExport = z.object({\n queries: z.array(ExportedQuery).nullable().transform((v) => v ?? []),\n stats: z.array(ExportedStats),\n});\n\nexport type CombinedExport = z.infer<typeof CombinedExport>;\n\nexport type QuerySource = \"pg_stat_statements\" | \"pg_stat_monitor\";\n\nfunction indent(sql: string, spaces: number): string {\n const pad = \" \".repeat(spaces);\n return sql\n .trim()\n .split(\"\\n\")\n .map((line) => pad + line)\n .join(\"\\n\");\n}\n\nexport function dumpQueriesSql(\n schema: string,\n source: QuerySource = \"pg_stat_statements\",\n): string {\n const quotedSchema = PgIdentifier.fromString(schema).toString();\n if (source === \"pg_stat_monitor\") {\n return dedent`\n SELECT\n COALESCE(username, 'unknown_user') as \"username\",\n query,\n mean_exec_time as \"meanTime\",\n calls,\n rows,\n toplevel as \"topLevel\"\n FROM ${quotedSchema}.pg_stat_monitor\n WHERE query NOT LIKE '%pg_stat_monitor%'\n AND query NOT LIKE '%@qd_introspection%'\n AND query NOT ILIKE 'explain%'\n `;\n }\n return dedent`\n SELECT\n 'unknown_user' as \"username\",\n query,\n mean_exec_time as \"meanTime\",\n calls,\n rows,\n toplevel as \"topLevel\"\n FROM ${quotedSchema}.pg_stat_statements\n WHERE query NOT LIKE '%pg_stat_statements%'\n AND query NOT LIKE '%@qd_introspection%'\n AND query != '<insufficient privilege>'\n AND query NOT ILIKE 'explain%'\n `;\n}\n\nexport function combinedDumpSql(\n schema: string,\n source: QuerySource = \"pg_stat_statements\",\n): string {\n const statsSql = indent(DUMP_STATS_SQL, 6);\n const queriesSql = indent(dumpQueriesSql(schema, source), 8);\n return [\n \"SELECT json_build_object(\",\n ` 'queries', (SELECT json_agg(q) FROM (`,\n queriesSql,\n ` ) q),`,\n ` 'stats', (`,\n statsSql,\n ` )`,\n `);`,\n ].join(\"\\n\");\n}\n"],"mappings":";;;;;;AAKA,MAAa,gBAAgB,EAAE,OAAO;CACpC,UAAU,EAAE,QAAQ;CACpB,OAAO,EAAE,QAAQ;CACjB,UAAU,EAAE,QAAQ;CACpB,OAAO,EAAE,OAAO,QAAQ;CACxB,MAAM,EAAE,OAAO,QAAQ;CACvB,UAAU,EAAE,SAAS;CACtB,CAAC;AAIF,MAAa,iBAAiB,EAAE,OAAO;CACrC,SAAS,EAAE,MAAM,cAAc,CAAC,UAAU,CAAC,WAAW,MAAM,KAAK,EAAE,CAAC;CACpE,OAAO,EAAE,MAAM,cAAc;CAC9B,CAAC;AAMF,SAAS,OAAO,KAAa,QAAwB;CACnD,MAAM,MAAM,IAAI,OAAO,OAAO;AAC9B,QAAO,IACJ,MAAM,CACN,MAAM,KAAK,CACX,KAAK,SAAS,MAAM,KAAK,CACzB,KAAK,KAAK;;AAGf,SAAgB,eACd,QACA,SAAsB,sBACd;CACR,MAAM,eAAe,aAAa,WAAW,OAAO,CAAC,UAAU;AAC/D,KAAI,WAAW,kBACb,QAAO,MAAM;;;;;;;;aAQJ,aAAa;;;;;AAMxB,QAAO,MAAM;;;;;;;;WAQJ,aAAa;;;;;;;AAQxB,SAAgB,gBACd,QACA,SAAsB,sBACd;CACR,MAAM,WAAW,OAAO,gBAAgB,EAAE;AAE1C,QAAO;EACL;EACA;EAHiB,OAAO,eAAe,QAAQ,OAAO,EAAE,EAAE;EAK1D;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK"}
|
|
@@ -143,6 +143,112 @@ function estimateIndexRelpages(reltuples, columns, fillfactor, amname, tableRelp
|
|
|
143
143
|
const keyWidth = columns.reduce((sum, col) => sum + estimateStawidth(col) + 16, 0);
|
|
144
144
|
return Math.ceil(reltuples * keyWidth / DEFAULT_PAGE_SIZE / fillfactor);
|
|
145
145
|
}
|
|
146
|
+
const DUMP_STATS_SQL = dedent.default`
|
|
147
|
+
WITH table_columns AS (
|
|
148
|
+
SELECT
|
|
149
|
+
cl.relname,
|
|
150
|
+
n.nspname,
|
|
151
|
+
cl.reltuples,
|
|
152
|
+
cl.relpages,
|
|
153
|
+
cl.relallvisible,
|
|
154
|
+
-- cl.relallfrozen,
|
|
155
|
+
json_agg(
|
|
156
|
+
json_build_object(
|
|
157
|
+
'columnName', a.attname,
|
|
158
|
+
'attlen', CASE WHEN a.attlen > 0 THEN a.attlen ELSE NULL END,
|
|
159
|
+
'dataType', t.typname,
|
|
160
|
+
'stats', (
|
|
161
|
+
SELECT json_build_object(
|
|
162
|
+
'starelid', s.starelid,
|
|
163
|
+
'staattnum', s.staattnum,
|
|
164
|
+
'stanullfrac', s.stanullfrac,
|
|
165
|
+
'stawidth', s.stawidth,
|
|
166
|
+
'stadistinct', s.stadistinct,
|
|
167
|
+
'stakind1', s.stakind1, 'staop1', s.staop1, 'stacoll1', s.stacoll1, 'stanumbers1', s.stanumbers1,
|
|
168
|
+
'stakind2', s.stakind2, 'staop2', s.staop2, 'stacoll2', s.stacoll2, 'stanumbers2', s.stanumbers2,
|
|
169
|
+
'stakind3', s.stakind3, 'staop3', s.staop3, 'stacoll3', s.stacoll3, 'stanumbers3', s.stanumbers3,
|
|
170
|
+
'stakind4', s.stakind4, 'staop4', s.staop4, 'stacoll4', s.stacoll4, 'stanumbers4', s.stanumbers4,
|
|
171
|
+
'stakind5', s.stakind5, 'staop5', s.staop5, 'stacoll5', s.stacoll5, 'stanumbers5', s.stanumbers5,
|
|
172
|
+
'stavalues1', s.stavalues1,
|
|
173
|
+
'stavalues2', s.stavalues2,
|
|
174
|
+
'stavalues3', s.stavalues3,
|
|
175
|
+
'stavalues4', s.stavalues4,
|
|
176
|
+
'stavalues5', s.stavalues5
|
|
177
|
+
)
|
|
178
|
+
FROM pg_statistic s
|
|
179
|
+
WHERE s.starelid = a.attrelid AND s.staattnum = a.attnum
|
|
180
|
+
)
|
|
181
|
+
)
|
|
182
|
+
ORDER BY a.attnum
|
|
183
|
+
) AS columns
|
|
184
|
+
FROM pg_class cl
|
|
185
|
+
JOIN pg_namespace n ON n.oid = cl.relnamespace
|
|
186
|
+
JOIN pg_attribute a ON a.attrelid = cl.oid AND a.attnum > 0 AND NOT a.attisdropped
|
|
187
|
+
JOIN pg_type t ON t.oid = a.atttypid
|
|
188
|
+
WHERE cl.relkind = 'r'
|
|
189
|
+
AND n.nspname NOT IN ('pg_catalog', 'information_schema', 'tiger', 'tiger_data', 'topology')
|
|
190
|
+
AND cl.relname NOT IN ('pg_stat_statements', 'pg_stat_statements_info')
|
|
191
|
+
GROUP BY cl.relname, n.nspname, cl.reltuples, cl.relpages, cl.relallvisible
|
|
192
|
+
),
|
|
193
|
+
table_indexes AS (
|
|
194
|
+
SELECT
|
|
195
|
+
t.relname AS table_name,
|
|
196
|
+
json_agg(
|
|
197
|
+
json_build_object(
|
|
198
|
+
'indexName', i.relname,
|
|
199
|
+
'amname', am.amname,
|
|
200
|
+
'reltuples', i.reltuples,
|
|
201
|
+
'relpages', i.relpages,
|
|
202
|
+
'relallvisible', i.relallvisible,
|
|
203
|
+
-- 'relallfrozen', i.relallfrozen,
|
|
204
|
+
'fillfactor', COALESCE(
|
|
205
|
+
(
|
|
206
|
+
SELECT (regexp_match(opt, 'fillfactor=(\\d+)'))[1]::integer
|
|
207
|
+
FROM unnest(i.reloptions) AS opt
|
|
208
|
+
WHERE opt LIKE 'fillfactor=%'
|
|
209
|
+
LIMIT 1
|
|
210
|
+
),
|
|
211
|
+
90
|
|
212
|
+
),
|
|
213
|
+
'columns', COALESCE(
|
|
214
|
+
(
|
|
215
|
+
SELECT json_agg(json_build_object(
|
|
216
|
+
'attlen', CASE WHEN a.attlen > 0 THEN a.attlen ELSE NULL END
|
|
217
|
+
) ORDER BY col_pos.ord)
|
|
218
|
+
FROM unnest(ix.indkey) WITH ORDINALITY AS col_pos(attnum, ord)
|
|
219
|
+
JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = col_pos.attnum
|
|
220
|
+
WHERE col_pos.attnum > 0
|
|
221
|
+
),
|
|
222
|
+
'[]'::json
|
|
223
|
+
)
|
|
224
|
+
)
|
|
225
|
+
) AS indexes
|
|
226
|
+
FROM pg_class t
|
|
227
|
+
JOIN pg_index ix ON ix.indrelid = t.oid
|
|
228
|
+
JOIN pg_class i ON i.oid = ix.indexrelid
|
|
229
|
+
JOIN pg_am am ON am.oid = i.relam
|
|
230
|
+
JOIN pg_namespace n ON n.oid = t.relnamespace
|
|
231
|
+
WHERE t.relname NOT LIKE 'pg_%'
|
|
232
|
+
AND n.nspname <> 'information_schema'
|
|
233
|
+
AND n.nspname NOT IN ('tiger', 'tiger_data', 'topology')
|
|
234
|
+
GROUP BY t.relname
|
|
235
|
+
)
|
|
236
|
+
SELECT json_agg(
|
|
237
|
+
json_build_object(
|
|
238
|
+
'tableName', tc.relname,
|
|
239
|
+
'schemaName', tc.nspname,
|
|
240
|
+
'reltuples', tc.reltuples,
|
|
241
|
+
'relpages', tc.relpages,
|
|
242
|
+
'relallvisible', tc.relallvisible,
|
|
243
|
+
-- 'relallfrozen', tc.relallfrozen,
|
|
244
|
+
'columns', COALESCE(tc.columns, '[]'::json),
|
|
245
|
+
'indexes', COALESCE(ti.indexes, '[]'::json)
|
|
246
|
+
)
|
|
247
|
+
)
|
|
248
|
+
FROM table_columns tc
|
|
249
|
+
LEFT JOIN table_indexes ti
|
|
250
|
+
ON ti.table_name = tc.relname
|
|
251
|
+
`;
|
|
146
252
|
var Statistics = class Statistics {
|
|
147
253
|
constructor(db, postgresVersion, ownMetadata, statsMode) {
|
|
148
254
|
this.db = db;
|
|
@@ -315,7 +421,7 @@ var Statistics = class Statistics {
|
|
|
315
421
|
}
|
|
316
422
|
static async fromPostgres(db, statsMode) {
|
|
317
423
|
const version = await db.serverNum();
|
|
318
|
-
return new Statistics(db, version, await Statistics.dumpStats(db, version
|
|
424
|
+
return new Statistics(db, version, await Statistics.dumpStats(db, version), statsMode);
|
|
319
425
|
}
|
|
320
426
|
restoreStats(tx) {
|
|
321
427
|
return this.restoreStats17(tx);
|
|
@@ -421,115 +527,9 @@ var Statistics = class Statistics {
|
|
|
421
527
|
if (reltuplesUpdates.length !== this.computedStats.reltuples.length) console.error(`Did not update expected reltuples/relpages`);
|
|
422
528
|
return warnings;
|
|
423
529
|
}
|
|
424
|
-
static async dumpStats(db, postgresVersion
|
|
425
|
-
const fullDump = kind === "full";
|
|
530
|
+
static async dumpStats(db, postgresVersion) {
|
|
426
531
|
console.log(`dumping stats for postgres ${(0, colorette.gray)(postgresVersion)}`);
|
|
427
|
-
const stats = await db.exec(
|
|
428
|
-
WITH table_columns AS (
|
|
429
|
-
SELECT
|
|
430
|
-
cl.relname,
|
|
431
|
-
n.nspname,
|
|
432
|
-
cl.reltuples,
|
|
433
|
-
cl.relpages,
|
|
434
|
-
cl.relallvisible,
|
|
435
|
-
-- cl.relallfrozen,
|
|
436
|
-
json_agg(
|
|
437
|
-
json_build_object(
|
|
438
|
-
'columnName', a.attname,
|
|
439
|
-
'attlen', CASE WHEN a.attlen > 0 THEN a.attlen ELSE NULL END,
|
|
440
|
-
'dataType', t.typname,
|
|
441
|
-
'stats', (
|
|
442
|
-
SELECT json_build_object(
|
|
443
|
-
'starelid', s.starelid,
|
|
444
|
-
'staattnum', s.staattnum,
|
|
445
|
-
'stanullfrac', s.stanullfrac,
|
|
446
|
-
'stawidth', s.stawidth,
|
|
447
|
-
'stadistinct', s.stadistinct,
|
|
448
|
-
'stakind1', s.stakind1, 'staop1', s.staop1, 'stacoll1', s.stacoll1, 'stanumbers1', s.stanumbers1,
|
|
449
|
-
'stakind2', s.stakind2, 'staop2', s.staop2, 'stacoll2', s.stacoll2, 'stanumbers2', s.stanumbers2,
|
|
450
|
-
'stakind3', s.stakind3, 'staop3', s.staop3, 'stacoll3', s.stacoll3, 'stanumbers3', s.stanumbers3,
|
|
451
|
-
'stakind4', s.stakind4, 'staop4', s.staop4, 'stacoll4', s.stacoll4, 'stanumbers4', s.stanumbers4,
|
|
452
|
-
'stakind5', s.stakind5, 'staop5', s.staop5, 'stacoll5', s.stacoll5, 'stanumbers5', s.stanumbers5,
|
|
453
|
-
'stavalues1', CASE WHEN $1 THEN s.stavalues1 ELSE NULL END,
|
|
454
|
-
'stavalues2', CASE WHEN $1 THEN s.stavalues2 ELSE NULL END,
|
|
455
|
-
'stavalues3', CASE WHEN $1 THEN s.stavalues3 ELSE NULL END,
|
|
456
|
-
'stavalues4', CASE WHEN $1 THEN s.stavalues4 ELSE NULL END,
|
|
457
|
-
'stavalues5', CASE WHEN $1 THEN s.stavalues5 ELSE NULL END
|
|
458
|
-
)
|
|
459
|
-
FROM pg_statistic s
|
|
460
|
-
WHERE s.starelid = a.attrelid AND s.staattnum = a.attnum
|
|
461
|
-
)
|
|
462
|
-
)
|
|
463
|
-
ORDER BY a.attnum
|
|
464
|
-
) AS columns
|
|
465
|
-
FROM pg_class cl
|
|
466
|
-
JOIN pg_namespace n ON n.oid = cl.relnamespace
|
|
467
|
-
JOIN pg_attribute a ON a.attrelid = cl.oid AND a.attnum > 0 AND NOT a.attisdropped
|
|
468
|
-
JOIN pg_type t ON t.oid = a.atttypid
|
|
469
|
-
WHERE cl.relkind = 'r'
|
|
470
|
-
AND n.nspname NOT IN ('pg_catalog', 'information_schema', 'tiger', 'tiger_data', 'topology')
|
|
471
|
-
AND cl.relname NOT IN ('pg_stat_statements', 'pg_stat_statements_info')
|
|
472
|
-
GROUP BY cl.relname, n.nspname, cl.reltuples, cl.relpages, cl.relallvisible
|
|
473
|
-
),
|
|
474
|
-
table_indexes AS (
|
|
475
|
-
SELECT
|
|
476
|
-
t.relname AS table_name,
|
|
477
|
-
json_agg(
|
|
478
|
-
json_build_object(
|
|
479
|
-
'indexName', i.relname,
|
|
480
|
-
'amname', am.amname,
|
|
481
|
-
'reltuples', i.reltuples,
|
|
482
|
-
'relpages', i.relpages,
|
|
483
|
-
'relallvisible', i.relallvisible,
|
|
484
|
-
-- 'relallfrozen', i.relallfrozen,
|
|
485
|
-
'fillfactor', COALESCE(
|
|
486
|
-
(
|
|
487
|
-
SELECT (regexp_match(opt, 'fillfactor=(\\d+)'))[1]::integer
|
|
488
|
-
FROM unnest(i.reloptions) AS opt
|
|
489
|
-
WHERE opt LIKE 'fillfactor=%'
|
|
490
|
-
LIMIT 1
|
|
491
|
-
),
|
|
492
|
-
90
|
|
493
|
-
),
|
|
494
|
-
'columns', COALESCE(
|
|
495
|
-
(
|
|
496
|
-
SELECT json_agg(json_build_object(
|
|
497
|
-
'attlen', CASE WHEN a.attlen > 0 THEN a.attlen ELSE NULL END
|
|
498
|
-
) ORDER BY col_pos.ord)
|
|
499
|
-
FROM unnest(ix.indkey) WITH ORDINALITY AS col_pos(attnum, ord)
|
|
500
|
-
JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = col_pos.attnum
|
|
501
|
-
WHERE col_pos.attnum > 0
|
|
502
|
-
),
|
|
503
|
-
'[]'::json
|
|
504
|
-
)
|
|
505
|
-
)
|
|
506
|
-
) AS indexes
|
|
507
|
-
FROM pg_class t
|
|
508
|
-
JOIN pg_index ix ON ix.indrelid = t.oid
|
|
509
|
-
JOIN pg_class i ON i.oid = ix.indexrelid
|
|
510
|
-
JOIN pg_am am ON am.oid = i.relam
|
|
511
|
-
JOIN pg_namespace n ON n.oid = t.relnamespace
|
|
512
|
-
WHERE t.relname NOT LIKE 'pg_%'
|
|
513
|
-
AND n.nspname <> 'information_schema'
|
|
514
|
-
AND n.nspname NOT IN ('tiger', 'tiger_data', 'topology')
|
|
515
|
-
GROUP BY t.relname
|
|
516
|
-
)
|
|
517
|
-
SELECT json_agg(
|
|
518
|
-
json_build_object(
|
|
519
|
-
'tableName', tc.relname,
|
|
520
|
-
'schemaName', tc.nspname,
|
|
521
|
-
'reltuples', tc.reltuples,
|
|
522
|
-
'relpages', tc.relpages,
|
|
523
|
-
'relallvisible', tc.relallvisible,
|
|
524
|
-
-- 'relallfrozen', tc.relallfrozen,
|
|
525
|
-
'columns', COALESCE(tc.columns, '[]'::json),
|
|
526
|
-
'indexes', COALESCE(ti.indexes, '[]'::json)
|
|
527
|
-
)
|
|
528
|
-
)
|
|
529
|
-
FROM table_columns tc
|
|
530
|
-
LEFT JOIN table_indexes ti
|
|
531
|
-
ON ti.table_name = tc.relname;
|
|
532
|
-
`, [fullDump]);
|
|
532
|
+
const stats = await db.exec(DUMP_STATS_SQL);
|
|
533
533
|
return zod.z.array(ExportedStats).parse(stats[0].json_agg);
|
|
534
534
|
}
|
|
535
535
|
/**
|
|
@@ -784,6 +784,7 @@ require_defineProperty._defineProperty(Statistics, "columnStatsSQL", dedent.defa
|
|
|
784
784
|
exports.ComputedColumnStats = ComputedColumnStats;
|
|
785
785
|
exports.ComputedReltuples = ComputedReltuples;
|
|
786
786
|
exports.ComputedStats = ComputedStats;
|
|
787
|
+
exports.DUMP_STATS_SQL = DUMP_STATS_SQL;
|
|
787
788
|
exports.ExportedStats = ExportedStats;
|
|
788
789
|
exports.ExportedStatsColumns = ExportedStatsColumns;
|
|
789
790
|
exports.ExportedStatsIndex = ExportedStatsIndex;
|