postgresai 0.14.0-dev.49 → 0.14.0-dev.51
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/bin/postgres-ai.js +23 -4
- package/lib/checkup.ts +28 -0
- package/lib/metrics-loader.ts +7 -1
- package/package.json +1 -1
- package/test/checkup.test.ts +14 -0
- package/test/schema-validation.test.ts +4 -1
package/dist/bin/postgres-ai.js
CHANGED
|
@@ -13064,7 +13064,7 @@ var {
|
|
|
13064
13064
|
// package.json
|
|
13065
13065
|
var package_default = {
|
|
13066
13066
|
name: "postgresai",
|
|
13067
|
-
version: "0.14.0-dev.
|
|
13067
|
+
version: "0.14.0-dev.51",
|
|
13068
13068
|
description: "postgres_ai CLI",
|
|
13069
13069
|
license: "Apache-2.0",
|
|
13070
13070
|
private: false,
|
|
@@ -15881,7 +15881,7 @@ var Result = import_lib.default.Result;
|
|
|
15881
15881
|
var TypeOverrides = import_lib.default.TypeOverrides;
|
|
15882
15882
|
var defaults = import_lib.default.defaults;
|
|
15883
15883
|
// package.json
|
|
15884
|
-
var version = "0.14.0-dev.
|
|
15884
|
+
var version = "0.14.0-dev.51";
|
|
15885
15885
|
var package_default2 = {
|
|
15886
15886
|
name: "postgresai",
|
|
15887
15887
|
version,
|
|
@@ -24599,7 +24599,13 @@ redundant_indexes_tmp_num as (
|
|
|
24599
24599
|
formated_schema_name as tag_schema_name,
|
|
24600
24600
|
formated_table_name as tag_table_name,
|
|
24601
24601
|
formated_relation_name as tag_relation_name,
|
|
24602
|
-
supports_fk::int as supports_fk
|
|
24602
|
+
supports_fk::int as supports_fk,
|
|
24603
|
+
json_agg(
|
|
24604
|
+
distinct jsonb_build_object(
|
|
24605
|
+
'index_name', reason,
|
|
24606
|
+
'index_definition', main_index_def
|
|
24607
|
+
)
|
|
24608
|
+
)::text as covering_indexes_json
|
|
24603
24609
|
from redundant_indexes_cut_grouped
|
|
24604
24610
|
group by
|
|
24605
24611
|
index_id,
|
|
@@ -24911,6 +24917,17 @@ async function getRedundantIndexes(client) {
|
|
|
24911
24917
|
const transformed = transformMetricRow(row);
|
|
24912
24918
|
const indexSizeBytes = parseInt(String(transformed.index_size_bytes || 0), 10);
|
|
24913
24919
|
const tableSizeBytes = parseInt(String(transformed.table_size_bytes || 0), 10);
|
|
24920
|
+
let coveringIndexes = [];
|
|
24921
|
+
try {
|
|
24922
|
+
const jsonStr = String(transformed.covering_indexes_json || "[]");
|
|
24923
|
+
const parsed = JSON.parse(jsonStr);
|
|
24924
|
+
if (Array.isArray(parsed)) {
|
|
24925
|
+
coveringIndexes = parsed.map((item) => ({
|
|
24926
|
+
index_name: String(item.index_name || ""),
|
|
24927
|
+
index_definition: String(item.index_definition || "")
|
|
24928
|
+
}));
|
|
24929
|
+
}
|
|
24930
|
+
} catch {}
|
|
24914
24931
|
return {
|
|
24915
24932
|
schema_name: String(transformed.schema_name || ""),
|
|
24916
24933
|
table_name: String(transformed.table_name || ""),
|
|
@@ -24924,7 +24941,8 @@ async function getRedundantIndexes(client) {
|
|
|
24924
24941
|
supports_fk: transformed.supports_fk === true || transformed.supports_fk === 1,
|
|
24925
24942
|
index_definition: String(transformed.index_definition || ""),
|
|
24926
24943
|
index_size_pretty: formatBytes(indexSizeBytes),
|
|
24927
|
-
table_size_pretty: formatBytes(tableSizeBytes)
|
|
24944
|
+
table_size_pretty: formatBytes(tableSizeBytes),
|
|
24945
|
+
covering_indexes: coveringIndexes
|
|
24928
24946
|
};
|
|
24929
24947
|
});
|
|
24930
24948
|
}
|
|
@@ -24933,6 +24951,7 @@ function createBaseReport(checkId, checkTitle, nodeName) {
|
|
|
24933
24951
|
return {
|
|
24934
24952
|
version: version || null,
|
|
24935
24953
|
build_ts: buildTs,
|
|
24954
|
+
generation_mode: "express",
|
|
24936
24955
|
checkId,
|
|
24937
24956
|
checkTitle,
|
|
24938
24957
|
timestamptz: new Date().toISOString(),
|
package/lib/checkup.ts
CHANGED
|
@@ -127,6 +127,14 @@ export interface StatsReset {
|
|
|
127
127
|
/**
|
|
128
128
|
* Redundant index entry (H004) - matches H004.schema.json redundantIndex
|
|
129
129
|
*/
|
|
130
|
+
/**
|
|
131
|
+
* Covering index definition (the index that makes another index redundant)
|
|
132
|
+
*/
|
|
133
|
+
export interface CoveringIndex {
|
|
134
|
+
index_name: string;
|
|
135
|
+
index_definition: string;
|
|
136
|
+
}
|
|
137
|
+
|
|
130
138
|
export interface RedundantIndex {
|
|
131
139
|
schema_name: string;
|
|
132
140
|
table_name: string;
|
|
@@ -141,6 +149,7 @@ export interface RedundantIndex {
|
|
|
141
149
|
index_definition: string;
|
|
142
150
|
index_size_pretty: string;
|
|
143
151
|
table_size_pretty: string;
|
|
152
|
+
covering_indexes: CoveringIndex[];
|
|
144
153
|
}
|
|
145
154
|
|
|
146
155
|
/**
|
|
@@ -157,6 +166,7 @@ export interface NodeResult {
|
|
|
157
166
|
export interface Report {
|
|
158
167
|
version: string | null;
|
|
159
168
|
build_ts: string | null;
|
|
169
|
+
generation_mode: string | null;
|
|
160
170
|
checkId: string;
|
|
161
171
|
checkTitle: string;
|
|
162
172
|
timestamptz: string;
|
|
@@ -516,6 +526,22 @@ export async function getRedundantIndexes(client: Client): Promise<RedundantInde
|
|
|
516
526
|
const transformed = transformMetricRow(row);
|
|
517
527
|
const indexSizeBytes = parseInt(String(transformed.index_size_bytes || 0), 10);
|
|
518
528
|
const tableSizeBytes = parseInt(String(transformed.table_size_bytes || 0), 10);
|
|
529
|
+
|
|
530
|
+
// Parse covering_indexes JSON array
|
|
531
|
+
let coveringIndexes: CoveringIndex[] = [];
|
|
532
|
+
try {
|
|
533
|
+
const jsonStr = String(transformed.covering_indexes_json || "[]");
|
|
534
|
+
const parsed = JSON.parse(jsonStr);
|
|
535
|
+
if (Array.isArray(parsed)) {
|
|
536
|
+
coveringIndexes = parsed.map((item: any) => ({
|
|
537
|
+
index_name: String(item.index_name || ""),
|
|
538
|
+
index_definition: String(item.index_definition || ""),
|
|
539
|
+
}));
|
|
540
|
+
}
|
|
541
|
+
} catch {
|
|
542
|
+
// If JSON parsing fails, leave as empty array
|
|
543
|
+
}
|
|
544
|
+
|
|
519
545
|
return {
|
|
520
546
|
schema_name: String(transformed.schema_name || ""),
|
|
521
547
|
table_name: String(transformed.table_name || ""),
|
|
@@ -530,6 +556,7 @@ export async function getRedundantIndexes(client: Client): Promise<RedundantInde
|
|
|
530
556
|
index_definition: String(transformed.index_definition || ""),
|
|
531
557
|
index_size_pretty: formatBytes(indexSizeBytes),
|
|
532
558
|
table_size_pretty: formatBytes(tableSizeBytes),
|
|
559
|
+
covering_indexes: coveringIndexes,
|
|
533
560
|
};
|
|
534
561
|
});
|
|
535
562
|
}
|
|
@@ -546,6 +573,7 @@ export function createBaseReport(
|
|
|
546
573
|
return {
|
|
547
574
|
version: pkg.version || null,
|
|
548
575
|
build_ts: buildTs,
|
|
576
|
+
generation_mode: "express",
|
|
549
577
|
checkId,
|
|
550
578
|
checkTitle,
|
|
551
579
|
timestamptz: new Date().toISOString(),
|
package/lib/metrics-loader.ts
CHANGED
|
@@ -418,7 +418,13 @@ redundant_indexes_tmp_num as (
|
|
|
418
418
|
formated_schema_name as tag_schema_name,
|
|
419
419
|
formated_table_name as tag_table_name,
|
|
420
420
|
formated_relation_name as tag_relation_name,
|
|
421
|
-
supports_fk::int as supports_fk
|
|
421
|
+
supports_fk::int as supports_fk,
|
|
422
|
+
json_agg(
|
|
423
|
+
distinct jsonb_build_object(
|
|
424
|
+
'index_name', reason,
|
|
425
|
+
'index_definition', main_index_def
|
|
426
|
+
)
|
|
427
|
+
)::text as covering_indexes_json
|
|
422
428
|
from redundant_indexes_cut_grouped
|
|
423
429
|
group by
|
|
424
430
|
index_id,
|
package/package.json
CHANGED
package/test/checkup.test.ts
CHANGED
|
@@ -840,6 +840,9 @@ describe("H004 - Redundant indexes", () => {
|
|
|
840
840
|
index_usage: "0",
|
|
841
841
|
supports_fk: false,
|
|
842
842
|
index_definition: "CREATE INDEX orders_user_id_idx ON public.orders USING btree (user_id)",
|
|
843
|
+
covering_indexes_json: JSON.stringify([
|
|
844
|
+
{ index_name: "public.orders_user_id_created_idx", index_definition: "CREATE INDEX orders_user_id_created_idx ON public.orders USING btree (user_id, created_at)" }
|
|
845
|
+
]),
|
|
843
846
|
},
|
|
844
847
|
],
|
|
845
848
|
});
|
|
@@ -853,6 +856,11 @@ describe("H004 - Redundant indexes", () => {
|
|
|
853
856
|
expect(indexes[0].supports_fk).toBe(false);
|
|
854
857
|
expect(indexes[0].index_definition).toBeTruthy();
|
|
855
858
|
expect(indexes[0].relation_name).toBe("orders");
|
|
859
|
+
// Verify covering_indexes is populated with definitions
|
|
860
|
+
expect(indexes[0].covering_indexes).toBeInstanceOf(Array);
|
|
861
|
+
expect(indexes[0].covering_indexes.length).toBe(1);
|
|
862
|
+
expect(indexes[0].covering_indexes[0].index_name).toBe("public.orders_user_id_created_idx");
|
|
863
|
+
expect(indexes[0].covering_indexes[0].index_definition).toContain("CREATE INDEX");
|
|
856
864
|
});
|
|
857
865
|
|
|
858
866
|
test("generateH004 creates report with redundant indexes", async () => {
|
|
@@ -876,6 +884,9 @@ describe("H004 - Redundant indexes", () => {
|
|
|
876
884
|
index_usage: "5",
|
|
877
885
|
supports_fk: false,
|
|
878
886
|
index_definition: "CREATE INDEX products_category_idx ON public.products USING btree (category)",
|
|
887
|
+
covering_indexes_json: JSON.stringify([
|
|
888
|
+
{ index_name: "public.products_category_name_idx", index_definition: "CREATE INDEX products_category_name_idx ON public.products USING btree (category, name)" }
|
|
889
|
+
]),
|
|
879
890
|
},
|
|
880
891
|
],
|
|
881
892
|
}
|
|
@@ -919,6 +930,9 @@ describe("H004 - Redundant indexes", () => {
|
|
|
919
930
|
index_usage: "5",
|
|
920
931
|
supports_fk: false,
|
|
921
932
|
index_definition: "CREATE INDEX products_category_idx ON public.products USING btree (category)",
|
|
933
|
+
covering_indexes_json: JSON.stringify([
|
|
934
|
+
{ index_name: "public.products_category_name_idx", index_definition: "CREATE INDEX products_category_name_idx ON public.products USING btree (category, name)" }
|
|
935
|
+
]),
|
|
922
936
|
},
|
|
923
937
|
],
|
|
924
938
|
}
|
|
@@ -202,7 +202,10 @@ describe("H004 schema validation", () => {
|
|
|
202
202
|
table_size_bytes: "16777216",
|
|
203
203
|
index_usage: "0",
|
|
204
204
|
supports_fk: false,
|
|
205
|
-
index_definition: "CREATE INDEX orders_user_id_idx ON public.orders USING btree (user_id)"
|
|
205
|
+
index_definition: "CREATE INDEX orders_user_id_idx ON public.orders USING btree (user_id)",
|
|
206
|
+
covering_indexes_json: JSON.stringify([
|
|
207
|
+
{ index_name: "public.orders_user_id_created_idx", index_definition: "CREATE INDEX orders_user_id_created_idx ON public.orders USING btree (user_id, created_at)" }
|
|
208
|
+
])
|
|
206
209
|
},
|
|
207
210
|
],
|
|
208
211
|
});
|