@neverinfamous/postgres-mcp 2.0.0 → 2.2.0
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/LICENSE +1 -1
- package/README.md +119 -46
- package/dist/__tests__/benchmarks/codemode.bench.js +3 -3
- package/dist/__tests__/benchmarks/codemode.bench.js.map +1 -1
- package/dist/__tests__/benchmarks/connection-pool.bench.js +3 -3
- package/dist/__tests__/benchmarks/connection-pool.bench.js.map +1 -1
- package/dist/__tests__/benchmarks/introspection-migration.bench.d.ts +11 -0
- package/dist/__tests__/benchmarks/introspection-migration.bench.d.ts.map +1 -0
- package/dist/__tests__/benchmarks/introspection-migration.bench.js +143 -0
- package/dist/__tests__/benchmarks/introspection-migration.bench.js.map +1 -0
- package/dist/__tests__/benchmarks/resource-prompts.bench.js +0 -64
- package/dist/__tests__/benchmarks/resource-prompts.bench.js.map +1 -1
- package/dist/__tests__/benchmarks/schema-parsing.bench.js +5 -5
- package/dist/__tests__/benchmarks/schema-parsing.bench.js.map +1 -1
- package/dist/__tests__/benchmarks/tool-filtering.bench.js +17 -8
- package/dist/__tests__/benchmarks/tool-filtering.bench.js.map +1 -1
- package/dist/__tests__/mocks/adapter.d.ts.map +1 -1
- package/dist/__tests__/mocks/adapter.js +2 -1
- package/dist/__tests__/mocks/adapter.js.map +1 -1
- package/dist/adapters/DatabaseAdapter.d.ts +6 -5
- package/dist/adapters/DatabaseAdapter.d.ts.map +1 -1
- package/dist/adapters/DatabaseAdapter.js +11 -20
- package/dist/adapters/DatabaseAdapter.js.map +1 -1
- package/dist/adapters/postgresql/PostgresAdapter.d.ts +5 -26
- package/dist/adapters/postgresql/PostgresAdapter.d.ts.map +1 -1
- package/dist/adapters/postgresql/PostgresAdapter.js +31 -526
- package/dist/adapters/postgresql/PostgresAdapter.js.map +1 -1
- package/dist/adapters/postgresql/prompts/index.js +1 -1
- package/dist/adapters/postgresql/prompts/index.js.map +1 -1
- package/dist/adapters/postgresql/resources/index.d.ts +1 -1
- package/dist/adapters/postgresql/resources/index.js +3 -3
- package/dist/adapters/postgresql/resources/index.js.map +1 -1
- package/dist/adapters/postgresql/schema-operations.d.ts +71 -0
- package/dist/adapters/postgresql/schema-operations.d.ts.map +1 -0
- package/dist/adapters/postgresql/schema-operations.js +561 -0
- package/dist/adapters/postgresql/schema-operations.js.map +1 -0
- package/dist/adapters/postgresql/schemas/admin.d.ts +4 -4
- package/dist/adapters/postgresql/schemas/admin.js +4 -4
- package/dist/adapters/postgresql/schemas/admin.js.map +1 -1
- package/dist/adapters/postgresql/schemas/backup.d.ts +2 -2
- package/dist/adapters/postgresql/schemas/backup.d.ts.map +1 -1
- package/dist/adapters/postgresql/schemas/backup.js +1 -3
- package/dist/adapters/postgresql/schemas/backup.js.map +1 -1
- package/dist/adapters/postgresql/schemas/core/index.d.ts +6 -0
- package/dist/adapters/postgresql/schemas/core/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/core/index.js +6 -0
- package/dist/adapters/postgresql/schemas/core/index.js.map +1 -0
- package/dist/adapters/postgresql/schemas/{core.d.ts → core/queries.d.ts} +16 -171
- package/dist/adapters/postgresql/schemas/core/queries.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/{core.js → core/queries.js} +5 -213
- package/dist/adapters/postgresql/schemas/core/queries.js.map +1 -0
- package/dist/adapters/postgresql/schemas/core/transactions.d.ts +149 -0
- package/dist/adapters/postgresql/schemas/core/transactions.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/core/transactions.js +239 -0
- package/dist/adapters/postgresql/schemas/core/transactions.js.map +1 -0
- package/dist/adapters/postgresql/schemas/cron.d.ts +12 -12
- package/dist/adapters/postgresql/schemas/cron.d.ts.map +1 -1
- package/dist/adapters/postgresql/schemas/cron.js +38 -10
- package/dist/adapters/postgresql/schemas/cron.js.map +1 -1
- package/dist/adapters/postgresql/schemas/extensions/citext.d.ts +222 -0
- package/dist/adapters/postgresql/schemas/extensions/citext.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/extensions/citext.js +306 -0
- package/dist/adapters/postgresql/schemas/extensions/citext.js.map +1 -0
- package/dist/adapters/postgresql/schemas/extensions/index.d.ts +15 -0
- package/dist/adapters/postgresql/schemas/extensions/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/extensions/index.js +20 -0
- package/dist/adapters/postgresql/schemas/extensions/index.js.map +1 -0
- package/dist/adapters/postgresql/schemas/extensions/kcache.d.ts +164 -0
- package/dist/adapters/postgresql/schemas/extensions/kcache.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/extensions/kcache.js +225 -0
- package/dist/adapters/postgresql/schemas/extensions/kcache.js.map +1 -0
- package/dist/adapters/postgresql/schemas/extensions/ltree.d.ts +253 -0
- package/dist/adapters/postgresql/schemas/extensions/ltree.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/extensions/ltree.js +430 -0
- package/dist/adapters/postgresql/schemas/extensions/ltree.js.map +1 -0
- package/dist/adapters/postgresql/schemas/extensions/pgcrypto.d.ts +251 -0
- package/dist/adapters/postgresql/schemas/extensions/pgcrypto.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/extensions/pgcrypto.js +294 -0
- package/dist/adapters/postgresql/schemas/extensions/pgcrypto.js.map +1 -0
- package/dist/adapters/postgresql/schemas/extensions/shared.d.ts +10 -0
- package/dist/adapters/postgresql/schemas/extensions/shared.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/extensions/shared.js +15 -0
- package/dist/adapters/postgresql/schemas/extensions/shared.js.map +1 -0
- package/dist/adapters/postgresql/schemas/index.d.ts +6 -6
- package/dist/adapters/postgresql/schemas/index.d.ts.map +1 -1
- package/dist/adapters/postgresql/schemas/index.js +8 -8
- package/dist/adapters/postgresql/schemas/index.js.map +1 -1
- package/dist/adapters/postgresql/schemas/introspection.d.ts +19 -42
- package/dist/adapters/postgresql/schemas/introspection.d.ts.map +1 -1
- package/dist/adapters/postgresql/schemas/introspection.js +72 -27
- package/dist/adapters/postgresql/schemas/introspection.js.map +1 -1
- package/dist/adapters/postgresql/schemas/jsonb/advanced.d.ts +270 -0
- package/dist/adapters/postgresql/schemas/jsonb/advanced.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/jsonb/advanced.js +371 -0
- package/dist/adapters/postgresql/schemas/jsonb/advanced.js.map +1 -0
- package/dist/adapters/postgresql/schemas/jsonb/basic.d.ts +283 -0
- package/dist/adapters/postgresql/schemas/jsonb/basic.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/jsonb/basic.js +456 -0
- package/dist/adapters/postgresql/schemas/jsonb/basic.js.map +1 -0
- package/dist/adapters/postgresql/schemas/jsonb/index.d.ts +6 -0
- package/dist/adapters/postgresql/schemas/jsonb/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/jsonb/index.js +6 -0
- package/dist/adapters/postgresql/schemas/jsonb/index.js.map +1 -0
- package/dist/adapters/postgresql/schemas/monitoring.d.ts +4 -4
- package/dist/adapters/postgresql/schemas/monitoring.js +2 -2
- package/dist/adapters/postgresql/schemas/monitoring.js.map +1 -1
- package/dist/adapters/postgresql/schemas/partitioning.d.ts +14 -14
- package/dist/adapters/postgresql/schemas/partitioning.d.ts.map +1 -1
- package/dist/adapters/postgresql/schemas/partitioning.js +64 -46
- package/dist/adapters/postgresql/schemas/partitioning.js.map +1 -1
- package/dist/adapters/postgresql/schemas/partman.d.ts +16 -14
- package/dist/adapters/postgresql/schemas/partman.d.ts.map +1 -1
- package/dist/adapters/postgresql/schemas/partman.js +9 -9
- package/dist/adapters/postgresql/schemas/partman.js.map +1 -1
- package/dist/adapters/postgresql/schemas/postgis/advanced.d.ts +429 -0
- package/dist/adapters/postgresql/schemas/postgis/advanced.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/postgis/advanced.js +495 -0
- package/dist/adapters/postgresql/schemas/postgis/advanced.js.map +1 -0
- package/dist/adapters/postgresql/schemas/{postgis.d.ts → postgis/basic.d.ts} +1 -423
- package/dist/adapters/postgresql/schemas/postgis/basic.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/{postgis.js → postgis/basic.js} +1 -486
- package/dist/adapters/postgresql/schemas/postgis/basic.js.map +1 -0
- package/dist/adapters/postgresql/schemas/postgis/index.d.ts +6 -0
- package/dist/adapters/postgresql/schemas/postgis/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/postgis/index.js +6 -0
- package/dist/adapters/postgresql/schemas/postgis/index.js.map +1 -0
- package/dist/adapters/postgresql/schemas/schema-mgmt.d.ts +35 -25
- package/dist/adapters/postgresql/schemas/schema-mgmt.d.ts.map +1 -1
- package/dist/adapters/postgresql/schemas/schema-mgmt.js +57 -19
- package/dist/adapters/postgresql/schemas/schema-mgmt.js.map +1 -1
- package/dist/adapters/postgresql/schemas/stats/index.d.ts +6 -0
- package/dist/adapters/postgresql/schemas/stats/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/stats/index.js +6 -0
- package/dist/adapters/postgresql/schemas/stats/index.js.map +1 -0
- package/dist/adapters/postgresql/schemas/stats/input.d.ts +260 -0
- package/dist/adapters/postgresql/schemas/stats/input.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/{stats.js → stats/input.js} +2 -331
- package/dist/adapters/postgresql/schemas/stats/input.js.map +1 -0
- package/dist/adapters/postgresql/schemas/{stats.d.ts → stats/output.d.ts} +3 -246
- package/dist/adapters/postgresql/schemas/stats/output.d.ts.map +1 -0
- package/dist/adapters/postgresql/schemas/stats/output.js +334 -0
- package/dist/adapters/postgresql/schemas/stats/output.js.map +1 -0
- package/dist/adapters/postgresql/schemas/text-search.d.ts +18 -18
- package/dist/adapters/postgresql/schemas/text-search.d.ts.map +1 -1
- package/dist/adapters/postgresql/schemas/text-search.js +12 -27
- package/dist/adapters/postgresql/schemas/text-search.js.map +1 -1
- package/dist/adapters/postgresql/schemas/vector.d.ts +10 -10
- package/dist/adapters/postgresql/schemas/vector.d.ts.map +1 -1
- package/dist/adapters/postgresql/schemas/vector.js +9 -15
- package/dist/adapters/postgresql/schemas/vector.js.map +1 -1
- package/dist/adapters/postgresql/tools/backup/dump.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/backup/dump.js +95 -76
- package/dist/adapters/postgresql/tools/backup/dump.js.map +1 -1
- package/dist/adapters/postgresql/tools/backup/planning.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/backup/planning.js +345 -287
- package/dist/adapters/postgresql/tools/backup/planning.js.map +1 -1
- package/dist/adapters/postgresql/tools/citext/analysis.d.ts +24 -0
- package/dist/adapters/postgresql/tools/citext/analysis.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/{citext.js → citext/analysis.js} +50 -232
- package/dist/adapters/postgresql/tools/citext/analysis.js.map +1 -0
- package/dist/adapters/postgresql/tools/citext/index.d.ts +15 -0
- package/dist/adapters/postgresql/tools/citext/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/citext/index.js +23 -0
- package/dist/adapters/postgresql/tools/citext/index.js.map +1 -0
- package/dist/adapters/postgresql/tools/citext/setup.d.ts +16 -0
- package/dist/adapters/postgresql/tools/citext/setup.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/citext/setup.js +193 -0
- package/dist/adapters/postgresql/tools/citext/setup.js.map +1 -0
- package/dist/adapters/postgresql/tools/codemode/index.js +1 -1
- package/dist/adapters/postgresql/tools/codemode/index.js.map +1 -1
- package/dist/adapters/postgresql/tools/core/convenience.d.ts +12 -22
- package/dist/adapters/postgresql/tools/core/convenience.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/core/convenience.js +100 -210
- package/dist/adapters/postgresql/tools/core/convenience.js.map +1 -1
- package/dist/adapters/postgresql/tools/core/error-helpers.d.ts +1 -0
- package/dist/adapters/postgresql/tools/core/error-helpers.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/core/error-helpers.js +8 -1
- package/dist/adapters/postgresql/tools/core/error-helpers.js.map +1 -1
- package/dist/adapters/postgresql/tools/core/health.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/core/health.js +124 -114
- package/dist/adapters/postgresql/tools/core/health.js.map +1 -1
- package/dist/adapters/postgresql/tools/core/index.d.ts +2 -1
- package/dist/adapters/postgresql/tools/core/index.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/core/index.js +3 -2
- package/dist/adapters/postgresql/tools/core/index.js.map +1 -1
- package/dist/adapters/postgresql/tools/core/indexes.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/core/indexes.js +151 -127
- package/dist/adapters/postgresql/tools/core/indexes.js.map +1 -1
- package/dist/adapters/postgresql/tools/core/objects.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/core/objects.js +186 -161
- package/dist/adapters/postgresql/tools/core/objects.js.map +1 -1
- package/dist/adapters/postgresql/tools/core/query.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/core/query.js +37 -25
- package/dist/adapters/postgresql/tools/core/query.js.map +1 -1
- package/dist/adapters/postgresql/tools/core/schemas.d.ts +6 -3
- package/dist/adapters/postgresql/tools/core/schemas.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/core/schemas.js +11 -2
- package/dist/adapters/postgresql/tools/core/schemas.js.map +1 -1
- package/dist/adapters/postgresql/tools/core/tables.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/core/tables.js +156 -129
- package/dist/adapters/postgresql/tools/core/tables.js.map +1 -1
- package/dist/adapters/postgresql/tools/core/utility.d.ts +26 -0
- package/dist/adapters/postgresql/tools/core/utility.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/core/utility.js +174 -0
- package/dist/adapters/postgresql/tools/core/utility.js.map +1 -0
- package/dist/adapters/postgresql/tools/cron.js +90 -43
- package/dist/adapters/postgresql/tools/cron.js.map +1 -1
- package/dist/adapters/postgresql/tools/introspection/analysis.d.ts +12 -0
- package/dist/adapters/postgresql/tools/introspection/analysis.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/introspection/analysis.js +605 -0
- package/dist/adapters/postgresql/tools/introspection/analysis.js.map +1 -0
- package/dist/adapters/postgresql/tools/introspection/graph.d.ts +55 -0
- package/dist/adapters/postgresql/tools/introspection/graph.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/introspection/graph.js +621 -0
- package/dist/adapters/postgresql/tools/introspection/graph.js.map +1 -0
- package/dist/adapters/postgresql/tools/introspection/index.d.ts +21 -0
- package/dist/adapters/postgresql/tools/introspection/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/introspection/index.js +31 -0
- package/dist/adapters/postgresql/tools/introspection/index.js.map +1 -0
- package/dist/adapters/postgresql/tools/introspection/migration.d.ts +15 -0
- package/dist/adapters/postgresql/tools/introspection/migration.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/introspection/migration.js +575 -0
- package/dist/adapters/postgresql/tools/introspection/migration.js.map +1 -0
- package/dist/adapters/postgresql/tools/jsonb/analytics.d.ts +20 -0
- package/dist/adapters/postgresql/tools/jsonb/analytics.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/jsonb/analytics.js +367 -0
- package/dist/adapters/postgresql/tools/jsonb/analytics.js.map +1 -0
- package/dist/adapters/postgresql/tools/jsonb/index.d.ts +4 -2
- package/dist/adapters/postgresql/tools/jsonb/index.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/jsonb/index.js +8 -4
- package/dist/adapters/postgresql/tools/jsonb/index.js.map +1 -1
- package/dist/adapters/postgresql/tools/jsonb/read.d.ts +38 -0
- package/dist/adapters/postgresql/tools/jsonb/read.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/jsonb/{basic.js → read.js} +41 -482
- package/dist/adapters/postgresql/tools/jsonb/read.js.map +1 -0
- package/dist/adapters/postgresql/tools/jsonb/{advanced.d.ts → transform.d.ts} +1 -13
- package/dist/adapters/postgresql/tools/jsonb/transform.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/jsonb/{advanced.js → transform.js} +26 -357
- package/dist/adapters/postgresql/tools/jsonb/transform.js.map +1 -0
- package/dist/adapters/postgresql/tools/jsonb/write.d.ts +14 -0
- package/dist/adapters/postgresql/tools/jsonb/write.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/jsonb/write.js +468 -0
- package/dist/adapters/postgresql/tools/jsonb/write.js.map +1 -0
- package/dist/adapters/postgresql/tools/kcache.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/kcache.js +116 -51
- package/dist/adapters/postgresql/tools/kcache.js.map +1 -1
- package/dist/adapters/postgresql/tools/ltree.js +346 -260
- package/dist/adapters/postgresql/tools/ltree.js.map +1 -1
- package/dist/adapters/postgresql/tools/migration/index.d.ts +15 -0
- package/dist/adapters/postgresql/tools/migration/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/migration/index.js +23 -0
- package/dist/adapters/postgresql/tools/migration/index.js.map +1 -0
- package/dist/adapters/postgresql/tools/monitoring/analysis.d.ts +15 -0
- package/dist/adapters/postgresql/tools/monitoring/analysis.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/{monitoring.js → monitoring/analysis.js} +24 -359
- package/dist/adapters/postgresql/tools/monitoring/analysis.js.map +1 -0
- package/dist/adapters/postgresql/tools/monitoring/basic.d.ts +17 -0
- package/dist/adapters/postgresql/tools/monitoring/basic.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/monitoring/basic.js +432 -0
- package/dist/adapters/postgresql/tools/monitoring/basic.js.map +1 -0
- package/dist/adapters/postgresql/tools/monitoring/index.d.ts +16 -0
- package/dist/adapters/postgresql/tools/monitoring/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/monitoring/index.js +31 -0
- package/dist/adapters/postgresql/tools/monitoring/index.js.map +1 -0
- package/dist/adapters/postgresql/tools/partitioning/index.d.ts +15 -0
- package/dist/adapters/postgresql/tools/partitioning/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/partitioning/index.js +23 -0
- package/dist/adapters/postgresql/tools/partitioning/index.js.map +1 -0
- package/dist/adapters/postgresql/tools/partitioning/info.d.ts +11 -0
- package/dist/adapters/postgresql/tools/partitioning/info.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/partitioning/info.js +302 -0
- package/dist/adapters/postgresql/tools/partitioning/info.js.map +1 -0
- package/dist/adapters/postgresql/tools/partitioning/management.d.ts +28 -0
- package/dist/adapters/postgresql/tools/partitioning/management.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/{partitioning.js → partitioning/management.js} +48 -307
- package/dist/adapters/postgresql/tools/partitioning/management.js.map +1 -0
- package/dist/adapters/postgresql/tools/partman/helpers.d.ts +29 -0
- package/dist/adapters/postgresql/tools/partman/helpers.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/partman/helpers.js +59 -0
- package/dist/adapters/postgresql/tools/partman/helpers.js.map +1 -0
- package/dist/adapters/postgresql/tools/partman/index.d.ts +2 -1
- package/dist/adapters/postgresql/tools/partman/index.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/partman/index.js +4 -2
- package/dist/adapters/postgresql/tools/partman/index.js.map +1 -1
- package/dist/adapters/postgresql/tools/partman/maintenance.d.ts +20 -0
- package/dist/adapters/postgresql/tools/partman/maintenance.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/partman/maintenance.js +496 -0
- package/dist/adapters/postgresql/tools/partman/maintenance.js.map +1 -0
- package/dist/adapters/postgresql/tools/partman/management.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/partman/management.js +438 -383
- package/dist/adapters/postgresql/tools/partman/management.js.map +1 -1
- package/dist/adapters/postgresql/tools/partman/operations.d.ts +1 -13
- package/dist/adapters/postgresql/tools/partman/operations.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/partman/operations.js +171 -652
- package/dist/adapters/postgresql/tools/partman/operations.js.map +1 -1
- package/dist/adapters/postgresql/tools/performance/analysis.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/performance/analysis.js +69 -42
- package/dist/adapters/postgresql/tools/performance/analysis.js.map +1 -1
- package/dist/adapters/postgresql/tools/performance/anomaly-detection.d.ts +18 -0
- package/dist/adapters/postgresql/tools/performance/anomaly-detection.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/performance/anomaly-detection.js +533 -0
- package/dist/adapters/postgresql/tools/performance/anomaly-detection.js.map +1 -0
- package/dist/adapters/postgresql/tools/performance/diagnostics.d.ts +11 -0
- package/dist/adapters/postgresql/tools/performance/diagnostics.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/performance/diagnostics.js +332 -0
- package/dist/adapters/postgresql/tools/performance/diagnostics.js.map +1 -0
- package/dist/adapters/postgresql/tools/performance/index.d.ts +1 -1
- package/dist/adapters/postgresql/tools/performance/index.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/performance/index.js +7 -1
- package/dist/adapters/postgresql/tools/performance/index.js.map +1 -1
- package/dist/adapters/postgresql/tools/performance/monitoring.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/performance/monitoring.js +80 -55
- package/dist/adapters/postgresql/tools/performance/monitoring.js.map +1 -1
- package/dist/adapters/postgresql/tools/performance/optimization.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/performance/optimization.js +18 -11
- package/dist/adapters/postgresql/tools/performance/optimization.js.map +1 -1
- package/dist/adapters/postgresql/tools/performance/stats.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/performance/stats.js +439 -318
- package/dist/adapters/postgresql/tools/performance/stats.js.map +1 -1
- package/dist/adapters/postgresql/tools/pgcrypto.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/pgcrypto.js +45 -77
- package/dist/adapters/postgresql/tools/pgcrypto.js.map +1 -1
- package/dist/adapters/postgresql/tools/postgis/basic.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/postgis/basic.js +121 -93
- package/dist/adapters/postgresql/tools/postgis/basic.js.map +1 -1
- package/dist/adapters/postgresql/tools/schema/index.d.ts +16 -0
- package/dist/adapters/postgresql/tools/schema/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/schema/index.js +32 -0
- package/dist/adapters/postgresql/tools/schema/index.js.map +1 -0
- package/dist/adapters/postgresql/tools/schema/objects.d.ts +15 -0
- package/dist/adapters/postgresql/tools/schema/objects.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/schema/objects.js +378 -0
- package/dist/adapters/postgresql/tools/schema/objects.js.map +1 -0
- package/dist/adapters/postgresql/tools/schema/views.d.ts +15 -0
- package/dist/adapters/postgresql/tools/schema/views.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/{schema.js → schema/views.js} +64 -386
- package/dist/adapters/postgresql/tools/schema/views.js.map +1 -0
- package/dist/adapters/postgresql/tools/stats/advanced.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/stats/advanced.js +1 -218
- package/dist/adapters/postgresql/tools/stats/advanced.js.map +1 -1
- package/dist/adapters/postgresql/tools/stats/math-utils.d.ts +33 -0
- package/dist/adapters/postgresql/tools/stats/math-utils.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/stats/math-utils.js +225 -0
- package/dist/adapters/postgresql/tools/stats/math-utils.js.map +1 -0
- package/dist/adapters/postgresql/tools/text/index.d.ts +16 -0
- package/dist/adapters/postgresql/tools/text/index.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/text/index.js +33 -0
- package/dist/adapters/postgresql/tools/text/index.js.map +1 -0
- package/dist/adapters/postgresql/tools/text/matching.d.ts +17 -0
- package/dist/adapters/postgresql/tools/text/matching.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/text/matching.js +565 -0
- package/dist/adapters/postgresql/tools/text/matching.js.map +1 -0
- package/dist/adapters/postgresql/tools/text/search.d.ts +17 -0
- package/dist/adapters/postgresql/tools/text/search.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/text/search.js +653 -0
- package/dist/adapters/postgresql/tools/text/search.js.map +1 -0
- package/dist/adapters/postgresql/tools/transactions.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/transactions.js +11 -27
- package/dist/adapters/postgresql/tools/transactions.js.map +1 -1
- package/dist/adapters/postgresql/tools/vector/{basic.d.ts → data.d.ts} +10 -8
- package/dist/adapters/postgresql/tools/vector/data.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/vector/data.js +540 -0
- package/dist/adapters/postgresql/tools/vector/data.js.map +1 -0
- package/dist/adapters/postgresql/tools/vector/index.d.ts.map +1 -1
- package/dist/adapters/postgresql/tools/vector/index.js +6 -2
- package/dist/adapters/postgresql/tools/vector/index.js.map +1 -1
- package/dist/adapters/postgresql/tools/vector/management.d.ts +11 -0
- package/dist/adapters/postgresql/tools/vector/management.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/vector/management.js +425 -0
- package/dist/adapters/postgresql/tools/vector/management.js.map +1 -0
- package/dist/adapters/postgresql/tools/vector/query.d.ts +14 -0
- package/dist/adapters/postgresql/tools/vector/query.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/vector/query.js +767 -0
- package/dist/adapters/postgresql/tools/vector/query.js.map +1 -0
- package/dist/adapters/postgresql/tools/vector/{advanced.d.ts → search-advanced.d.ts} +4 -5
- package/dist/adapters/postgresql/tools/vector/search-advanced.d.ts.map +1 -0
- package/dist/adapters/postgresql/tools/vector/search-advanced.js +626 -0
- package/dist/adapters/postgresql/tools/vector/search-advanced.js.map +1 -0
- package/dist/auth/scopes.d.ts.map +1 -1
- package/dist/auth/scopes.js +3 -1
- package/dist/auth/scopes.js.map +1 -1
- package/dist/cli/args.d.ts +3 -2
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +4 -3
- package/dist/cli/args.js.map +1 -1
- package/dist/cli.js +16 -4
- package/dist/cli.js.map +1 -1
- package/dist/codemode/api/aliases.d.ts +14 -0
- package/dist/codemode/api/aliases.d.ts.map +1 -0
- package/dist/codemode/api/aliases.js +503 -0
- package/dist/codemode/api/aliases.js.map +1 -0
- package/dist/codemode/api/group-api.d.ts +23 -0
- package/dist/codemode/api/group-api.d.ts.map +1 -0
- package/dist/codemode/api/group-api.js +179 -0
- package/dist/codemode/api/group-api.js.map +1 -0
- package/dist/codemode/{api.d.ts → api/index.d.ts} +5 -4
- package/dist/codemode/api/index.d.ts.map +1 -0
- package/dist/codemode/api/index.js +195 -0
- package/dist/codemode/api/index.js.map +1 -0
- package/dist/codemode/api/maps.d.ts +47 -0
- package/dist/codemode/api/maps.d.ts.map +1 -0
- package/dist/codemode/api/maps.js +529 -0
- package/dist/codemode/api/maps.js.map +1 -0
- package/dist/codemode/api/normalize.d.ts +13 -0
- package/dist/codemode/api/normalize.d.ts.map +1 -0
- package/dist/codemode/api/normalize.js +120 -0
- package/dist/codemode/api/normalize.js.map +1 -0
- package/dist/codemode/index.d.ts +1 -1
- package/dist/codemode/index.d.ts.map +1 -1
- package/dist/codemode/index.js +1 -1
- package/dist/codemode/index.js.map +1 -1
- package/dist/codemode/sandbox.d.ts.map +1 -1
- package/dist/codemode/sandbox.js +8 -25
- package/dist/codemode/sandbox.js.map +1 -1
- package/dist/filtering/ToolConstants.d.ts +11 -11
- package/dist/filtering/ToolConstants.d.ts.map +1 -1
- package/dist/filtering/ToolConstants.js +28 -15
- package/dist/filtering/ToolConstants.js.map +1 -1
- package/dist/filtering/ToolFilter.d.ts +0 -32
- package/dist/filtering/ToolFilter.d.ts.map +1 -1
- package/dist/filtering/ToolFilter.js +0 -43
- package/dist/filtering/ToolFilter.js.map +1 -1
- package/dist/server/McpServer.d.ts +1 -1
- package/dist/server/McpServer.d.ts.map +1 -1
- package/dist/server/McpServer.js +1 -2
- package/dist/server/McpServer.js.map +1 -1
- package/dist/transports/http.d.ts +55 -10
- package/dist/transports/http.d.ts.map +1 -1
- package/dist/transports/http.js +301 -50
- package/dist/transports/http.js.map +1 -1
- package/dist/types/filtering.d.ts +1 -1
- package/dist/types/filtering.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/mcp.d.ts +0 -21
- package/dist/types/mcp.d.ts.map +1 -1
- package/dist/types/schema.d.ts +0 -79
- package/dist/types/schema.d.ts.map +1 -1
- package/dist/utils/fts-config.d.ts +0 -6
- package/dist/utils/fts-config.d.ts.map +1 -1
- package/dist/utils/fts-config.js +1 -1
- package/dist/utils/fts-config.js.map +1 -1
- package/dist/utils/icons.d.ts.map +1 -1
- package/dist/utils/icons.js +5 -0
- package/dist/utils/icons.js.map +1 -1
- package/dist/utils/identifiers.d.ts.map +1 -1
- package/dist/utils/identifiers.js +6 -6
- package/dist/utils/identifiers.js.map +1 -1
- package/dist/utils/logger.d.ts +6 -6
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +18 -15
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/progress-utils.d.ts +3 -14
- package/dist/utils/progress-utils.d.ts.map +1 -1
- package/dist/utils/progress-utils.js +2 -21
- package/dist/utils/progress-utils.js.map +1 -1
- package/dist/utils/version.d.ts +9 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +12 -0
- package/dist/utils/version.js.map +1 -0
- package/dist/utils/where-clause.d.ts +4 -0
- package/dist/utils/where-clause.d.ts.map +1 -1
- package/dist/utils/where-clause.js +16 -0
- package/dist/utils/where-clause.js.map +1 -1
- package/package.json +6 -4
- package/dist/adapters/postgresql/schemas/core.d.ts.map +0 -1
- package/dist/adapters/postgresql/schemas/core.js.map +0 -1
- package/dist/adapters/postgresql/schemas/extensions.d.ts +0 -852
- package/dist/adapters/postgresql/schemas/extensions.d.ts.map +0 -1
- package/dist/adapters/postgresql/schemas/extensions.js +0 -1202
- package/dist/adapters/postgresql/schemas/extensions.js.map +0 -1
- package/dist/adapters/postgresql/schemas/jsonb.d.ts +0 -541
- package/dist/adapters/postgresql/schemas/jsonb.d.ts.map +0 -1
- package/dist/adapters/postgresql/schemas/jsonb.js +0 -814
- package/dist/adapters/postgresql/schemas/jsonb.js.map +0 -1
- package/dist/adapters/postgresql/schemas/postgis.d.ts.map +0 -1
- package/dist/adapters/postgresql/schemas/postgis.js.map +0 -1
- package/dist/adapters/postgresql/schemas/stats.d.ts.map +0 -1
- package/dist/adapters/postgresql/schemas/stats.js.map +0 -1
- package/dist/adapters/postgresql/tools/citext.d.ts +0 -18
- package/dist/adapters/postgresql/tools/citext.d.ts.map +0 -1
- package/dist/adapters/postgresql/tools/citext.js.map +0 -1
- package/dist/adapters/postgresql/tools/introspection.d.ts +0 -15
- package/dist/adapters/postgresql/tools/introspection.d.ts.map +0 -1
- package/dist/adapters/postgresql/tools/introspection.js +0 -1682
- package/dist/adapters/postgresql/tools/introspection.js.map +0 -1
- package/dist/adapters/postgresql/tools/jsonb/advanced.d.ts.map +0 -1
- package/dist/adapters/postgresql/tools/jsonb/advanced.js.map +0 -1
- package/dist/adapters/postgresql/tools/jsonb/basic.d.ts +0 -20
- package/dist/adapters/postgresql/tools/jsonb/basic.d.ts.map +0 -1
- package/dist/adapters/postgresql/tools/jsonb/basic.js.map +0 -1
- package/dist/adapters/postgresql/tools/monitoring.d.ts +0 -13
- package/dist/adapters/postgresql/tools/monitoring.d.ts.map +0 -1
- package/dist/adapters/postgresql/tools/monitoring.js.map +0 -1
- package/dist/adapters/postgresql/tools/partitioning.d.ts +0 -13
- package/dist/adapters/postgresql/tools/partitioning.d.ts.map +0 -1
- package/dist/adapters/postgresql/tools/partitioning.js.map +0 -1
- package/dist/adapters/postgresql/tools/schema.d.ts +0 -13
- package/dist/adapters/postgresql/tools/schema.d.ts.map +0 -1
- package/dist/adapters/postgresql/tools/schema.js.map +0 -1
- package/dist/adapters/postgresql/tools/text.d.ts +0 -13
- package/dist/adapters/postgresql/tools/text.d.ts.map +0 -1
- package/dist/adapters/postgresql/tools/text.js +0 -1082
- package/dist/adapters/postgresql/tools/text.js.map +0 -1
- package/dist/adapters/postgresql/tools/vector/advanced.d.ts.map +0 -1
- package/dist/adapters/postgresql/tools/vector/advanced.js +0 -958
- package/dist/adapters/postgresql/tools/vector/advanced.js.map +0 -1
- package/dist/adapters/postgresql/tools/vector/basic.d.ts.map +0 -1
- package/dist/adapters/postgresql/tools/vector/basic.js +0 -1165
- package/dist/adapters/postgresql/tools/vector/basic.js.map +0 -1
- package/dist/codemode/api.d.ts.map +0 -1
- package/dist/codemode/api.js +0 -1544
- package/dist/codemode/api.js.map +0 -1
- package/dist/utils/promptGenerator.d.ts +0 -20
- package/dist/utils/promptGenerator.d.ts.map +0 -1
- package/dist/utils/promptGenerator.js +0 -81
- package/dist/utils/promptGenerator.js.map +0 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PostgreSQL Introspection Tools - Graph Analysis
|
|
3
|
+
*
|
|
4
|
+
* Dependency graph, topological sort, and cascade simulation tools.
|
|
5
|
+
* 3 tools total.
|
|
6
|
+
*/
|
|
7
|
+
import type { PostgresAdapter } from "../../PostgresAdapter.js";
|
|
8
|
+
import type { ToolDefinition } from "../../../../types/index.js";
|
|
9
|
+
interface FkEdge {
|
|
10
|
+
constraintName: string;
|
|
11
|
+
fromSchema: string;
|
|
12
|
+
fromTable: string;
|
|
13
|
+
fromColumns: string[];
|
|
14
|
+
toSchema: string;
|
|
15
|
+
toTable: string;
|
|
16
|
+
toColumns: string[];
|
|
17
|
+
onDelete: string;
|
|
18
|
+
onUpdate: string;
|
|
19
|
+
}
|
|
20
|
+
interface TableNode {
|
|
21
|
+
schema: string;
|
|
22
|
+
table: string;
|
|
23
|
+
rowCount?: number;
|
|
24
|
+
sizeBytes?: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Fetch all foreign key relationships across user schemas
|
|
28
|
+
*/
|
|
29
|
+
export declare function fetchForeignKeys(adapter: PostgresAdapter, schemaFilter?: string, excludeExtensionSchemas?: boolean): Promise<FkEdge[]>;
|
|
30
|
+
/**
|
|
31
|
+
* Fetch all user tables with row counts and sizes
|
|
32
|
+
*/
|
|
33
|
+
export declare function fetchTableNodes(adapter: PostgresAdapter, schemaFilter?: string, excludeExtensionSchemas?: boolean): Promise<TableNode[]>;
|
|
34
|
+
/**
|
|
35
|
+
* Parse PostgreSQL array column (handles both native arrays and string format)
|
|
36
|
+
*/
|
|
37
|
+
export declare function parseArrayColumn(value: unknown): string[];
|
|
38
|
+
/**
|
|
39
|
+
* Create qualified table name
|
|
40
|
+
*/
|
|
41
|
+
export declare function qualifiedName(schema: string, table: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Detect circular dependencies using DFS
|
|
44
|
+
*/
|
|
45
|
+
export declare function detectCycles(adjacency: Map<string, string[]>): string[][];
|
|
46
|
+
/**
|
|
47
|
+
* Topological sort using Kahn's algorithm
|
|
48
|
+
* Returns null if cycles exist
|
|
49
|
+
*/
|
|
50
|
+
export declare function topologicalSort(adjacency: Map<string, string[]>, allNodes: Set<string>): string[] | null;
|
|
51
|
+
export declare function createDependencyGraphTool(adapter: PostgresAdapter): ToolDefinition;
|
|
52
|
+
export declare function createTopologicalSortTool(adapter: PostgresAdapter): ToolDefinition;
|
|
53
|
+
export declare function createCascadeSimulatorTool(adapter: PostgresAdapter): ToolDefinition;
|
|
54
|
+
export {};
|
|
55
|
+
//# sourceMappingURL=graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../../../src/adapters/postgresql/tools/introspection/graph.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EACV,cAAc,EAEf,MAAM,4BAA4B,CAAC;AAqBpC,UAAU,MAAM;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,SAAS;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,eAAe,EACxB,YAAY,CAAC,EAAE,MAAM,EACrB,uBAAuB,CAAC,EAAE,OAAO,GAChC,OAAO,CAAC,MAAM,EAAE,CAAC,CA6DnB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,eAAe,EACxB,YAAY,CAAC,EAAE,MAAM,EACrB,uBAAuB,CAAC,EAAE,OAAO,GAChC,OAAO,CAAC,SAAS,EAAE,CAAC,CAsCtB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAQzD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnE;AAMD;;GAEG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,EAAE,CAkCzE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAChC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,GACpB,MAAM,EAAE,GAAG,IAAI,CA2CjB;AAwCD,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,eAAe,GACvB,cAAc,CA2HhB;AAMD,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,eAAe,GACvB,cAAc,CAkIhB;AAMD,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,eAAe,GACvB,cAAc,CA2KhB"}
|
|
@@ -0,0 +1,621 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PostgreSQL Introspection Tools - Graph Analysis
|
|
3
|
+
*
|
|
4
|
+
* Dependency graph, topological sort, and cascade simulation tools.
|
|
5
|
+
* 3 tools total.
|
|
6
|
+
*/
|
|
7
|
+
import { readOnly } from "../../../../utils/annotations.js";
|
|
8
|
+
import { getToolIcons } from "../../../../utils/icons.js";
|
|
9
|
+
import { formatPostgresError } from "../core/error-helpers.js";
|
|
10
|
+
import { DependencyGraphSchemaBase, DependencyGraphSchema, TopologicalSortSchemaBase, TopologicalSortSchema, CascadeSimulatorSchemaBase, CascadeSimulatorSchema,
|
|
11
|
+
// Output schemas
|
|
12
|
+
DependencyGraphOutputSchema, TopologicalSortOutputSchema, CascadeSimulatorOutputSchema, } from "../../schemas/index.js";
|
|
13
|
+
// =============================================================================
|
|
14
|
+
// Shared queries
|
|
15
|
+
// =============================================================================
|
|
16
|
+
/**
|
|
17
|
+
* Fetch all foreign key relationships across user schemas
|
|
18
|
+
*/
|
|
19
|
+
export async function fetchForeignKeys(adapter, schemaFilter, excludeExtensionSchemas) {
|
|
20
|
+
const params = [];
|
|
21
|
+
let schemaClause = "";
|
|
22
|
+
if (schemaFilter) {
|
|
23
|
+
params.push(schemaFilter);
|
|
24
|
+
schemaClause = `AND src_ns.nspname = $${String(params.length)}`;
|
|
25
|
+
}
|
|
26
|
+
const extensionSchemaExclude = !schemaFilter && excludeExtensionSchemas !== false
|
|
27
|
+
? "AND src_ns.nspname NOT IN ('cron', 'topology', 'tiger', 'tiger_data')"
|
|
28
|
+
: "";
|
|
29
|
+
const result = await adapter.executeQuery(`SELECT
|
|
30
|
+
c.conname AS constraint_name,
|
|
31
|
+
src_ns.nspname AS from_schema,
|
|
32
|
+
src_t.relname AS from_table,
|
|
33
|
+
array_agg(DISTINCT src_a.attname ORDER BY src_a.attname) AS from_columns,
|
|
34
|
+
ref_ns.nspname AS to_schema,
|
|
35
|
+
ref_t.relname AS to_table,
|
|
36
|
+
array_agg(DISTINCT ref_a.attname ORDER BY ref_a.attname) AS to_columns,
|
|
37
|
+
CASE c.confdeltype
|
|
38
|
+
WHEN 'a' THEN 'NO ACTION' WHEN 'r' THEN 'RESTRICT'
|
|
39
|
+
WHEN 'c' THEN 'CASCADE' WHEN 'n' THEN 'SET NULL'
|
|
40
|
+
WHEN 'd' THEN 'SET DEFAULT'
|
|
41
|
+
END AS on_delete,
|
|
42
|
+
CASE c.confupdtype
|
|
43
|
+
WHEN 'a' THEN 'NO ACTION' WHEN 'r' THEN 'RESTRICT'
|
|
44
|
+
WHEN 'c' THEN 'CASCADE' WHEN 'n' THEN 'SET NULL'
|
|
45
|
+
WHEN 'd' THEN 'SET DEFAULT'
|
|
46
|
+
END AS on_update
|
|
47
|
+
FROM pg_constraint c
|
|
48
|
+
JOIN pg_class src_t ON src_t.oid = c.conrelid
|
|
49
|
+
JOIN pg_namespace src_ns ON src_ns.oid = src_t.relnamespace
|
|
50
|
+
JOIN pg_class ref_t ON ref_t.oid = c.confrelid
|
|
51
|
+
JOIN pg_namespace ref_ns ON ref_ns.oid = ref_t.relnamespace
|
|
52
|
+
JOIN pg_attribute src_a ON src_a.attrelid = src_t.oid AND src_a.attnum = ANY(c.conkey)
|
|
53
|
+
JOIN pg_attribute ref_a ON ref_a.attrelid = ref_t.oid AND ref_a.attnum = ANY(c.confkey)
|
|
54
|
+
WHERE c.contype = 'f'
|
|
55
|
+
AND src_ns.nspname NOT IN ('pg_catalog', 'information_schema')
|
|
56
|
+
AND src_ns.nspname !~ '^pg_toast'
|
|
57
|
+
${extensionSchemaExclude}
|
|
58
|
+
${schemaClause}
|
|
59
|
+
GROUP BY c.conname, src_ns.nspname, src_t.relname,
|
|
60
|
+
ref_ns.nspname, ref_t.relname, c.confdeltype, c.confupdtype
|
|
61
|
+
ORDER BY src_ns.nspname, src_t.relname, c.conname`, params.length > 0 ? params : undefined);
|
|
62
|
+
return (result.rows ?? []).map((row) => ({
|
|
63
|
+
constraintName: row["constraint_name"],
|
|
64
|
+
fromSchema: row["from_schema"],
|
|
65
|
+
fromTable: row["from_table"],
|
|
66
|
+
fromColumns: parseArrayColumn(row["from_columns"]),
|
|
67
|
+
toSchema: row["to_schema"],
|
|
68
|
+
toTable: row["to_table"],
|
|
69
|
+
toColumns: parseArrayColumn(row["to_columns"]),
|
|
70
|
+
onDelete: row["on_delete"],
|
|
71
|
+
onUpdate: row["on_update"],
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Fetch all user tables with row counts and sizes
|
|
76
|
+
*/
|
|
77
|
+
export async function fetchTableNodes(adapter, schemaFilter, excludeExtensionSchemas) {
|
|
78
|
+
const params = [];
|
|
79
|
+
let schemaClause = "";
|
|
80
|
+
if (schemaFilter) {
|
|
81
|
+
params.push(schemaFilter);
|
|
82
|
+
schemaClause = `AND n.nspname = $${String(params.length)}`;
|
|
83
|
+
}
|
|
84
|
+
const extensionSchemaExclude = !schemaFilter && excludeExtensionSchemas !== false
|
|
85
|
+
? "AND n.nspname NOT IN ('cron', 'topology', 'tiger', 'tiger_data')"
|
|
86
|
+
: "";
|
|
87
|
+
const result = await adapter.executeQuery(`SELECT
|
|
88
|
+
n.nspname AS schema,
|
|
89
|
+
c.relname AS table_name,
|
|
90
|
+
CASE WHEN c.reltuples = -1 THEN COALESCE(s.n_live_tup, 0)
|
|
91
|
+
ELSE c.reltuples END::bigint AS row_count,
|
|
92
|
+
pg_table_size(c.oid) AS size_bytes
|
|
93
|
+
FROM pg_class c
|
|
94
|
+
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
95
|
+
LEFT JOIN pg_stat_user_tables s ON s.relid = c.oid
|
|
96
|
+
WHERE c.relkind IN ('r', 'p')
|
|
97
|
+
AND n.nspname NOT IN ('pg_catalog', 'information_schema')
|
|
98
|
+
AND n.nspname !~ '^pg_toast'
|
|
99
|
+
${extensionSchemaExclude}
|
|
100
|
+
${schemaClause}
|
|
101
|
+
ORDER BY n.nspname, c.relname`, params.length > 0 ? params : undefined);
|
|
102
|
+
return (result.rows ?? []).map((row) => ({
|
|
103
|
+
schema: row["schema"],
|
|
104
|
+
table: row["table_name"],
|
|
105
|
+
rowCount: Number(row["row_count"]) || 0,
|
|
106
|
+
sizeBytes: Number(row["size_bytes"]) || 0,
|
|
107
|
+
}));
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Parse PostgreSQL array column (handles both native arrays and string format)
|
|
111
|
+
*/
|
|
112
|
+
export function parseArrayColumn(value) {
|
|
113
|
+
if (Array.isArray(value))
|
|
114
|
+
return value;
|
|
115
|
+
if (typeof value === "string") {
|
|
116
|
+
const trimmed = value.replace(/^{|}$/g, "");
|
|
117
|
+
if (trimmed === "")
|
|
118
|
+
return [];
|
|
119
|
+
return trimmed.split(",").map((c) => c.trim().replace(/^"|"$/g, ""));
|
|
120
|
+
}
|
|
121
|
+
return [];
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Create qualified table name
|
|
125
|
+
*/
|
|
126
|
+
export function qualifiedName(schema, table) {
|
|
127
|
+
return `${schema}.${table}`;
|
|
128
|
+
}
|
|
129
|
+
// =============================================================================
|
|
130
|
+
// Graph algorithms
|
|
131
|
+
// =============================================================================
|
|
132
|
+
/**
|
|
133
|
+
* Detect circular dependencies using DFS
|
|
134
|
+
*/
|
|
135
|
+
export function detectCycles(adjacency) {
|
|
136
|
+
const cycles = [];
|
|
137
|
+
const visited = new Set();
|
|
138
|
+
const inStack = new Set();
|
|
139
|
+
const stack = [];
|
|
140
|
+
function dfs(node) {
|
|
141
|
+
if (inStack.has(node)) {
|
|
142
|
+
// Found a cycle - extract it from the stack
|
|
143
|
+
const cycleStart = stack.indexOf(node);
|
|
144
|
+
if (cycleStart !== -1) {
|
|
145
|
+
cycles.push([...stack.slice(cycleStart), node]);
|
|
146
|
+
}
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
if (visited.has(node))
|
|
150
|
+
return;
|
|
151
|
+
visited.add(node);
|
|
152
|
+
inStack.add(node);
|
|
153
|
+
stack.push(node);
|
|
154
|
+
for (const neighbor of adjacency.get(node) ?? []) {
|
|
155
|
+
dfs(neighbor);
|
|
156
|
+
}
|
|
157
|
+
stack.pop();
|
|
158
|
+
inStack.delete(node);
|
|
159
|
+
}
|
|
160
|
+
for (const node of adjacency.keys()) {
|
|
161
|
+
dfs(node);
|
|
162
|
+
}
|
|
163
|
+
return cycles;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Topological sort using Kahn's algorithm
|
|
167
|
+
* Returns null if cycles exist
|
|
168
|
+
*/
|
|
169
|
+
export function topologicalSort(adjacency, allNodes) {
|
|
170
|
+
// Compute in-degrees
|
|
171
|
+
const inDegree = new Map();
|
|
172
|
+
for (const node of allNodes) {
|
|
173
|
+
inDegree.set(node, 0);
|
|
174
|
+
}
|
|
175
|
+
for (const [, neighbors] of adjacency) {
|
|
176
|
+
for (const n of neighbors) {
|
|
177
|
+
inDegree.set(n, (inDegree.get(n) ?? 0) + 1);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// Enqueue nodes with 0 in-degree
|
|
181
|
+
const queue = [];
|
|
182
|
+
for (const [node, degree] of inDegree) {
|
|
183
|
+
if (degree === 0) {
|
|
184
|
+
queue.push(node);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
queue.sort(); // Deterministic ordering
|
|
188
|
+
const result = [];
|
|
189
|
+
while (queue.length > 0) {
|
|
190
|
+
const node = queue.shift();
|
|
191
|
+
if (node === undefined)
|
|
192
|
+
break;
|
|
193
|
+
result.push(node);
|
|
194
|
+
for (const neighbor of adjacency.get(node) ?? []) {
|
|
195
|
+
const newDegree = (inDegree.get(neighbor) ?? 1) - 1;
|
|
196
|
+
inDegree.set(neighbor, newDegree);
|
|
197
|
+
if (newDegree === 0) {
|
|
198
|
+
// Insert in sorted position for deterministic output
|
|
199
|
+
const insertIdx = queue.findIndex((q) => q > neighbor);
|
|
200
|
+
if (insertIdx === -1) {
|
|
201
|
+
queue.push(neighbor);
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
queue.splice(insertIdx, 0, neighbor);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return result.length === allNodes.size ? result : null;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Calculate max depth from root nodes in DAG
|
|
213
|
+
*/
|
|
214
|
+
function calculateMaxDepth(adjacency, roots) {
|
|
215
|
+
if (roots.length === 0)
|
|
216
|
+
return 0;
|
|
217
|
+
let maxDepth = 0;
|
|
218
|
+
const depthMap = new Map();
|
|
219
|
+
function dfs(node, depth, visited) {
|
|
220
|
+
if (visited.has(node))
|
|
221
|
+
return;
|
|
222
|
+
visited.add(node);
|
|
223
|
+
const currentMax = depthMap.get(node) ?? -1;
|
|
224
|
+
if (depth > currentMax) {
|
|
225
|
+
depthMap.set(node, depth);
|
|
226
|
+
if (depth > maxDepth)
|
|
227
|
+
maxDepth = depth;
|
|
228
|
+
}
|
|
229
|
+
for (const neighbor of adjacency.get(node) ?? []) {
|
|
230
|
+
dfs(neighbor, depth + 1, visited);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
for (const root of roots) {
|
|
234
|
+
dfs(root, 0, new Set());
|
|
235
|
+
}
|
|
236
|
+
return maxDepth;
|
|
237
|
+
}
|
|
238
|
+
// =============================================================================
|
|
239
|
+
// pg_dependency_graph
|
|
240
|
+
// =============================================================================
|
|
241
|
+
export function createDependencyGraphTool(adapter) {
|
|
242
|
+
return {
|
|
243
|
+
name: "pg_dependency_graph",
|
|
244
|
+
description: "Get the full foreign key dependency graph with cascade paths, row counts, circular dependency detection, and severity assessment. Agent-optimized structured output.",
|
|
245
|
+
group: "introspection",
|
|
246
|
+
inputSchema: DependencyGraphSchemaBase,
|
|
247
|
+
outputSchema: DependencyGraphOutputSchema,
|
|
248
|
+
annotations: readOnly("Dependency Graph"),
|
|
249
|
+
icons: getToolIcons("introspection", readOnly("Dependency Graph")),
|
|
250
|
+
handler: async (params, _context) => {
|
|
251
|
+
try {
|
|
252
|
+
const parsed = DependencyGraphSchema.parse(params);
|
|
253
|
+
const includeRowCounts = parsed.includeRowCounts !== false;
|
|
254
|
+
const excludeExt = parsed.excludeExtensionSchemas;
|
|
255
|
+
const [fks, tables] = await Promise.all([
|
|
256
|
+
fetchForeignKeys(adapter, parsed.schema, excludeExt),
|
|
257
|
+
includeRowCounts
|
|
258
|
+
? fetchTableNodes(adapter, parsed.schema, excludeExt)
|
|
259
|
+
: Promise.resolve([]),
|
|
260
|
+
]);
|
|
261
|
+
const tableMap = new Map(tables.map((t) => [qualifiedName(t.schema, t.table), t]));
|
|
262
|
+
// Build adjacency list (from → to, meaning "from" depends on "to")
|
|
263
|
+
const adjacency = new Map();
|
|
264
|
+
const allNodes = new Set();
|
|
265
|
+
// Ensure all tables are in the node set even if they have no FKs
|
|
266
|
+
for (const t of tables) {
|
|
267
|
+
allNodes.add(qualifiedName(t.schema, t.table));
|
|
268
|
+
}
|
|
269
|
+
for (const fk of fks) {
|
|
270
|
+
const from = qualifiedName(fk.fromSchema, fk.fromTable);
|
|
271
|
+
const to = qualifiedName(fk.toSchema, fk.toTable);
|
|
272
|
+
allNodes.add(from);
|
|
273
|
+
allNodes.add(to);
|
|
274
|
+
const existing = adjacency.get(from) ?? [];
|
|
275
|
+
existing.push(to);
|
|
276
|
+
adjacency.set(from, existing);
|
|
277
|
+
}
|
|
278
|
+
// Find root tables (no dependencies) and leaf tables (no dependents)
|
|
279
|
+
const dependents = new Set();
|
|
280
|
+
for (const [, neighbors] of adjacency) {
|
|
281
|
+
for (const n of neighbors) {
|
|
282
|
+
dependents.add(n);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
const rootTables = [...allNodes]
|
|
286
|
+
.filter((n) => !adjacency.has(n) || (adjacency.get(n)?.length ?? 0) === 0)
|
|
287
|
+
.sort();
|
|
288
|
+
const leafTables = [...allNodes]
|
|
289
|
+
.filter((n) => !dependents.has(n))
|
|
290
|
+
.sort();
|
|
291
|
+
// Detect cycles
|
|
292
|
+
const cycles = detectCycles(adjacency);
|
|
293
|
+
const maxDepth = calculateMaxDepth(adjacency, leafTables);
|
|
294
|
+
// Build nodes
|
|
295
|
+
const nodes = [...allNodes].sort().map((name) => {
|
|
296
|
+
const info = tableMap.get(name);
|
|
297
|
+
const parts = name.split(".");
|
|
298
|
+
return {
|
|
299
|
+
table: parts[1] ?? name,
|
|
300
|
+
schema: parts[0] ?? "public",
|
|
301
|
+
...(includeRowCounts && info
|
|
302
|
+
? { rowCount: info.rowCount, sizeBytes: info.sizeBytes }
|
|
303
|
+
: {}),
|
|
304
|
+
};
|
|
305
|
+
});
|
|
306
|
+
// Build edges
|
|
307
|
+
const edges = fks.map((fk) => ({
|
|
308
|
+
from: qualifiedName(fk.fromSchema, fk.fromTable),
|
|
309
|
+
to: qualifiedName(fk.toSchema, fk.toTable),
|
|
310
|
+
constraint: fk.constraintName,
|
|
311
|
+
columns: fk.fromColumns.map((col, i) => ({
|
|
312
|
+
from: col,
|
|
313
|
+
to: fk.toColumns[i] ?? col,
|
|
314
|
+
})),
|
|
315
|
+
onDelete: fk.onDelete,
|
|
316
|
+
onUpdate: fk.onUpdate,
|
|
317
|
+
}));
|
|
318
|
+
// Add hint for nonexistent/empty schema
|
|
319
|
+
const hint = parsed.schema !== undefined && allNodes.size === 0
|
|
320
|
+
? `Schema '${parsed.schema}' returned no tables. Verify the schema exists with pg_list_schemas.`
|
|
321
|
+
: undefined;
|
|
322
|
+
return {
|
|
323
|
+
nodes,
|
|
324
|
+
edges,
|
|
325
|
+
circularDependencies: cycles,
|
|
326
|
+
stats: {
|
|
327
|
+
totalTables: allNodes.size,
|
|
328
|
+
totalRelationships: fks.length,
|
|
329
|
+
maxDepth,
|
|
330
|
+
rootTables,
|
|
331
|
+
leafTables,
|
|
332
|
+
},
|
|
333
|
+
...(hint !== undefined && { hint }),
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
catch (error) {
|
|
337
|
+
return {
|
|
338
|
+
success: false,
|
|
339
|
+
error: formatPostgresError(error, {
|
|
340
|
+
tool: "pg_dependency_graph",
|
|
341
|
+
}),
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
},
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
// =============================================================================
|
|
348
|
+
// pg_topological_sort
|
|
349
|
+
// =============================================================================
|
|
350
|
+
export function createTopologicalSortTool(adapter) {
|
|
351
|
+
return {
|
|
352
|
+
name: "pg_topological_sort",
|
|
353
|
+
description: "Get tables in safe DDL execution order. 'create' direction: dependencies first (for CREATE TABLE). 'drop' direction: dependents first (for DROP TABLE).",
|
|
354
|
+
group: "introspection",
|
|
355
|
+
inputSchema: TopologicalSortSchemaBase,
|
|
356
|
+
outputSchema: TopologicalSortOutputSchema,
|
|
357
|
+
annotations: readOnly("Topological Sort"),
|
|
358
|
+
icons: getToolIcons("introspection", readOnly("Topological Sort")),
|
|
359
|
+
handler: async (params, _context) => {
|
|
360
|
+
try {
|
|
361
|
+
const parsed = TopologicalSortSchema.parse(params);
|
|
362
|
+
const direction = parsed.direction ?? "create";
|
|
363
|
+
const excludeExt = parsed.excludeExtensionSchemas;
|
|
364
|
+
const fks = await fetchForeignKeys(adapter, parsed.schema, excludeExt);
|
|
365
|
+
const tables = await fetchTableNodes(adapter, parsed.schema, excludeExt);
|
|
366
|
+
// Build all graph structures in a single FK iteration (PERF-P3)
|
|
367
|
+
const adjacency = new Map();
|
|
368
|
+
const allNodes = new Set();
|
|
369
|
+
const dependsOn = new Map();
|
|
370
|
+
// Pre-compute create-direction adjacency for level computation in drop mode
|
|
371
|
+
const createAdj = new Map();
|
|
372
|
+
for (const t of tables) {
|
|
373
|
+
allNodes.add(qualifiedName(t.schema, t.table));
|
|
374
|
+
}
|
|
375
|
+
for (const fk of fks) {
|
|
376
|
+
const from = qualifiedName(fk.fromSchema, fk.fromTable);
|
|
377
|
+
const to = qualifiedName(fk.toSchema, fk.toTable);
|
|
378
|
+
allNodes.add(from);
|
|
379
|
+
allNodes.add(to);
|
|
380
|
+
if (from === to)
|
|
381
|
+
continue; // Self-references don't affect ordering
|
|
382
|
+
// dependsOn: from depends on to
|
|
383
|
+
const deps = dependsOn.get(from) ?? new Set();
|
|
384
|
+
deps.add(to);
|
|
385
|
+
dependsOn.set(from, deps);
|
|
386
|
+
// adjacency for requested direction
|
|
387
|
+
if (direction === "create") {
|
|
388
|
+
const existing = adjacency.get(to) ?? [];
|
|
389
|
+
existing.push(from);
|
|
390
|
+
adjacency.set(to, existing);
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
const existing = adjacency.get(from) ?? [];
|
|
394
|
+
existing.push(to);
|
|
395
|
+
adjacency.set(from, existing);
|
|
396
|
+
// Also build create-direction adjacency for level computation
|
|
397
|
+
const createExisting = createAdj.get(to) ?? [];
|
|
398
|
+
createExisting.push(from);
|
|
399
|
+
createAdj.set(to, createExisting);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
const sorted = topologicalSort(adjacency, allNodes);
|
|
403
|
+
const cycles = sorted === null ? detectCycles(adjacency) : [];
|
|
404
|
+
// Compute level (depth in the dependency graph)
|
|
405
|
+
// Always use create-order traversal for consistent levels regardless of direction
|
|
406
|
+
const levelMap = new Map();
|
|
407
|
+
if (sorted) {
|
|
408
|
+
// For create direction, sorted is already in dependency order.
|
|
409
|
+
// For drop direction, use pre-computed create-direction adjacency.
|
|
410
|
+
let createOrder;
|
|
411
|
+
if (direction === "create") {
|
|
412
|
+
createOrder = sorted;
|
|
413
|
+
}
|
|
414
|
+
else {
|
|
415
|
+
createOrder =
|
|
416
|
+
topologicalSort(createAdj, allNodes) ?? [...allNodes].sort();
|
|
417
|
+
}
|
|
418
|
+
for (const node of createOrder) {
|
|
419
|
+
const deps = dependsOn.get(node);
|
|
420
|
+
if (!deps || deps.size === 0) {
|
|
421
|
+
levelMap.set(node, 0);
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
let maxParentLevel = 0;
|
|
425
|
+
for (const dep of deps) {
|
|
426
|
+
const parentLevel = levelMap.get(dep) ?? 0;
|
|
427
|
+
if (parentLevel >= maxParentLevel) {
|
|
428
|
+
maxParentLevel = parentLevel + 1;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
levelMap.set(node, maxParentLevel);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
const order = (sorted ?? [...allNodes].sort()).map((name) => {
|
|
436
|
+
const parts = name.split(".");
|
|
437
|
+
return {
|
|
438
|
+
table: parts[1] ?? name,
|
|
439
|
+
schema: parts[0] ?? "public",
|
|
440
|
+
level: levelMap.get(name) ?? 0,
|
|
441
|
+
dependencies: [...(dependsOn.get(name) ?? [])].sort(),
|
|
442
|
+
};
|
|
443
|
+
});
|
|
444
|
+
// Add hint for nonexistent/empty schema
|
|
445
|
+
const hint = parsed.schema !== undefined && allNodes.size === 0
|
|
446
|
+
? `Schema '${parsed.schema}' returned no tables. Verify the schema exists with pg_list_schemas.`
|
|
447
|
+
: undefined;
|
|
448
|
+
return {
|
|
449
|
+
order,
|
|
450
|
+
direction,
|
|
451
|
+
hasCycles: sorted === null,
|
|
452
|
+
...(cycles.length > 0 ? { cycles } : {}),
|
|
453
|
+
...(hint !== undefined && { hint }),
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
catch (error) {
|
|
457
|
+
return {
|
|
458
|
+
success: false,
|
|
459
|
+
error: formatPostgresError(error, {
|
|
460
|
+
tool: "pg_topological_sort",
|
|
461
|
+
}),
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
},
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
// =============================================================================
|
|
468
|
+
// pg_cascade_simulator
|
|
469
|
+
// =============================================================================
|
|
470
|
+
export function createCascadeSimulatorTool(adapter) {
|
|
471
|
+
return {
|
|
472
|
+
name: "pg_cascade_simulator",
|
|
473
|
+
description: "Simulate the impact of DELETE, DROP, or TRUNCATE on a table. Returns affected tables, estimated row counts, cascade paths, and severity assessment.",
|
|
474
|
+
group: "introspection",
|
|
475
|
+
inputSchema: CascadeSimulatorSchemaBase,
|
|
476
|
+
outputSchema: CascadeSimulatorOutputSchema,
|
|
477
|
+
annotations: readOnly("Cascade Simulator"),
|
|
478
|
+
icons: getToolIcons("introspection", readOnly("Cascade Simulator")),
|
|
479
|
+
handler: async (params, _context) => {
|
|
480
|
+
try {
|
|
481
|
+
const parsed = CascadeSimulatorSchema.parse(params);
|
|
482
|
+
const schema = parsed.schema ?? "public";
|
|
483
|
+
const operation = parsed.operation ?? "DELETE";
|
|
484
|
+
const sourceQName = qualifiedName(schema, parsed.table);
|
|
485
|
+
// Cascade simulator must include ALL schemas for accurate cascade path tracing
|
|
486
|
+
const [fks, tables] = await Promise.all([
|
|
487
|
+
fetchForeignKeys(adapter, undefined, false),
|
|
488
|
+
fetchTableNodes(adapter, undefined, false),
|
|
489
|
+
]);
|
|
490
|
+
const tableMap = new Map(tables.map((t) => [qualifiedName(t.schema, t.table), t]));
|
|
491
|
+
// Check if source table exists
|
|
492
|
+
if (!tableMap.has(sourceQName)) {
|
|
493
|
+
return {
|
|
494
|
+
success: false,
|
|
495
|
+
sourceTable: sourceQName,
|
|
496
|
+
operation,
|
|
497
|
+
affectedTables: [],
|
|
498
|
+
severity: "low",
|
|
499
|
+
stats: {
|
|
500
|
+
totalTablesAffected: 0,
|
|
501
|
+
cascadeActions: 0,
|
|
502
|
+
blockingActions: 0,
|
|
503
|
+
setNullActions: 0,
|
|
504
|
+
maxDepth: 0,
|
|
505
|
+
},
|
|
506
|
+
error: `Table '${sourceQName}' not found. Use pg_list_tables to verify.`,
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
// Build reverse adjacency: for each table, find what references it
|
|
510
|
+
// (which tables have FKs pointing TO this table)
|
|
511
|
+
const referencedBy = new Map();
|
|
512
|
+
for (const fk of fks) {
|
|
513
|
+
const to = qualifiedName(fk.toSchema, fk.toTable);
|
|
514
|
+
const existing = referencedBy.get(to) ?? [];
|
|
515
|
+
existing.push(fk);
|
|
516
|
+
referencedBy.set(to, existing);
|
|
517
|
+
}
|
|
518
|
+
const affected = [];
|
|
519
|
+
const visited = new Set();
|
|
520
|
+
const queue = [{ tableName: sourceQName, path: [sourceQName], depth: 0 }];
|
|
521
|
+
visited.add(sourceQName);
|
|
522
|
+
let cascadeActions = 0;
|
|
523
|
+
let blockingActions = 0;
|
|
524
|
+
let setNullActions = 0;
|
|
525
|
+
while (queue.length > 0) {
|
|
526
|
+
const current = queue.shift();
|
|
527
|
+
if (current === undefined)
|
|
528
|
+
break;
|
|
529
|
+
const refs = referencedBy.get(current.tableName) ?? [];
|
|
530
|
+
for (const ref of refs) {
|
|
531
|
+
const refQName = qualifiedName(ref.fromSchema, ref.fromTable);
|
|
532
|
+
if (visited.has(refQName))
|
|
533
|
+
continue;
|
|
534
|
+
visited.add(refQName);
|
|
535
|
+
const action = operation === "DELETE" ? ref.onDelete : "CASCADE";
|
|
536
|
+
const tableInfo = tableMap.get(refQName);
|
|
537
|
+
if (action === "CASCADE") {
|
|
538
|
+
cascadeActions++;
|
|
539
|
+
affected.push({
|
|
540
|
+
table: ref.fromTable,
|
|
541
|
+
schema: ref.fromSchema,
|
|
542
|
+
action: "CASCADE",
|
|
543
|
+
estimatedRows: tableInfo?.rowCount,
|
|
544
|
+
path: [...current.path, refQName],
|
|
545
|
+
depth: current.depth + 1,
|
|
546
|
+
});
|
|
547
|
+
// Continue traversal for cascade
|
|
548
|
+
queue.push({
|
|
549
|
+
tableName: refQName,
|
|
550
|
+
path: [...current.path, refQName],
|
|
551
|
+
depth: current.depth + 1,
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
else if (action === "RESTRICT" || action === "NO ACTION") {
|
|
555
|
+
blockingActions++;
|
|
556
|
+
affected.push({
|
|
557
|
+
table: ref.fromTable,
|
|
558
|
+
schema: ref.fromSchema,
|
|
559
|
+
action,
|
|
560
|
+
estimatedRows: tableInfo?.rowCount,
|
|
561
|
+
path: [...current.path, refQName],
|
|
562
|
+
depth: current.depth + 1,
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
else if (action === "SET NULL" || action === "SET DEFAULT") {
|
|
566
|
+
setNullActions++;
|
|
567
|
+
affected.push({
|
|
568
|
+
table: ref.fromTable,
|
|
569
|
+
schema: ref.fromSchema,
|
|
570
|
+
action,
|
|
571
|
+
estimatedRows: tableInfo?.rowCount,
|
|
572
|
+
path: [...current.path, refQName],
|
|
573
|
+
depth: current.depth + 1,
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
const maxDepth = affected.reduce((max, a) => Math.max(max, a.depth), 0);
|
|
579
|
+
// Severity assessment
|
|
580
|
+
let severity;
|
|
581
|
+
if (blockingActions > 0) {
|
|
582
|
+
severity = "critical"; // Operation will fail
|
|
583
|
+
}
|
|
584
|
+
else if (operation !== "DELETE" && cascadeActions > 0) {
|
|
585
|
+
severity = "critical"; // DROP/TRUNCATE force-cascades everything
|
|
586
|
+
}
|
|
587
|
+
else if (cascadeActions > 5 || maxDepth > 3) {
|
|
588
|
+
severity = "high";
|
|
589
|
+
}
|
|
590
|
+
else if (cascadeActions > 0) {
|
|
591
|
+
severity = "medium";
|
|
592
|
+
}
|
|
593
|
+
else {
|
|
594
|
+
severity = "low";
|
|
595
|
+
}
|
|
596
|
+
return {
|
|
597
|
+
sourceTable: sourceQName,
|
|
598
|
+
operation,
|
|
599
|
+
affectedTables: affected,
|
|
600
|
+
severity,
|
|
601
|
+
stats: {
|
|
602
|
+
totalTablesAffected: affected.length,
|
|
603
|
+
cascadeActions,
|
|
604
|
+
blockingActions,
|
|
605
|
+
setNullActions,
|
|
606
|
+
maxDepth,
|
|
607
|
+
},
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
catch (error) {
|
|
611
|
+
return {
|
|
612
|
+
success: false,
|
|
613
|
+
error: formatPostgresError(error, {
|
|
614
|
+
tool: "pg_cascade_simulator",
|
|
615
|
+
}),
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
},
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
//# sourceMappingURL=graph.js.map
|