@query-doctor/core 0.4.1 → 0.4.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.
Files changed (63) hide show
  1. package/dist/index.cjs +1678 -2000
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +750 -0
  4. package/dist/index.d.cts.map +1 -0
  5. package/dist/index.d.mts +750 -0
  6. package/dist/index.d.mts.map +1 -0
  7. package/dist/index.mjs +1676 -24978
  8. package/dist/index.mjs.map +1 -1
  9. package/package.json +12 -11
  10. package/dist/explain/rewriter.d.ts +0 -4
  11. package/dist/explain/rewriter.d.ts.map +0 -1
  12. package/dist/explain/traverse.d.ts +0 -3
  13. package/dist/explain/traverse.d.ts.map +0 -1
  14. package/dist/explain/tree.d.ts +0 -73
  15. package/dist/explain/tree.d.ts.map +0 -1
  16. package/dist/index.d.ts +0 -10
  17. package/dist/index.d.ts.map +0 -1
  18. package/dist/index.js +0 -2352
  19. package/dist/index.js.map +0 -1
  20. package/dist/optimizer/genalgo.d.ts +0 -104
  21. package/dist/optimizer/genalgo.d.ts.map +0 -1
  22. package/dist/optimizer/genalgo.test.d.ts +0 -2
  23. package/dist/optimizer/genalgo.test.d.ts.map +0 -1
  24. package/dist/optimizer/index-candidate.d.ts +0 -23
  25. package/dist/optimizer/index-candidate.d.ts.map +0 -1
  26. package/dist/optimizer/index-shrinker.d.ts +0 -10
  27. package/dist/optimizer/index-shrinker.d.ts.map +0 -1
  28. package/dist/optimizer/index-shrinker.test.d.ts +0 -2
  29. package/dist/optimizer/index-shrinker.test.d.ts.map +0 -1
  30. package/dist/optimizer/index-tester.d.ts +0 -2
  31. package/dist/optimizer/index-tester.d.ts.map +0 -1
  32. package/dist/optimizer/pss-rewriter.d.ts +0 -11
  33. package/dist/optimizer/pss-rewriter.d.ts.map +0 -1
  34. package/dist/optimizer/pss-rewriter.test.d.ts +0 -2
  35. package/dist/optimizer/pss-rewriter.test.d.ts.map +0 -1
  36. package/dist/optimizer/statistics.d.ts +0 -360
  37. package/dist/optimizer/statistics.d.ts.map +0 -1
  38. package/dist/sql/analyzer.d.ts +0 -105
  39. package/dist/sql/analyzer.d.ts.map +0 -1
  40. package/dist/sql/analyzer.test.d.ts +0 -2
  41. package/dist/sql/analyzer.test.d.ts.map +0 -1
  42. package/dist/sql/builder.d.ts +0 -31
  43. package/dist/sql/builder.d.ts.map +0 -1
  44. package/dist/sql/builder.test.d.ts +0 -2
  45. package/dist/sql/builder.test.d.ts.map +0 -1
  46. package/dist/sql/database.d.ts +0 -84
  47. package/dist/sql/database.d.ts.map +0 -1
  48. package/dist/sql/indexes.d.ts +0 -8
  49. package/dist/sql/indexes.d.ts.map +0 -1
  50. package/dist/sql/nudges.d.ts +0 -16
  51. package/dist/sql/nudges.d.ts.map +0 -1
  52. package/dist/sql/permutations.d.ts +0 -10
  53. package/dist/sql/permutations.d.ts.map +0 -1
  54. package/dist/sql/permutations.test.d.ts +0 -2
  55. package/dist/sql/permutations.test.d.ts.map +0 -1
  56. package/dist/sql/pg-identifier.d.ts +0 -26
  57. package/dist/sql/pg-identifier.d.ts.map +0 -1
  58. package/dist/sql/pg-identifier.test.d.ts +0 -2
  59. package/dist/sql/pg-identifier.test.d.ts.map +0 -1
  60. package/dist/sql/walker.d.ts +0 -46
  61. package/dist/sql/walker.d.ts.map +0 -1
  62. package/dist/sql/walker.test.d.ts +0 -2
  63. package/dist/sql/walker.test.d.ts.map +0 -1
@@ -0,0 +1,750 @@
1
+ 'use client';
2
+
3
+ import { Node, NullTestType, SortByDir, SortByNulls } from "@pgsql/types";
4
+ import { z } from "zod";
5
+
6
+ //#region src/sql/pg-identifier.d.ts
7
+ /**
8
+ * Represents an identifier in postgres that is subject
9
+ * to quoting rules. The {@link toString} rule behaves
10
+ * exactly like calling `select quote_ident($1)` in postgres
11
+ */
12
+ declare class PgIdentifier {
13
+ private readonly value;
14
+ private readonly quoted;
15
+ private constructor();
16
+ /**
17
+ * Constructs an identifier from a single part (column or table name).
18
+ * When quoting identifiers like `select table.col` use {@link fromParts} instead
19
+ */
20
+ static fromString(identifier: string): PgIdentifier;
21
+ /**
22
+ * Quotes parts of an identifier like `select schema.table.col`.
23
+ * A separate function is necessary because postgres will treat
24
+ * `select "HELLO.WORLD"` as a column name. It has to be like
25
+ * `select "HELLO"."WORLD"` instead.
26
+ */
27
+ static fromParts(...identifiers: (string | PgIdentifier)[]): PgIdentifier;
28
+ toString(): string;
29
+ toJSON(): string;
30
+ private static readonly reservedKeywords;
31
+ }
32
+ //#endregion
33
+ //#region src/sql/builder.d.ts
34
+ type PostgresQueryBuilderCommand = "bitmapscan" | "indexscan" | "seqscan";
35
+ declare class PostgresQueryBuilder {
36
+ private query;
37
+ private readonly commands;
38
+ private isIntrospection;
39
+ private explainFlags;
40
+ private _preamble;
41
+ private parameters;
42
+ private limitSubstitution?;
43
+ constructor(query: string);
44
+ get preamble(): number;
45
+ static createIndex(definition: string, name?: PgIdentifier): PostgresQueryBuilder;
46
+ enable(command: PostgresQueryBuilderCommand, value?: boolean): this;
47
+ withQuery(query: string): this;
48
+ introspect(): this;
49
+ explain(flags: string[]): this;
50
+ parameterize(parameters: Record<Parameter, number>): this;
51
+ replaceLimit(limit: number): this;
52
+ build(): string;
53
+ /** Return the "set a=b" parts of the command in the query separate from the explain select ... part */
54
+ buildParts(): {
55
+ commands: string;
56
+ query: string;
57
+ };
58
+ private generateSetCommands;
59
+ private generateExplain;
60
+ private substituteQuery;
61
+ }
62
+ type Parameter = `$${string}`;
63
+ //#endregion
64
+ //#region src/sql/database.d.ts
65
+ declare const PostgresVersion: z.core.$ZodBranded<z.ZodString, "PostgresVersion">;
66
+ type PostgresVersion = z.infer<typeof PostgresVersion>;
67
+ interface PostgresTransaction {
68
+ /**
69
+ * Exec a query and return the result as an array of objects.
70
+ */
71
+ exec<T>(query: string, params?: unknown[]): Promise<T[]>;
72
+ }
73
+ /**
74
+ * A shared interface for all postgres connections.
75
+ * This is required to allow interop between pglite and regular postgres drivers
76
+ */
77
+ interface Postgres extends PostgresTransaction {
78
+ transaction<T>(callback: (tx: PostgresTransaction) => Promise<T>): Promise<T>;
79
+ cursor?<T>(query: string, params?: unknown[], options?: {
80
+ size?: number;
81
+ }): AsyncGenerator<T, void, unknown>;
82
+ serverNum(): Promise<PostgresVersion>;
83
+ }
84
+ type PostgresConnectionInput = {
85
+ url: string;
86
+ };
87
+ type PostgresFactory = (input: PostgresConnectionInput) => Postgres;
88
+ declare const StageId: unique symbol;
89
+ type PostgresStageId = number & {
90
+ [StageId]: "StageId";
91
+ };
92
+ type PostgresStage = "Seq Scan" | "Limit" | "Bitmap Heap Scan" | "Bitmap Index Scan" | "Index Only Scan" | "Index Scan" | "BitmapOr";
93
+ type PostgresExplainStageCommon = {
94
+ "Node Type": PostgresStage;
95
+ "Node Id": PostgresStageId;
96
+ Plans?: PostgresExplainStage[];
97
+ "Plan Width": number;
98
+ "Total Cost": number;
99
+ };
100
+ type PostgresExplainStage = (PostgresExplainStageCommon & {
101
+ "Node Type": "Index Scan";
102
+ "Index Name": string;
103
+ "Relation Name": string;
104
+ Alias: string;
105
+ "Rows Removed by Filter": number;
106
+ }) | (PostgresExplainStageCommon & {
107
+ "Node Type": "Seq Scan";
108
+ "Relation Name": string;
109
+ Filter?: string;
110
+ "Actual Rows": number;
111
+ "Actual Loops": number;
112
+ "Rows Removed by Filter": number;
113
+ }) | (PostgresExplainStageCommon & {
114
+ "Node Type": "Bitmap Heap Scan";
115
+ "Relation Name": string;
116
+ Filter?: string;
117
+ "Actual Rows": number;
118
+ "Actual Loops": number;
119
+ "Rows Removed by Filter": number;
120
+ }) | (PostgresExplainStageCommon & {
121
+ "Node Type": "Bitmap Index Scan";
122
+ "Index Name": string;
123
+ Filter?: string;
124
+ "Actual Rows": number;
125
+ "Actual Loops": number;
126
+ "Rows Removed by Filter": number;
127
+ }) | (PostgresExplainStageCommon & {
128
+ "Node Type": "Index Only Scan";
129
+ "Index Name": string;
130
+ Filter?: string;
131
+ "Actual Rows": number;
132
+ "Actual Loops": number;
133
+ "Rows Removed by Filter": number;
134
+ }) | PostgresExplainStageCommon;
135
+ type PostgresExplainResult = {
136
+ "QUERY PLAN": {
137
+ Plan: PostgresExplainStage;
138
+ }[];
139
+ };
140
+ /**
141
+ * Drops a disabled index. Rollsback if it fails for any reason
142
+ * @returns Did dropping the index succeed?
143
+ */
144
+ declare function dropIndex(tx: PostgresTransaction, index: PgIdentifier): Promise<boolean>;
145
+ //#endregion
146
+ //#region src/optimizer/statistics.d.ts
147
+ type Path = string;
148
+ declare const StatisticsSource: z.ZodUnion<readonly [z.ZodObject<{
149
+ kind: z.ZodLiteral<"path">;
150
+ path: z.ZodString;
151
+ }, z.core.$strip>, z.ZodObject<{
152
+ kind: z.ZodLiteral<"inline">;
153
+ }, z.core.$strip>]>;
154
+ declare const ExportedStatsStatistics: z.ZodObject<{
155
+ stawidth: z.ZodNumber;
156
+ stainherit: z.ZodDefault<z.ZodBoolean>;
157
+ stadistinct: z.ZodNumber;
158
+ stanullfrac: z.ZodNumber;
159
+ stakind1: z.ZodNumber;
160
+ stakind2: z.ZodNumber;
161
+ stakind3: z.ZodNumber;
162
+ stakind4: z.ZodNumber;
163
+ stakind5: z.ZodNumber;
164
+ staop1: z.ZodString;
165
+ staop2: z.ZodString;
166
+ staop3: z.ZodString;
167
+ staop4: z.ZodString;
168
+ staop5: z.ZodString;
169
+ stacoll1: z.ZodString;
170
+ stacoll2: z.ZodString;
171
+ stacoll3: z.ZodString;
172
+ stacoll4: z.ZodString;
173
+ stacoll5: z.ZodString;
174
+ stanumbers1: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
175
+ stanumbers2: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
176
+ stanumbers3: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
177
+ stanumbers4: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
178
+ stanumbers5: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
179
+ stavalues1: z.ZodNullable<z.ZodArray<z.ZodAny>>;
180
+ stavalues2: z.ZodNullable<z.ZodArray<z.ZodAny>>;
181
+ stavalues3: z.ZodNullable<z.ZodArray<z.ZodAny>>;
182
+ stavalues4: z.ZodNullable<z.ZodArray<z.ZodAny>>;
183
+ stavalues5: z.ZodNullable<z.ZodArray<z.ZodAny>>;
184
+ }, z.core.$strip>;
185
+ declare const ExportedStatsColumns: z.ZodObject<{
186
+ columnName: z.ZodString;
187
+ stats: z.ZodNullable<z.ZodObject<{
188
+ stawidth: z.ZodNumber;
189
+ stainherit: z.ZodDefault<z.ZodBoolean>;
190
+ stadistinct: z.ZodNumber;
191
+ stanullfrac: z.ZodNumber;
192
+ stakind1: z.ZodNumber;
193
+ stakind2: z.ZodNumber;
194
+ stakind3: z.ZodNumber;
195
+ stakind4: z.ZodNumber;
196
+ stakind5: z.ZodNumber;
197
+ staop1: z.ZodString;
198
+ staop2: z.ZodString;
199
+ staop3: z.ZodString;
200
+ staop4: z.ZodString;
201
+ staop5: z.ZodString;
202
+ stacoll1: z.ZodString;
203
+ stacoll2: z.ZodString;
204
+ stacoll3: z.ZodString;
205
+ stacoll4: z.ZodString;
206
+ stacoll5: z.ZodString;
207
+ stanumbers1: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
208
+ stanumbers2: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
209
+ stanumbers3: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
210
+ stanumbers4: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
211
+ stanumbers5: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
212
+ stavalues1: z.ZodNullable<z.ZodArray<z.ZodAny>>;
213
+ stavalues2: z.ZodNullable<z.ZodArray<z.ZodAny>>;
214
+ stavalues3: z.ZodNullable<z.ZodArray<z.ZodAny>>;
215
+ stavalues4: z.ZodNullable<z.ZodArray<z.ZodAny>>;
216
+ stavalues5: z.ZodNullable<z.ZodArray<z.ZodAny>>;
217
+ }, z.core.$strip>>;
218
+ }, z.core.$strip>;
219
+ declare const ExportedStatsIndex: z.ZodObject<{
220
+ indexName: z.ZodString;
221
+ relpages: z.ZodNumber;
222
+ reltuples: z.ZodNumber;
223
+ relallvisible: z.ZodNumber;
224
+ relallfrozen: z.ZodOptional<z.ZodNumber>;
225
+ }, z.core.$strip>;
226
+ declare const ExportedStatsV1: z.ZodObject<{
227
+ tableName: z.ZodString;
228
+ schemaName: z.ZodString;
229
+ relpages: z.ZodNumber;
230
+ reltuples: z.ZodNumber;
231
+ relallvisible: z.ZodNumber;
232
+ relallfrozen: z.ZodOptional<z.ZodNumber>;
233
+ columns: z.ZodNullable<z.ZodArray<z.ZodObject<{
234
+ columnName: z.ZodString;
235
+ stats: z.ZodNullable<z.ZodObject<{
236
+ stawidth: z.ZodNumber;
237
+ stainherit: z.ZodDefault<z.ZodBoolean>;
238
+ stadistinct: z.ZodNumber;
239
+ stanullfrac: z.ZodNumber;
240
+ stakind1: z.ZodNumber;
241
+ stakind2: z.ZodNumber;
242
+ stakind3: z.ZodNumber;
243
+ stakind4: z.ZodNumber;
244
+ stakind5: z.ZodNumber;
245
+ staop1: z.ZodString;
246
+ staop2: z.ZodString;
247
+ staop3: z.ZodString;
248
+ staop4: z.ZodString;
249
+ staop5: z.ZodString;
250
+ stacoll1: z.ZodString;
251
+ stacoll2: z.ZodString;
252
+ stacoll3: z.ZodString;
253
+ stacoll4: z.ZodString;
254
+ stacoll5: z.ZodString;
255
+ stanumbers1: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
256
+ stanumbers2: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
257
+ stanumbers3: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
258
+ stanumbers4: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
259
+ stanumbers5: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
260
+ stavalues1: z.ZodNullable<z.ZodArray<z.ZodAny>>;
261
+ stavalues2: z.ZodNullable<z.ZodArray<z.ZodAny>>;
262
+ stavalues3: z.ZodNullable<z.ZodArray<z.ZodAny>>;
263
+ stavalues4: z.ZodNullable<z.ZodArray<z.ZodAny>>;
264
+ stavalues5: z.ZodNullable<z.ZodArray<z.ZodAny>>;
265
+ }, z.core.$strip>>;
266
+ }, z.core.$strip>>>;
267
+ indexes: z.ZodArray<z.ZodObject<{
268
+ indexName: z.ZodString;
269
+ relpages: z.ZodNumber;
270
+ reltuples: z.ZodNumber;
271
+ relallvisible: z.ZodNumber;
272
+ relallfrozen: z.ZodOptional<z.ZodNumber>;
273
+ }, z.core.$strip>>;
274
+ }, z.core.$strip>;
275
+ declare const ExportedStats: z.ZodUnion<readonly [z.ZodObject<{
276
+ tableName: z.ZodString;
277
+ schemaName: z.ZodString;
278
+ relpages: z.ZodNumber;
279
+ reltuples: z.ZodNumber;
280
+ relallvisible: z.ZodNumber;
281
+ relallfrozen: z.ZodOptional<z.ZodNumber>;
282
+ columns: z.ZodNullable<z.ZodArray<z.ZodObject<{
283
+ columnName: z.ZodString;
284
+ stats: z.ZodNullable<z.ZodObject<{
285
+ stawidth: z.ZodNumber;
286
+ stainherit: z.ZodDefault<z.ZodBoolean>;
287
+ stadistinct: z.ZodNumber;
288
+ stanullfrac: z.ZodNumber;
289
+ stakind1: z.ZodNumber;
290
+ stakind2: z.ZodNumber;
291
+ stakind3: z.ZodNumber;
292
+ stakind4: z.ZodNumber;
293
+ stakind5: z.ZodNumber;
294
+ staop1: z.ZodString;
295
+ staop2: z.ZodString;
296
+ staop3: z.ZodString;
297
+ staop4: z.ZodString;
298
+ staop5: z.ZodString;
299
+ stacoll1: z.ZodString;
300
+ stacoll2: z.ZodString;
301
+ stacoll3: z.ZodString;
302
+ stacoll4: z.ZodString;
303
+ stacoll5: z.ZodString;
304
+ stanumbers1: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
305
+ stanumbers2: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
306
+ stanumbers3: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
307
+ stanumbers4: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
308
+ stanumbers5: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
309
+ stavalues1: z.ZodNullable<z.ZodArray<z.ZodAny>>;
310
+ stavalues2: z.ZodNullable<z.ZodArray<z.ZodAny>>;
311
+ stavalues3: z.ZodNullable<z.ZodArray<z.ZodAny>>;
312
+ stavalues4: z.ZodNullable<z.ZodArray<z.ZodAny>>;
313
+ stavalues5: z.ZodNullable<z.ZodArray<z.ZodAny>>;
314
+ }, z.core.$strip>>;
315
+ }, z.core.$strip>>>;
316
+ indexes: z.ZodArray<z.ZodObject<{
317
+ indexName: z.ZodString;
318
+ relpages: z.ZodNumber;
319
+ reltuples: z.ZodNumber;
320
+ relallvisible: z.ZodNumber;
321
+ relallfrozen: z.ZodOptional<z.ZodNumber>;
322
+ }, z.core.$strip>>;
323
+ }, z.core.$strip>]>;
324
+ type ExportedStats = z.infer<typeof ExportedStats>;
325
+ declare const StatisticsMode: z.ZodDiscriminatedUnion<[z.ZodObject<{
326
+ kind: z.ZodLiteral<"fromAssumption">;
327
+ reltuples: z.ZodNumber;
328
+ relpages: z.ZodNumber;
329
+ }, z.core.$strip>, z.ZodObject<{
330
+ kind: z.ZodLiteral<"fromStatisticsExport">;
331
+ stats: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
332
+ tableName: z.ZodString;
333
+ schemaName: z.ZodString;
334
+ relpages: z.ZodNumber;
335
+ reltuples: z.ZodNumber;
336
+ relallvisible: z.ZodNumber;
337
+ relallfrozen: z.ZodOptional<z.ZodNumber>;
338
+ columns: z.ZodNullable<z.ZodArray<z.ZodObject<{
339
+ columnName: z.ZodString;
340
+ stats: z.ZodNullable<z.ZodObject<{
341
+ stawidth: z.ZodNumber;
342
+ stainherit: z.ZodDefault<z.ZodBoolean>;
343
+ stadistinct: z.ZodNumber;
344
+ stanullfrac: z.ZodNumber;
345
+ stakind1: z.ZodNumber;
346
+ stakind2: z.ZodNumber;
347
+ stakind3: z.ZodNumber;
348
+ stakind4: z.ZodNumber;
349
+ stakind5: z.ZodNumber;
350
+ staop1: z.ZodString;
351
+ staop2: z.ZodString;
352
+ staop3: z.ZodString;
353
+ staop4: z.ZodString;
354
+ staop5: z.ZodString;
355
+ stacoll1: z.ZodString;
356
+ stacoll2: z.ZodString;
357
+ stacoll3: z.ZodString;
358
+ stacoll4: z.ZodString;
359
+ stacoll5: z.ZodString;
360
+ stanumbers1: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
361
+ stanumbers2: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
362
+ stanumbers3: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
363
+ stanumbers4: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
364
+ stanumbers5: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
365
+ stavalues1: z.ZodNullable<z.ZodArray<z.ZodAny>>;
366
+ stavalues2: z.ZodNullable<z.ZodArray<z.ZodAny>>;
367
+ stavalues3: z.ZodNullable<z.ZodArray<z.ZodAny>>;
368
+ stavalues4: z.ZodNullable<z.ZodArray<z.ZodAny>>;
369
+ stavalues5: z.ZodNullable<z.ZodArray<z.ZodAny>>;
370
+ }, z.core.$strip>>;
371
+ }, z.core.$strip>>>;
372
+ indexes: z.ZodArray<z.ZodObject<{
373
+ indexName: z.ZodString;
374
+ relpages: z.ZodNumber;
375
+ reltuples: z.ZodNumber;
376
+ relallvisible: z.ZodNumber;
377
+ relallfrozen: z.ZodOptional<z.ZodNumber>;
378
+ }, z.core.$strip>>;
379
+ }, z.core.$strip>]>>;
380
+ source: z.ZodUnion<readonly [z.ZodObject<{
381
+ kind: z.ZodLiteral<"path">;
382
+ path: z.ZodString;
383
+ }, z.core.$strip>, z.ZodObject<{
384
+ kind: z.ZodLiteral<"inline">;
385
+ }, z.core.$strip>]>;
386
+ }, z.core.$strip>], "kind">;
387
+ type StatisticsMode = z.infer<typeof StatisticsMode>;
388
+ declare class Statistics {
389
+ private readonly db;
390
+ readonly postgresVersion: PostgresVersion;
391
+ readonly ownMetadata: ExportedStats[];
392
+ readonly mode: StatisticsMode;
393
+ private readonly exportedMetadata;
394
+ static readonly defaultStatsMode: StatisticsMode;
395
+ constructor(db: Postgres, postgresVersion: PostgresVersion, ownMetadata: ExportedStats[], statsMode: StatisticsMode);
396
+ static statsModeFromAssumption({
397
+ reltuples,
398
+ relpages
399
+ }: {
400
+ reltuples: number;
401
+ relpages: number;
402
+ }): StatisticsMode;
403
+ /**
404
+ * Create a statistic mode from stats exported from another database
405
+ **/
406
+ static statsModeFromExport(stats: ExportedStats[]): StatisticsMode;
407
+ static fromPostgres(db: Postgres, statsMode: StatisticsMode): Promise<Statistics>;
408
+ restoreStats(tx: PostgresTransaction): Promise<{
409
+ tablesNotInExports: string[];
410
+ tablesNotInTest: string[];
411
+ tableNotAnalyzed: string[];
412
+ statsMissing: {
413
+ statistic: string;
414
+ table: string;
415
+ schema: string;
416
+ column: string;
417
+ }[];
418
+ }>;
419
+ approximateTotalRows(): number;
420
+ /**
421
+ * We have to cast stavaluesN to the correct type
422
+ * This derives that type for us so it can be used in `array_in`
423
+ */
424
+ private stavalueKind;
425
+ /**
426
+ * PostgreSQL's anyarray columns in pg_statistic can hold arrays of arrays
427
+ * for columns with array types (e.g. text[], int4[]). These create
428
+ * multidimensional arrays that can be "ragged" (sub-arrays with different
429
+ * lengths). jsonb_to_recordset can't reconstruct ragged multidimensional
430
+ * arrays from JSON, so we need to drop these values.
431
+ */
432
+ private static safeStavalues;
433
+ private restoreStats17;
434
+ static dumpStats(db: PostgresTransaction, postgresVersion: PostgresVersion, kind: "anonymous" | "full"): Promise<ExportedStats[]>;
435
+ /**
436
+ * Returns all indexes in the database.
437
+ * ONLY handles regular btree indexes
438
+ */
439
+ getExistingIndexes(): Promise<IndexedTable[]>;
440
+ }
441
+ type ColumnMetadata = {
442
+ columnName: string;
443
+ dataType: string;
444
+ isNullable: boolean;
445
+ stats: ColumnStats | null;
446
+ };
447
+ type ColumnStats = {
448
+ stainherit: boolean;
449
+ stanullfrac: number;
450
+ stawidth: number;
451
+ stadistinct: number;
452
+ stakind1: number;
453
+ stakind2: number;
454
+ stakind3: number;
455
+ stakind4: number;
456
+ stakind5: number;
457
+ staop1: number;
458
+ staop2: number;
459
+ staop3: number;
460
+ staop4: number;
461
+ staop5: number;
462
+ stacoll1: number;
463
+ stacoll2: number;
464
+ stacoll3: number;
465
+ stacoll4: number;
466
+ stacoll5: number;
467
+ stanumbers1: number;
468
+ stanumbers2: number;
469
+ stanumbers3: number;
470
+ stanumbers4: number;
471
+ stanumbers5: number;
472
+ };
473
+ type TableMetadata = {
474
+ tableName: string;
475
+ schemaName: string;
476
+ reltuples: number;
477
+ relpages: number;
478
+ relallvisible: number;
479
+ relallfrozen?: number;
480
+ columns: ColumnMetadata[];
481
+ };
482
+ type TableName = string;
483
+ type TableStats = {
484
+ tupleEstimate: bigint;
485
+ pageCount: number;
486
+ };
487
+ type SerializeResult = {
488
+ schema: TableMetadata[];
489
+ serialized: string;
490
+ sampledRecords: Record<TableName, number>;
491
+ };
492
+ type IndexOrder = "ASC" | "DESC";
493
+ type IndexedTable = {
494
+ index_columns: Array<{
495
+ name: string;
496
+ order: IndexOrder;
497
+ opclass?: string;
498
+ }>;
499
+ is_primary: boolean;
500
+ is_unique: boolean;
501
+ index_name: string;
502
+ index_type: "btree" | "gin" | (string & {});
503
+ schema_name: string;
504
+ table_name: string;
505
+ };
506
+ //#endregion
507
+ //#region src/optimizer/genalgo.d.ts
508
+ type IndexIdentifier = string;
509
+ type IndexRecommendation = PermutedIndexCandidate & {
510
+ definition: IndexIdentifier;
511
+ };
512
+ declare class IndexOptimizer {
513
+ private readonly db;
514
+ private readonly statistics;
515
+ private existingIndexes;
516
+ private readonly config;
517
+ static prefix: string;
518
+ constructor(db: Postgres, statistics: Statistics, existingIndexes: IndexedTable[], config?: {
519
+ trace?: boolean;
520
+ debug?: boolean;
521
+ });
522
+ run(builder: PostgresQueryBuilder, indexes: RootIndexCandidate[], beforeQuery?: (tx: PostgresTransaction) => Promise<void>): Promise<OptimizeResult>;
523
+ runWithoutIndexes(builder: PostgresQueryBuilder): Promise<{
524
+ Plan: PostgresExplainStage;
525
+ }>;
526
+ /**
527
+ * Given the current indexes in the optimizer, transform them in some
528
+ * way to change which indexes will be assumed to exist when optimizing
529
+ *
530
+ * @example
531
+ * ```
532
+ * // resets indexes
533
+ * optimizer.transformIndexes(() => [])
534
+ *
535
+ * // adds new index
536
+ * optimizer.transformIndexes(indexes => [...indexes, newIndex])
537
+ * ```
538
+ */
539
+ transformIndexes(f: (indexes: IndexedTable[]) => IndexedTable[]): this;
540
+ /**
541
+ * Postgres has a limit of 63 characters for index names.
542
+ * So we use this to make sure we don't derive it from a list of columns that can
543
+ * overflow that limit.
544
+ */
545
+ private indexName;
546
+ private indexAlreadyExists;
547
+ /**
548
+ * Derive the list of indexes [tableA(X, Y, Z), tableB(H, I, J)]
549
+ **/
550
+ private indexesToCreate;
551
+ private toDefinition;
552
+ private toGinDefinition;
553
+ private groupGinCandidatesByColumn;
554
+ private ginIndexAlreadyExists;
555
+ /**
556
+ * Drop indexes that can be dropped. Ignore the ones that can't
557
+ */
558
+ private dropExistingIndexes;
559
+ private whereClause;
560
+ private nullsOrder;
561
+ private sortDirection;
562
+ testQueryWithStats(builder: PostgresQueryBuilder, f?: (tx: PostgresTransaction) => Promise<void>, options?: {
563
+ params?: unknown[];
564
+ genericPlan?: boolean;
565
+ }): Promise<{
566
+ Plan: PostgresExplainStage;
567
+ }>;
568
+ private groupPotentialIndexColumnsByTable;
569
+ private findUsedIndexes;
570
+ private replaceUsedIndexesWithDefinition;
571
+ }
572
+ type OptimizeResult = {
573
+ kind: "ok";
574
+ baseExplainPlan: PostgresExplainStage;
575
+ baseCost: number;
576
+ finalCost: number;
577
+ newIndexes: Set<string>;
578
+ existingIndexes: Set<string>;
579
+ triedIndexes: Map<string, IndexRecommendation>;
580
+ explainPlan: PostgresExplainStage;
581
+ } | {
582
+ kind: "zero_cost_plan";
583
+ explainPlan: PostgresExplainStage;
584
+ };
585
+ type RootIndexCandidate = {
586
+ schema: string;
587
+ table: string;
588
+ column: string;
589
+ sort?: SortContext;
590
+ where?: {
591
+ nulltest?: NullTestType;
592
+ };
593
+ jsonbOperator?: JsonbOperator;
594
+ };
595
+ type PermutedIndexCandidate = {
596
+ schema: string;
597
+ table: string;
598
+ columns: RootIndexCandidate[];
599
+ where?: string;
600
+ indexMethod?: "btree" | "gin";
601
+ opclass?: string;
602
+ };
603
+ declare const PROCEED: unique symbol;
604
+ declare const SKIP: unique symbol;
605
+ //#endregion
606
+ //#region src/sql/nudges.d.ts
607
+ type NudgeKind = "LARGE_IMPROVEMENT_FOUND" | "SMALL_IMPROVEMENT_FOUND" | "AVOID_SELECT_STAR" | "AVOID_FUNCTIONS_ON_COLUMNS_IN_WHERE" | "MISSING_WHERE_CLAUSE" | "MISSING_LIMIT_CLAUSE" | "USE_IS_NULL_NOT_EQUALS" | "AVOID_DISTINCT_WITHOUT_REASON" | "MISSING_JOIN_CONDITION" | "AVOID_LEADING_WILDCARD_LIKE" | "CONSIDER_IN_INSTEAD_OF_MANY_ORS" | "REPLACE_LARGE_IN_TUPLE_WITH_ANY_ARRAY" | "PREFER_NOT_EXISTS_OVER_NOT_IN";
608
+ type Nudge = {
609
+ kind: NudgeKind;
610
+ severity: "CRITICAL" | "WARNING" | "INFO";
611
+ message: string;
612
+ location?: number;
613
+ };
614
+ type KeysOfUnion<T> = T extends T ? keyof T : never;
615
+ /**
616
+ * Detect nudges for a single node during AST traversal.
617
+ * Returns an array of nudges found for this node.
618
+ */
619
+ declare function parseNudges(node: Node, stack: (KeysOfUnion<Node> | string)[]): Nudge[];
620
+ //#endregion
621
+ //#region src/sql/walker.d.ts
622
+ type ColumnReferencePart = {
623
+ schema?: string; /** the text of the column reference (excluding any potential quotes) */
624
+ text: string;
625
+ start?: number;
626
+ quoted: boolean;
627
+ alias?: string;
628
+ };
629
+ //#endregion
630
+ //#region src/sql/analyzer.d.ts
631
+ interface DatabaseDriver {
632
+ query(query: string, params: unknown[]): Promise<unknown[]>;
633
+ }
634
+ declare const ignoredIdentifier = "__qd_placeholder";
635
+ interface SQLCommenterTag {
636
+ key: string;
637
+ value: string;
638
+ }
639
+ type SortContext = {
640
+ dir: SortByDir;
641
+ nulls: SortByNulls;
642
+ };
643
+ type DiscoveredColumnReference = {
644
+ /** How often the column reference appears in the query. */frequency: number;
645
+ /**
646
+ * Representation of the column reference exactly
647
+ * as it appears in the query.
648
+ */
649
+ representation: string;
650
+ /**
651
+ * Parts of the column reference separated by dots in the query.
652
+ * The table reference (if it exists) is resolved if the query
653
+ * uses an alias.
654
+ *
655
+ * Has 3 different potential configurations (in theory)
656
+ * `a.b.c` - a column reference with a table and a schema reference
657
+ * `a.b` - a column reference with a table reference but no schema
658
+ * `a` - a column reference with no table reference.
659
+ *
660
+ * We use a simple array here to allow parsing of any syntactically correct
661
+ * but logically incorrect query. The checks happen later when we're deriving
662
+ * potential indexes from parts of a column reference in `deriveIndexes`
663
+ */
664
+ parts: ColumnReferencePart[];
665
+ /**
666
+ * Whether the column reference is invalid. This
667
+ */
668
+ ignored: boolean; /** The position of the column reference in the query. */
669
+ position: {
670
+ start: number;
671
+ end: number;
672
+ };
673
+ /**
674
+ * A sort direction associated by the column reference.
675
+ * Only relevant to references from sorts
676
+ */
677
+ sort?: SortContext;
678
+ where?: {
679
+ nulltest?: NullTestType;
680
+ };
681
+ jsonbOperator?: JsonbOperator;
682
+ };
683
+ type JsonbOperator = "@>" | "?" | "?|" | "?&";
684
+ /** A function defined by @pgsql/parser */
685
+ type Parser = (query: string) => Promise<unknown>;
686
+ type TableReference = {
687
+ schema?: string;
688
+ table: string;
689
+ };
690
+ type AnalysisResult = {
691
+ indexesToCheck: DiscoveredColumnReference[];
692
+ ansiHighlightedQuery: string;
693
+ referencedTables: TableReference[];
694
+ shadowedAliases: ColumnReferencePart[];
695
+ tags: SQLCommenterTag[];
696
+ queryWithoutTags: string;
697
+ formattedQueryWithoutTags?: string;
698
+ nudges: Nudge[];
699
+ };
700
+ type SQLCommenterExtraction = {
701
+ tags: SQLCommenterTag[];
702
+ queryWithoutTags: string;
703
+ };
704
+ /**
705
+ * Analyzes a query and returns a list of column references that
706
+ * should be indexed.
707
+ *
708
+ * This should be instantiated once per analyzed query.
709
+ */
710
+ declare class Analyzer {
711
+ private readonly parser;
712
+ constructor(parser: Parser);
713
+ analyze(query: string, formattedQuery?: string): Promise<AnalysisResult>;
714
+ deriveIndexes(tables: ExportedStats[], discovered: DiscoveredColumnReference[], referencedTables: TableReference[]): RootIndexCandidate[];
715
+ private filterReferences;
716
+ private hasColumn;
717
+ private colorizeKeywords;
718
+ /**
719
+ * Resolves aliases such as `a.b` to `x.b` if `a` is a known
720
+ * alias to a table called x.
721
+ *
722
+ * Ignores all other combination of parts such as `a.b.c`
723
+ */
724
+ private resolveTableAliases;
725
+ private normalize;
726
+ private extractSqlcommenter;
727
+ }
728
+ //#endregion
729
+ //#region src/sql/indexes.d.ts
730
+ declare function isIndexSupported(index: IndexedTable): boolean;
731
+ /**
732
+ * Doesn't necessarily decide whether the index can be dropped but can be
733
+ * used to not even try dropping indexes that _definitely_ cannot be dropped
734
+ */
735
+ declare function isIndexProbablyDroppable(index: IndexedTable): boolean;
736
+ //#endregion
737
+ //#region src/optimizer/pss-rewriter.d.ts
738
+ /**
739
+ * Rewriter for pg_stat_statements queries.
740
+ * Not all queries found in pg_stat_statements can be
741
+ * directly sent back to the database without first being rewritten.
742
+ */
743
+ declare class PssRewriter {
744
+ rewrite(query: string): string;
745
+ private rewriteKeywordWithParameter;
746
+ private problematicKeywords;
747
+ }
748
+ //#endregion
749
+ export { AnalysisResult, Analyzer, ColumnMetadata, DatabaseDriver, DiscoveredColumnReference, ExportedStats, ExportedStatsColumns, ExportedStatsIndex, ExportedStatsStatistics, ExportedStatsV1, IndexIdentifier, IndexOptimizer, IndexOrder, IndexRecommendation, IndexedTable, JsonbOperator, Nudge, OptimizeResult, PROCEED, Parameter, Parser, Path, PermutedIndexCandidate, PgIdentifier, Postgres, PostgresConnectionInput, PostgresExplainResult, PostgresExplainStage, PostgresExplainStageCommon, PostgresFactory, PostgresQueryBuilder, PostgresQueryBuilderCommand, PostgresStage, PostgresStageId, PostgresTransaction, PostgresVersion, PssRewriter, RootIndexCandidate, SKIP, SQLCommenterExtraction, SQLCommenterTag, SerializeResult, SortContext, Statistics, StatisticsMode, StatisticsSource, TableMetadata, TableReference, TableStats, dropIndex, ignoredIdentifier, isIndexProbablyDroppable, isIndexSupported, parseNudges };
750
+ //# sourceMappingURL=index.d.cts.map