@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.
Files changed (518) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +119 -46
  3. package/dist/__tests__/benchmarks/codemode.bench.js +3 -3
  4. package/dist/__tests__/benchmarks/codemode.bench.js.map +1 -1
  5. package/dist/__tests__/benchmarks/connection-pool.bench.js +3 -3
  6. package/dist/__tests__/benchmarks/connection-pool.bench.js.map +1 -1
  7. package/dist/__tests__/benchmarks/introspection-migration.bench.d.ts +11 -0
  8. package/dist/__tests__/benchmarks/introspection-migration.bench.d.ts.map +1 -0
  9. package/dist/__tests__/benchmarks/introspection-migration.bench.js +143 -0
  10. package/dist/__tests__/benchmarks/introspection-migration.bench.js.map +1 -0
  11. package/dist/__tests__/benchmarks/resource-prompts.bench.js +0 -64
  12. package/dist/__tests__/benchmarks/resource-prompts.bench.js.map +1 -1
  13. package/dist/__tests__/benchmarks/schema-parsing.bench.js +5 -5
  14. package/dist/__tests__/benchmarks/schema-parsing.bench.js.map +1 -1
  15. package/dist/__tests__/benchmarks/tool-filtering.bench.js +17 -8
  16. package/dist/__tests__/benchmarks/tool-filtering.bench.js.map +1 -1
  17. package/dist/__tests__/mocks/adapter.d.ts.map +1 -1
  18. package/dist/__tests__/mocks/adapter.js +2 -1
  19. package/dist/__tests__/mocks/adapter.js.map +1 -1
  20. package/dist/adapters/DatabaseAdapter.d.ts +6 -5
  21. package/dist/adapters/DatabaseAdapter.d.ts.map +1 -1
  22. package/dist/adapters/DatabaseAdapter.js +11 -20
  23. package/dist/adapters/DatabaseAdapter.js.map +1 -1
  24. package/dist/adapters/postgresql/PostgresAdapter.d.ts +5 -26
  25. package/dist/adapters/postgresql/PostgresAdapter.d.ts.map +1 -1
  26. package/dist/adapters/postgresql/PostgresAdapter.js +31 -526
  27. package/dist/adapters/postgresql/PostgresAdapter.js.map +1 -1
  28. package/dist/adapters/postgresql/prompts/index.js +1 -1
  29. package/dist/adapters/postgresql/prompts/index.js.map +1 -1
  30. package/dist/adapters/postgresql/resources/index.d.ts +1 -1
  31. package/dist/adapters/postgresql/resources/index.js +3 -3
  32. package/dist/adapters/postgresql/resources/index.js.map +1 -1
  33. package/dist/adapters/postgresql/schema-operations.d.ts +71 -0
  34. package/dist/adapters/postgresql/schema-operations.d.ts.map +1 -0
  35. package/dist/adapters/postgresql/schema-operations.js +561 -0
  36. package/dist/adapters/postgresql/schema-operations.js.map +1 -0
  37. package/dist/adapters/postgresql/schemas/admin.d.ts +4 -4
  38. package/dist/adapters/postgresql/schemas/admin.js +4 -4
  39. package/dist/adapters/postgresql/schemas/admin.js.map +1 -1
  40. package/dist/adapters/postgresql/schemas/backup.d.ts +2 -2
  41. package/dist/adapters/postgresql/schemas/backup.d.ts.map +1 -1
  42. package/dist/adapters/postgresql/schemas/backup.js +1 -3
  43. package/dist/adapters/postgresql/schemas/backup.js.map +1 -1
  44. package/dist/adapters/postgresql/schemas/core/index.d.ts +6 -0
  45. package/dist/adapters/postgresql/schemas/core/index.d.ts.map +1 -0
  46. package/dist/adapters/postgresql/schemas/core/index.js +6 -0
  47. package/dist/adapters/postgresql/schemas/core/index.js.map +1 -0
  48. package/dist/adapters/postgresql/schemas/{core.d.ts → core/queries.d.ts} +16 -171
  49. package/dist/adapters/postgresql/schemas/core/queries.d.ts.map +1 -0
  50. package/dist/adapters/postgresql/schemas/{core.js → core/queries.js} +5 -213
  51. package/dist/adapters/postgresql/schemas/core/queries.js.map +1 -0
  52. package/dist/adapters/postgresql/schemas/core/transactions.d.ts +149 -0
  53. package/dist/adapters/postgresql/schemas/core/transactions.d.ts.map +1 -0
  54. package/dist/adapters/postgresql/schemas/core/transactions.js +239 -0
  55. package/dist/adapters/postgresql/schemas/core/transactions.js.map +1 -0
  56. package/dist/adapters/postgresql/schemas/cron.d.ts +12 -12
  57. package/dist/adapters/postgresql/schemas/cron.d.ts.map +1 -1
  58. package/dist/adapters/postgresql/schemas/cron.js +38 -10
  59. package/dist/adapters/postgresql/schemas/cron.js.map +1 -1
  60. package/dist/adapters/postgresql/schemas/extensions/citext.d.ts +222 -0
  61. package/dist/adapters/postgresql/schemas/extensions/citext.d.ts.map +1 -0
  62. package/dist/adapters/postgresql/schemas/extensions/citext.js +306 -0
  63. package/dist/adapters/postgresql/schemas/extensions/citext.js.map +1 -0
  64. package/dist/adapters/postgresql/schemas/extensions/index.d.ts +15 -0
  65. package/dist/adapters/postgresql/schemas/extensions/index.d.ts.map +1 -0
  66. package/dist/adapters/postgresql/schemas/extensions/index.js +20 -0
  67. package/dist/adapters/postgresql/schemas/extensions/index.js.map +1 -0
  68. package/dist/adapters/postgresql/schemas/extensions/kcache.d.ts +164 -0
  69. package/dist/adapters/postgresql/schemas/extensions/kcache.d.ts.map +1 -0
  70. package/dist/adapters/postgresql/schemas/extensions/kcache.js +225 -0
  71. package/dist/adapters/postgresql/schemas/extensions/kcache.js.map +1 -0
  72. package/dist/adapters/postgresql/schemas/extensions/ltree.d.ts +253 -0
  73. package/dist/adapters/postgresql/schemas/extensions/ltree.d.ts.map +1 -0
  74. package/dist/adapters/postgresql/schemas/extensions/ltree.js +430 -0
  75. package/dist/adapters/postgresql/schemas/extensions/ltree.js.map +1 -0
  76. package/dist/adapters/postgresql/schemas/extensions/pgcrypto.d.ts +251 -0
  77. package/dist/adapters/postgresql/schemas/extensions/pgcrypto.d.ts.map +1 -0
  78. package/dist/adapters/postgresql/schemas/extensions/pgcrypto.js +294 -0
  79. package/dist/adapters/postgresql/schemas/extensions/pgcrypto.js.map +1 -0
  80. package/dist/adapters/postgresql/schemas/extensions/shared.d.ts +10 -0
  81. package/dist/adapters/postgresql/schemas/extensions/shared.d.ts.map +1 -0
  82. package/dist/adapters/postgresql/schemas/extensions/shared.js +15 -0
  83. package/dist/adapters/postgresql/schemas/extensions/shared.js.map +1 -0
  84. package/dist/adapters/postgresql/schemas/index.d.ts +6 -6
  85. package/dist/adapters/postgresql/schemas/index.d.ts.map +1 -1
  86. package/dist/adapters/postgresql/schemas/index.js +8 -8
  87. package/dist/adapters/postgresql/schemas/index.js.map +1 -1
  88. package/dist/adapters/postgresql/schemas/introspection.d.ts +19 -42
  89. package/dist/adapters/postgresql/schemas/introspection.d.ts.map +1 -1
  90. package/dist/adapters/postgresql/schemas/introspection.js +72 -27
  91. package/dist/adapters/postgresql/schemas/introspection.js.map +1 -1
  92. package/dist/adapters/postgresql/schemas/jsonb/advanced.d.ts +270 -0
  93. package/dist/adapters/postgresql/schemas/jsonb/advanced.d.ts.map +1 -0
  94. package/dist/adapters/postgresql/schemas/jsonb/advanced.js +371 -0
  95. package/dist/adapters/postgresql/schemas/jsonb/advanced.js.map +1 -0
  96. package/dist/adapters/postgresql/schemas/jsonb/basic.d.ts +283 -0
  97. package/dist/adapters/postgresql/schemas/jsonb/basic.d.ts.map +1 -0
  98. package/dist/adapters/postgresql/schemas/jsonb/basic.js +456 -0
  99. package/dist/adapters/postgresql/schemas/jsonb/basic.js.map +1 -0
  100. package/dist/adapters/postgresql/schemas/jsonb/index.d.ts +6 -0
  101. package/dist/adapters/postgresql/schemas/jsonb/index.d.ts.map +1 -0
  102. package/dist/adapters/postgresql/schemas/jsonb/index.js +6 -0
  103. package/dist/adapters/postgresql/schemas/jsonb/index.js.map +1 -0
  104. package/dist/adapters/postgresql/schemas/monitoring.d.ts +4 -4
  105. package/dist/adapters/postgresql/schemas/monitoring.js +2 -2
  106. package/dist/adapters/postgresql/schemas/monitoring.js.map +1 -1
  107. package/dist/adapters/postgresql/schemas/partitioning.d.ts +14 -14
  108. package/dist/adapters/postgresql/schemas/partitioning.d.ts.map +1 -1
  109. package/dist/adapters/postgresql/schemas/partitioning.js +64 -46
  110. package/dist/adapters/postgresql/schemas/partitioning.js.map +1 -1
  111. package/dist/adapters/postgresql/schemas/partman.d.ts +16 -14
  112. package/dist/adapters/postgresql/schemas/partman.d.ts.map +1 -1
  113. package/dist/adapters/postgresql/schemas/partman.js +9 -9
  114. package/dist/adapters/postgresql/schemas/partman.js.map +1 -1
  115. package/dist/adapters/postgresql/schemas/postgis/advanced.d.ts +429 -0
  116. package/dist/adapters/postgresql/schemas/postgis/advanced.d.ts.map +1 -0
  117. package/dist/adapters/postgresql/schemas/postgis/advanced.js +495 -0
  118. package/dist/adapters/postgresql/schemas/postgis/advanced.js.map +1 -0
  119. package/dist/adapters/postgresql/schemas/{postgis.d.ts → postgis/basic.d.ts} +1 -423
  120. package/dist/adapters/postgresql/schemas/postgis/basic.d.ts.map +1 -0
  121. package/dist/adapters/postgresql/schemas/{postgis.js → postgis/basic.js} +1 -486
  122. package/dist/adapters/postgresql/schemas/postgis/basic.js.map +1 -0
  123. package/dist/adapters/postgresql/schemas/postgis/index.d.ts +6 -0
  124. package/dist/adapters/postgresql/schemas/postgis/index.d.ts.map +1 -0
  125. package/dist/adapters/postgresql/schemas/postgis/index.js +6 -0
  126. package/dist/adapters/postgresql/schemas/postgis/index.js.map +1 -0
  127. package/dist/adapters/postgresql/schemas/schema-mgmt.d.ts +35 -25
  128. package/dist/adapters/postgresql/schemas/schema-mgmt.d.ts.map +1 -1
  129. package/dist/adapters/postgresql/schemas/schema-mgmt.js +57 -19
  130. package/dist/adapters/postgresql/schemas/schema-mgmt.js.map +1 -1
  131. package/dist/adapters/postgresql/schemas/stats/index.d.ts +6 -0
  132. package/dist/adapters/postgresql/schemas/stats/index.d.ts.map +1 -0
  133. package/dist/adapters/postgresql/schemas/stats/index.js +6 -0
  134. package/dist/adapters/postgresql/schemas/stats/index.js.map +1 -0
  135. package/dist/adapters/postgresql/schemas/stats/input.d.ts +260 -0
  136. package/dist/adapters/postgresql/schemas/stats/input.d.ts.map +1 -0
  137. package/dist/adapters/postgresql/schemas/{stats.js → stats/input.js} +2 -331
  138. package/dist/adapters/postgresql/schemas/stats/input.js.map +1 -0
  139. package/dist/adapters/postgresql/schemas/{stats.d.ts → stats/output.d.ts} +3 -246
  140. package/dist/adapters/postgresql/schemas/stats/output.d.ts.map +1 -0
  141. package/dist/adapters/postgresql/schemas/stats/output.js +334 -0
  142. package/dist/adapters/postgresql/schemas/stats/output.js.map +1 -0
  143. package/dist/adapters/postgresql/schemas/text-search.d.ts +18 -18
  144. package/dist/adapters/postgresql/schemas/text-search.d.ts.map +1 -1
  145. package/dist/adapters/postgresql/schemas/text-search.js +12 -27
  146. package/dist/adapters/postgresql/schemas/text-search.js.map +1 -1
  147. package/dist/adapters/postgresql/schemas/vector.d.ts +10 -10
  148. package/dist/adapters/postgresql/schemas/vector.d.ts.map +1 -1
  149. package/dist/adapters/postgresql/schemas/vector.js +9 -15
  150. package/dist/adapters/postgresql/schemas/vector.js.map +1 -1
  151. package/dist/adapters/postgresql/tools/backup/dump.d.ts.map +1 -1
  152. package/dist/adapters/postgresql/tools/backup/dump.js +95 -76
  153. package/dist/adapters/postgresql/tools/backup/dump.js.map +1 -1
  154. package/dist/adapters/postgresql/tools/backup/planning.d.ts.map +1 -1
  155. package/dist/adapters/postgresql/tools/backup/planning.js +345 -287
  156. package/dist/adapters/postgresql/tools/backup/planning.js.map +1 -1
  157. package/dist/adapters/postgresql/tools/citext/analysis.d.ts +24 -0
  158. package/dist/adapters/postgresql/tools/citext/analysis.d.ts.map +1 -0
  159. package/dist/adapters/postgresql/tools/{citext.js → citext/analysis.js} +50 -232
  160. package/dist/adapters/postgresql/tools/citext/analysis.js.map +1 -0
  161. package/dist/adapters/postgresql/tools/citext/index.d.ts +15 -0
  162. package/dist/adapters/postgresql/tools/citext/index.d.ts.map +1 -0
  163. package/dist/adapters/postgresql/tools/citext/index.js +23 -0
  164. package/dist/adapters/postgresql/tools/citext/index.js.map +1 -0
  165. package/dist/adapters/postgresql/tools/citext/setup.d.ts +16 -0
  166. package/dist/adapters/postgresql/tools/citext/setup.d.ts.map +1 -0
  167. package/dist/adapters/postgresql/tools/citext/setup.js +193 -0
  168. package/dist/adapters/postgresql/tools/citext/setup.js.map +1 -0
  169. package/dist/adapters/postgresql/tools/codemode/index.js +1 -1
  170. package/dist/adapters/postgresql/tools/codemode/index.js.map +1 -1
  171. package/dist/adapters/postgresql/tools/core/convenience.d.ts +12 -22
  172. package/dist/adapters/postgresql/tools/core/convenience.d.ts.map +1 -1
  173. package/dist/adapters/postgresql/tools/core/convenience.js +100 -210
  174. package/dist/adapters/postgresql/tools/core/convenience.js.map +1 -1
  175. package/dist/adapters/postgresql/tools/core/error-helpers.d.ts +1 -0
  176. package/dist/adapters/postgresql/tools/core/error-helpers.d.ts.map +1 -1
  177. package/dist/adapters/postgresql/tools/core/error-helpers.js +8 -1
  178. package/dist/adapters/postgresql/tools/core/error-helpers.js.map +1 -1
  179. package/dist/adapters/postgresql/tools/core/health.d.ts.map +1 -1
  180. package/dist/adapters/postgresql/tools/core/health.js +124 -114
  181. package/dist/adapters/postgresql/tools/core/health.js.map +1 -1
  182. package/dist/adapters/postgresql/tools/core/index.d.ts +2 -1
  183. package/dist/adapters/postgresql/tools/core/index.d.ts.map +1 -1
  184. package/dist/adapters/postgresql/tools/core/index.js +3 -2
  185. package/dist/adapters/postgresql/tools/core/index.js.map +1 -1
  186. package/dist/adapters/postgresql/tools/core/indexes.d.ts.map +1 -1
  187. package/dist/adapters/postgresql/tools/core/indexes.js +151 -127
  188. package/dist/adapters/postgresql/tools/core/indexes.js.map +1 -1
  189. package/dist/adapters/postgresql/tools/core/objects.d.ts.map +1 -1
  190. package/dist/adapters/postgresql/tools/core/objects.js +186 -161
  191. package/dist/adapters/postgresql/tools/core/objects.js.map +1 -1
  192. package/dist/adapters/postgresql/tools/core/query.d.ts.map +1 -1
  193. package/dist/adapters/postgresql/tools/core/query.js +37 -25
  194. package/dist/adapters/postgresql/tools/core/query.js.map +1 -1
  195. package/dist/adapters/postgresql/tools/core/schemas.d.ts +6 -3
  196. package/dist/adapters/postgresql/tools/core/schemas.d.ts.map +1 -1
  197. package/dist/adapters/postgresql/tools/core/schemas.js +11 -2
  198. package/dist/adapters/postgresql/tools/core/schemas.js.map +1 -1
  199. package/dist/adapters/postgresql/tools/core/tables.d.ts.map +1 -1
  200. package/dist/adapters/postgresql/tools/core/tables.js +156 -129
  201. package/dist/adapters/postgresql/tools/core/tables.js.map +1 -1
  202. package/dist/adapters/postgresql/tools/core/utility.d.ts +26 -0
  203. package/dist/adapters/postgresql/tools/core/utility.d.ts.map +1 -0
  204. package/dist/adapters/postgresql/tools/core/utility.js +174 -0
  205. package/dist/adapters/postgresql/tools/core/utility.js.map +1 -0
  206. package/dist/adapters/postgresql/tools/cron.js +90 -43
  207. package/dist/adapters/postgresql/tools/cron.js.map +1 -1
  208. package/dist/adapters/postgresql/tools/introspection/analysis.d.ts +12 -0
  209. package/dist/adapters/postgresql/tools/introspection/analysis.d.ts.map +1 -0
  210. package/dist/adapters/postgresql/tools/introspection/analysis.js +605 -0
  211. package/dist/adapters/postgresql/tools/introspection/analysis.js.map +1 -0
  212. package/dist/adapters/postgresql/tools/introspection/graph.d.ts +55 -0
  213. package/dist/adapters/postgresql/tools/introspection/graph.d.ts.map +1 -0
  214. package/dist/adapters/postgresql/tools/introspection/graph.js +621 -0
  215. package/dist/adapters/postgresql/tools/introspection/graph.js.map +1 -0
  216. package/dist/adapters/postgresql/tools/introspection/index.d.ts +21 -0
  217. package/dist/adapters/postgresql/tools/introspection/index.d.ts.map +1 -0
  218. package/dist/adapters/postgresql/tools/introspection/index.js +31 -0
  219. package/dist/adapters/postgresql/tools/introspection/index.js.map +1 -0
  220. package/dist/adapters/postgresql/tools/introspection/migration.d.ts +15 -0
  221. package/dist/adapters/postgresql/tools/introspection/migration.d.ts.map +1 -0
  222. package/dist/adapters/postgresql/tools/introspection/migration.js +575 -0
  223. package/dist/adapters/postgresql/tools/introspection/migration.js.map +1 -0
  224. package/dist/adapters/postgresql/tools/jsonb/analytics.d.ts +20 -0
  225. package/dist/adapters/postgresql/tools/jsonb/analytics.d.ts.map +1 -0
  226. package/dist/adapters/postgresql/tools/jsonb/analytics.js +367 -0
  227. package/dist/adapters/postgresql/tools/jsonb/analytics.js.map +1 -0
  228. package/dist/adapters/postgresql/tools/jsonb/index.d.ts +4 -2
  229. package/dist/adapters/postgresql/tools/jsonb/index.d.ts.map +1 -1
  230. package/dist/adapters/postgresql/tools/jsonb/index.js +8 -4
  231. package/dist/adapters/postgresql/tools/jsonb/index.js.map +1 -1
  232. package/dist/adapters/postgresql/tools/jsonb/read.d.ts +38 -0
  233. package/dist/adapters/postgresql/tools/jsonb/read.d.ts.map +1 -0
  234. package/dist/adapters/postgresql/tools/jsonb/{basic.js → read.js} +41 -482
  235. package/dist/adapters/postgresql/tools/jsonb/read.js.map +1 -0
  236. package/dist/adapters/postgresql/tools/jsonb/{advanced.d.ts → transform.d.ts} +1 -13
  237. package/dist/adapters/postgresql/tools/jsonb/transform.d.ts.map +1 -0
  238. package/dist/adapters/postgresql/tools/jsonb/{advanced.js → transform.js} +26 -357
  239. package/dist/adapters/postgresql/tools/jsonb/transform.js.map +1 -0
  240. package/dist/adapters/postgresql/tools/jsonb/write.d.ts +14 -0
  241. package/dist/adapters/postgresql/tools/jsonb/write.d.ts.map +1 -0
  242. package/dist/adapters/postgresql/tools/jsonb/write.js +468 -0
  243. package/dist/adapters/postgresql/tools/jsonb/write.js.map +1 -0
  244. package/dist/adapters/postgresql/tools/kcache.d.ts.map +1 -1
  245. package/dist/adapters/postgresql/tools/kcache.js +116 -51
  246. package/dist/adapters/postgresql/tools/kcache.js.map +1 -1
  247. package/dist/adapters/postgresql/tools/ltree.js +346 -260
  248. package/dist/adapters/postgresql/tools/ltree.js.map +1 -1
  249. package/dist/adapters/postgresql/tools/migration/index.d.ts +15 -0
  250. package/dist/adapters/postgresql/tools/migration/index.d.ts.map +1 -0
  251. package/dist/adapters/postgresql/tools/migration/index.js +23 -0
  252. package/dist/adapters/postgresql/tools/migration/index.js.map +1 -0
  253. package/dist/adapters/postgresql/tools/monitoring/analysis.d.ts +15 -0
  254. package/dist/adapters/postgresql/tools/monitoring/analysis.d.ts.map +1 -0
  255. package/dist/adapters/postgresql/tools/{monitoring.js → monitoring/analysis.js} +24 -359
  256. package/dist/adapters/postgresql/tools/monitoring/analysis.js.map +1 -0
  257. package/dist/adapters/postgresql/tools/monitoring/basic.d.ts +17 -0
  258. package/dist/adapters/postgresql/tools/monitoring/basic.d.ts.map +1 -0
  259. package/dist/adapters/postgresql/tools/monitoring/basic.js +432 -0
  260. package/dist/adapters/postgresql/tools/monitoring/basic.js.map +1 -0
  261. package/dist/adapters/postgresql/tools/monitoring/index.d.ts +16 -0
  262. package/dist/adapters/postgresql/tools/monitoring/index.d.ts.map +1 -0
  263. package/dist/adapters/postgresql/tools/monitoring/index.js +31 -0
  264. package/dist/adapters/postgresql/tools/monitoring/index.js.map +1 -0
  265. package/dist/adapters/postgresql/tools/partitioning/index.d.ts +15 -0
  266. package/dist/adapters/postgresql/tools/partitioning/index.d.ts.map +1 -0
  267. package/dist/adapters/postgresql/tools/partitioning/index.js +23 -0
  268. package/dist/adapters/postgresql/tools/partitioning/index.js.map +1 -0
  269. package/dist/adapters/postgresql/tools/partitioning/info.d.ts +11 -0
  270. package/dist/adapters/postgresql/tools/partitioning/info.d.ts.map +1 -0
  271. package/dist/adapters/postgresql/tools/partitioning/info.js +302 -0
  272. package/dist/adapters/postgresql/tools/partitioning/info.js.map +1 -0
  273. package/dist/adapters/postgresql/tools/partitioning/management.d.ts +28 -0
  274. package/dist/adapters/postgresql/tools/partitioning/management.d.ts.map +1 -0
  275. package/dist/adapters/postgresql/tools/{partitioning.js → partitioning/management.js} +48 -307
  276. package/dist/adapters/postgresql/tools/partitioning/management.js.map +1 -0
  277. package/dist/adapters/postgresql/tools/partman/helpers.d.ts +29 -0
  278. package/dist/adapters/postgresql/tools/partman/helpers.d.ts.map +1 -0
  279. package/dist/adapters/postgresql/tools/partman/helpers.js +59 -0
  280. package/dist/adapters/postgresql/tools/partman/helpers.js.map +1 -0
  281. package/dist/adapters/postgresql/tools/partman/index.d.ts +2 -1
  282. package/dist/adapters/postgresql/tools/partman/index.d.ts.map +1 -1
  283. package/dist/adapters/postgresql/tools/partman/index.js +4 -2
  284. package/dist/adapters/postgresql/tools/partman/index.js.map +1 -1
  285. package/dist/adapters/postgresql/tools/partman/maintenance.d.ts +20 -0
  286. package/dist/adapters/postgresql/tools/partman/maintenance.d.ts.map +1 -0
  287. package/dist/adapters/postgresql/tools/partman/maintenance.js +496 -0
  288. package/dist/adapters/postgresql/tools/partman/maintenance.js.map +1 -0
  289. package/dist/adapters/postgresql/tools/partman/management.d.ts.map +1 -1
  290. package/dist/adapters/postgresql/tools/partman/management.js +438 -383
  291. package/dist/adapters/postgresql/tools/partman/management.js.map +1 -1
  292. package/dist/adapters/postgresql/tools/partman/operations.d.ts +1 -13
  293. package/dist/adapters/postgresql/tools/partman/operations.d.ts.map +1 -1
  294. package/dist/adapters/postgresql/tools/partman/operations.js +171 -652
  295. package/dist/adapters/postgresql/tools/partman/operations.js.map +1 -1
  296. package/dist/adapters/postgresql/tools/performance/analysis.d.ts.map +1 -1
  297. package/dist/adapters/postgresql/tools/performance/analysis.js +69 -42
  298. package/dist/adapters/postgresql/tools/performance/analysis.js.map +1 -1
  299. package/dist/adapters/postgresql/tools/performance/anomaly-detection.d.ts +18 -0
  300. package/dist/adapters/postgresql/tools/performance/anomaly-detection.d.ts.map +1 -0
  301. package/dist/adapters/postgresql/tools/performance/anomaly-detection.js +533 -0
  302. package/dist/adapters/postgresql/tools/performance/anomaly-detection.js.map +1 -0
  303. package/dist/adapters/postgresql/tools/performance/diagnostics.d.ts +11 -0
  304. package/dist/adapters/postgresql/tools/performance/diagnostics.d.ts.map +1 -0
  305. package/dist/adapters/postgresql/tools/performance/diagnostics.js +332 -0
  306. package/dist/adapters/postgresql/tools/performance/diagnostics.js.map +1 -0
  307. package/dist/adapters/postgresql/tools/performance/index.d.ts +1 -1
  308. package/dist/adapters/postgresql/tools/performance/index.d.ts.map +1 -1
  309. package/dist/adapters/postgresql/tools/performance/index.js +7 -1
  310. package/dist/adapters/postgresql/tools/performance/index.js.map +1 -1
  311. package/dist/adapters/postgresql/tools/performance/monitoring.d.ts.map +1 -1
  312. package/dist/adapters/postgresql/tools/performance/monitoring.js +80 -55
  313. package/dist/adapters/postgresql/tools/performance/monitoring.js.map +1 -1
  314. package/dist/adapters/postgresql/tools/performance/optimization.d.ts.map +1 -1
  315. package/dist/adapters/postgresql/tools/performance/optimization.js +18 -11
  316. package/dist/adapters/postgresql/tools/performance/optimization.js.map +1 -1
  317. package/dist/adapters/postgresql/tools/performance/stats.d.ts.map +1 -1
  318. package/dist/adapters/postgresql/tools/performance/stats.js +439 -318
  319. package/dist/adapters/postgresql/tools/performance/stats.js.map +1 -1
  320. package/dist/adapters/postgresql/tools/pgcrypto.d.ts.map +1 -1
  321. package/dist/adapters/postgresql/tools/pgcrypto.js +45 -77
  322. package/dist/adapters/postgresql/tools/pgcrypto.js.map +1 -1
  323. package/dist/adapters/postgresql/tools/postgis/basic.d.ts.map +1 -1
  324. package/dist/adapters/postgresql/tools/postgis/basic.js +121 -93
  325. package/dist/adapters/postgresql/tools/postgis/basic.js.map +1 -1
  326. package/dist/adapters/postgresql/tools/schema/index.d.ts +16 -0
  327. package/dist/adapters/postgresql/tools/schema/index.d.ts.map +1 -0
  328. package/dist/adapters/postgresql/tools/schema/index.js +32 -0
  329. package/dist/adapters/postgresql/tools/schema/index.js.map +1 -0
  330. package/dist/adapters/postgresql/tools/schema/objects.d.ts +15 -0
  331. package/dist/adapters/postgresql/tools/schema/objects.d.ts.map +1 -0
  332. package/dist/adapters/postgresql/tools/schema/objects.js +378 -0
  333. package/dist/adapters/postgresql/tools/schema/objects.js.map +1 -0
  334. package/dist/adapters/postgresql/tools/schema/views.d.ts +15 -0
  335. package/dist/adapters/postgresql/tools/schema/views.d.ts.map +1 -0
  336. package/dist/adapters/postgresql/tools/{schema.js → schema/views.js} +64 -386
  337. package/dist/adapters/postgresql/tools/schema/views.js.map +1 -0
  338. package/dist/adapters/postgresql/tools/stats/advanced.d.ts.map +1 -1
  339. package/dist/adapters/postgresql/tools/stats/advanced.js +1 -218
  340. package/dist/adapters/postgresql/tools/stats/advanced.js.map +1 -1
  341. package/dist/adapters/postgresql/tools/stats/math-utils.d.ts +33 -0
  342. package/dist/adapters/postgresql/tools/stats/math-utils.d.ts.map +1 -0
  343. package/dist/adapters/postgresql/tools/stats/math-utils.js +225 -0
  344. package/dist/adapters/postgresql/tools/stats/math-utils.js.map +1 -0
  345. package/dist/adapters/postgresql/tools/text/index.d.ts +16 -0
  346. package/dist/adapters/postgresql/tools/text/index.d.ts.map +1 -0
  347. package/dist/adapters/postgresql/tools/text/index.js +33 -0
  348. package/dist/adapters/postgresql/tools/text/index.js.map +1 -0
  349. package/dist/adapters/postgresql/tools/text/matching.d.ts +17 -0
  350. package/dist/adapters/postgresql/tools/text/matching.d.ts.map +1 -0
  351. package/dist/adapters/postgresql/tools/text/matching.js +565 -0
  352. package/dist/adapters/postgresql/tools/text/matching.js.map +1 -0
  353. package/dist/adapters/postgresql/tools/text/search.d.ts +17 -0
  354. package/dist/adapters/postgresql/tools/text/search.d.ts.map +1 -0
  355. package/dist/adapters/postgresql/tools/text/search.js +653 -0
  356. package/dist/adapters/postgresql/tools/text/search.js.map +1 -0
  357. package/dist/adapters/postgresql/tools/transactions.d.ts.map +1 -1
  358. package/dist/adapters/postgresql/tools/transactions.js +11 -27
  359. package/dist/adapters/postgresql/tools/transactions.js.map +1 -1
  360. package/dist/adapters/postgresql/tools/vector/{basic.d.ts → data.d.ts} +10 -8
  361. package/dist/adapters/postgresql/tools/vector/data.d.ts.map +1 -0
  362. package/dist/adapters/postgresql/tools/vector/data.js +540 -0
  363. package/dist/adapters/postgresql/tools/vector/data.js.map +1 -0
  364. package/dist/adapters/postgresql/tools/vector/index.d.ts.map +1 -1
  365. package/dist/adapters/postgresql/tools/vector/index.js +6 -2
  366. package/dist/adapters/postgresql/tools/vector/index.js.map +1 -1
  367. package/dist/adapters/postgresql/tools/vector/management.d.ts +11 -0
  368. package/dist/adapters/postgresql/tools/vector/management.d.ts.map +1 -0
  369. package/dist/adapters/postgresql/tools/vector/management.js +425 -0
  370. package/dist/adapters/postgresql/tools/vector/management.js.map +1 -0
  371. package/dist/adapters/postgresql/tools/vector/query.d.ts +14 -0
  372. package/dist/adapters/postgresql/tools/vector/query.d.ts.map +1 -0
  373. package/dist/adapters/postgresql/tools/vector/query.js +767 -0
  374. package/dist/adapters/postgresql/tools/vector/query.js.map +1 -0
  375. package/dist/adapters/postgresql/tools/vector/{advanced.d.ts → search-advanced.d.ts} +4 -5
  376. package/dist/adapters/postgresql/tools/vector/search-advanced.d.ts.map +1 -0
  377. package/dist/adapters/postgresql/tools/vector/search-advanced.js +626 -0
  378. package/dist/adapters/postgresql/tools/vector/search-advanced.js.map +1 -0
  379. package/dist/auth/scopes.d.ts.map +1 -1
  380. package/dist/auth/scopes.js +3 -1
  381. package/dist/auth/scopes.js.map +1 -1
  382. package/dist/cli/args.d.ts +3 -2
  383. package/dist/cli/args.d.ts.map +1 -1
  384. package/dist/cli/args.js +4 -3
  385. package/dist/cli/args.js.map +1 -1
  386. package/dist/cli.js +16 -4
  387. package/dist/cli.js.map +1 -1
  388. package/dist/codemode/api/aliases.d.ts +14 -0
  389. package/dist/codemode/api/aliases.d.ts.map +1 -0
  390. package/dist/codemode/api/aliases.js +503 -0
  391. package/dist/codemode/api/aliases.js.map +1 -0
  392. package/dist/codemode/api/group-api.d.ts +23 -0
  393. package/dist/codemode/api/group-api.d.ts.map +1 -0
  394. package/dist/codemode/api/group-api.js +179 -0
  395. package/dist/codemode/api/group-api.js.map +1 -0
  396. package/dist/codemode/{api.d.ts → api/index.d.ts} +5 -4
  397. package/dist/codemode/api/index.d.ts.map +1 -0
  398. package/dist/codemode/api/index.js +195 -0
  399. package/dist/codemode/api/index.js.map +1 -0
  400. package/dist/codemode/api/maps.d.ts +47 -0
  401. package/dist/codemode/api/maps.d.ts.map +1 -0
  402. package/dist/codemode/api/maps.js +529 -0
  403. package/dist/codemode/api/maps.js.map +1 -0
  404. package/dist/codemode/api/normalize.d.ts +13 -0
  405. package/dist/codemode/api/normalize.d.ts.map +1 -0
  406. package/dist/codemode/api/normalize.js +120 -0
  407. package/dist/codemode/api/normalize.js.map +1 -0
  408. package/dist/codemode/index.d.ts +1 -1
  409. package/dist/codemode/index.d.ts.map +1 -1
  410. package/dist/codemode/index.js +1 -1
  411. package/dist/codemode/index.js.map +1 -1
  412. package/dist/codemode/sandbox.d.ts.map +1 -1
  413. package/dist/codemode/sandbox.js +8 -25
  414. package/dist/codemode/sandbox.js.map +1 -1
  415. package/dist/filtering/ToolConstants.d.ts +11 -11
  416. package/dist/filtering/ToolConstants.d.ts.map +1 -1
  417. package/dist/filtering/ToolConstants.js +28 -15
  418. package/dist/filtering/ToolConstants.js.map +1 -1
  419. package/dist/filtering/ToolFilter.d.ts +0 -32
  420. package/dist/filtering/ToolFilter.d.ts.map +1 -1
  421. package/dist/filtering/ToolFilter.js +0 -43
  422. package/dist/filtering/ToolFilter.js.map +1 -1
  423. package/dist/server/McpServer.d.ts +1 -1
  424. package/dist/server/McpServer.d.ts.map +1 -1
  425. package/dist/server/McpServer.js +1 -2
  426. package/dist/server/McpServer.js.map +1 -1
  427. package/dist/transports/http.d.ts +55 -10
  428. package/dist/transports/http.d.ts.map +1 -1
  429. package/dist/transports/http.js +301 -50
  430. package/dist/transports/http.js.map +1 -1
  431. package/dist/types/filtering.d.ts +1 -1
  432. package/dist/types/filtering.d.ts.map +1 -1
  433. package/dist/types/index.d.ts +2 -2
  434. package/dist/types/index.d.ts.map +1 -1
  435. package/dist/types/index.js.map +1 -1
  436. package/dist/types/mcp.d.ts +0 -21
  437. package/dist/types/mcp.d.ts.map +1 -1
  438. package/dist/types/schema.d.ts +0 -79
  439. package/dist/types/schema.d.ts.map +1 -1
  440. package/dist/utils/fts-config.d.ts +0 -6
  441. package/dist/utils/fts-config.d.ts.map +1 -1
  442. package/dist/utils/fts-config.js +1 -1
  443. package/dist/utils/fts-config.js.map +1 -1
  444. package/dist/utils/icons.d.ts.map +1 -1
  445. package/dist/utils/icons.js +5 -0
  446. package/dist/utils/icons.js.map +1 -1
  447. package/dist/utils/identifiers.d.ts.map +1 -1
  448. package/dist/utils/identifiers.js +6 -6
  449. package/dist/utils/identifiers.js.map +1 -1
  450. package/dist/utils/logger.d.ts +6 -6
  451. package/dist/utils/logger.d.ts.map +1 -1
  452. package/dist/utils/logger.js +18 -15
  453. package/dist/utils/logger.js.map +1 -1
  454. package/dist/utils/progress-utils.d.ts +3 -14
  455. package/dist/utils/progress-utils.d.ts.map +1 -1
  456. package/dist/utils/progress-utils.js +2 -21
  457. package/dist/utils/progress-utils.js.map +1 -1
  458. package/dist/utils/version.d.ts +9 -0
  459. package/dist/utils/version.d.ts.map +1 -0
  460. package/dist/utils/version.js +12 -0
  461. package/dist/utils/version.js.map +1 -0
  462. package/dist/utils/where-clause.d.ts +4 -0
  463. package/dist/utils/where-clause.d.ts.map +1 -1
  464. package/dist/utils/where-clause.js +16 -0
  465. package/dist/utils/where-clause.js.map +1 -1
  466. package/package.json +6 -4
  467. package/dist/adapters/postgresql/schemas/core.d.ts.map +0 -1
  468. package/dist/adapters/postgresql/schemas/core.js.map +0 -1
  469. package/dist/adapters/postgresql/schemas/extensions.d.ts +0 -852
  470. package/dist/adapters/postgresql/schemas/extensions.d.ts.map +0 -1
  471. package/dist/adapters/postgresql/schemas/extensions.js +0 -1202
  472. package/dist/adapters/postgresql/schemas/extensions.js.map +0 -1
  473. package/dist/adapters/postgresql/schemas/jsonb.d.ts +0 -541
  474. package/dist/adapters/postgresql/schemas/jsonb.d.ts.map +0 -1
  475. package/dist/adapters/postgresql/schemas/jsonb.js +0 -814
  476. package/dist/adapters/postgresql/schemas/jsonb.js.map +0 -1
  477. package/dist/adapters/postgresql/schemas/postgis.d.ts.map +0 -1
  478. package/dist/adapters/postgresql/schemas/postgis.js.map +0 -1
  479. package/dist/adapters/postgresql/schemas/stats.d.ts.map +0 -1
  480. package/dist/adapters/postgresql/schemas/stats.js.map +0 -1
  481. package/dist/adapters/postgresql/tools/citext.d.ts +0 -18
  482. package/dist/adapters/postgresql/tools/citext.d.ts.map +0 -1
  483. package/dist/adapters/postgresql/tools/citext.js.map +0 -1
  484. package/dist/adapters/postgresql/tools/introspection.d.ts +0 -15
  485. package/dist/adapters/postgresql/tools/introspection.d.ts.map +0 -1
  486. package/dist/adapters/postgresql/tools/introspection.js +0 -1682
  487. package/dist/adapters/postgresql/tools/introspection.js.map +0 -1
  488. package/dist/adapters/postgresql/tools/jsonb/advanced.d.ts.map +0 -1
  489. package/dist/adapters/postgresql/tools/jsonb/advanced.js.map +0 -1
  490. package/dist/adapters/postgresql/tools/jsonb/basic.d.ts +0 -20
  491. package/dist/adapters/postgresql/tools/jsonb/basic.d.ts.map +0 -1
  492. package/dist/adapters/postgresql/tools/jsonb/basic.js.map +0 -1
  493. package/dist/adapters/postgresql/tools/monitoring.d.ts +0 -13
  494. package/dist/adapters/postgresql/tools/monitoring.d.ts.map +0 -1
  495. package/dist/adapters/postgresql/tools/monitoring.js.map +0 -1
  496. package/dist/adapters/postgresql/tools/partitioning.d.ts +0 -13
  497. package/dist/adapters/postgresql/tools/partitioning.d.ts.map +0 -1
  498. package/dist/adapters/postgresql/tools/partitioning.js.map +0 -1
  499. package/dist/adapters/postgresql/tools/schema.d.ts +0 -13
  500. package/dist/adapters/postgresql/tools/schema.d.ts.map +0 -1
  501. package/dist/adapters/postgresql/tools/schema.js.map +0 -1
  502. package/dist/adapters/postgresql/tools/text.d.ts +0 -13
  503. package/dist/adapters/postgresql/tools/text.d.ts.map +0 -1
  504. package/dist/adapters/postgresql/tools/text.js +0 -1082
  505. package/dist/adapters/postgresql/tools/text.js.map +0 -1
  506. package/dist/adapters/postgresql/tools/vector/advanced.d.ts.map +0 -1
  507. package/dist/adapters/postgresql/tools/vector/advanced.js +0 -958
  508. package/dist/adapters/postgresql/tools/vector/advanced.js.map +0 -1
  509. package/dist/adapters/postgresql/tools/vector/basic.d.ts.map +0 -1
  510. package/dist/adapters/postgresql/tools/vector/basic.js +0 -1165
  511. package/dist/adapters/postgresql/tools/vector/basic.js.map +0 -1
  512. package/dist/codemode/api.d.ts.map +0 -1
  513. package/dist/codemode/api.js +0 -1544
  514. package/dist/codemode/api.js.map +0 -1
  515. package/dist/utils/promptGenerator.d.ts +0 -20
  516. package/dist/utils/promptGenerator.d.ts.map +0 -1
  517. package/dist/utils/promptGenerator.js +0 -81
  518. package/dist/utils/promptGenerator.js.map +0 -1
@@ -5,7 +5,7 @@
5
5
  import { z } from "zod";
6
6
  import { readOnly, write } from "../../../utils/annotations.js";
7
7
  import { getToolIcons } from "../../../utils/icons.js";
8
- import { parsePostgresError } from "./core/error-helpers.js";
8
+ import { formatPostgresError } from "./core/error-helpers.js";
9
9
  import { LtreeQuerySchema, LtreeQuerySchemaBase, LtreeSubpathSchema, LtreeSubpathSchemaBase, LtreeLcaSchemaBase, LtreeLcaSchema, LtreeMatchSchema, LtreeMatchSchemaBase, LtreeListColumnsSchemaBase, LtreeListColumnsSchema, LtreeConvertColumnSchema, LtreeConvertColumnSchemaBase, LtreeIndexSchema, LtreeIndexSchemaBase,
10
10
  // Output schemas
11
11
  LtreeCreateExtensionOutputSchema, LtreeQueryOutputSchema, LtreeSubpathOutputSchema, LtreeLcaOutputSchema, LtreeMatchOutputSchema, LtreeListColumnsOutputSchema, LtreeConvertColumnOutputSchema, LtreeCreateIndexOutputSchema, } from "../schemas/index.js";
@@ -31,8 +31,18 @@ function createLtreeExtensionTool(adapter) {
31
31
  annotations: write("Create Ltree Extension"),
32
32
  icons: getToolIcons("ltree", write("Create Ltree Extension")),
33
33
  handler: async (_params, _context) => {
34
- await adapter.executeQuery("CREATE EXTENSION IF NOT EXISTS ltree");
35
- return { success: true, message: "ltree extension enabled" };
34
+ try {
35
+ await adapter.executeQuery("CREATE EXTENSION IF NOT EXISTS ltree");
36
+ return { success: true, message: "ltree extension enabled" };
37
+ }
38
+ catch (error) {
39
+ return {
40
+ success: false,
41
+ error: formatPostgresError(error, {
42
+ tool: "pg_ltree_create_extension",
43
+ }),
44
+ };
45
+ }
36
46
  },
37
47
  };
38
48
  }
@@ -46,42 +56,64 @@ function createLtreeQueryTool(adapter) {
46
56
  annotations: readOnly("Query Ltree"),
47
57
  icons: getToolIcons("ltree", readOnly("Query Ltree")),
48
58
  handler: async (params, _context) => {
49
- const { table, column, path, mode, schema, limit } = LtreeQuerySchema.parse(params);
50
- const schemaName = schema ?? "public";
51
- const queryMode = mode ?? "descendants";
52
- const qualifiedTable = `"${schemaName}"."${table}"`;
53
- const limitClause = limit !== undefined ? `LIMIT ${String(limit)}` : "";
54
- // Validate column is ltree type
55
- const colCheck = await adapter.executeQuery(`SELECT udt_name FROM information_schema.columns WHERE table_schema = $1 AND table_name = $2 AND column_name = $3`, [schemaName, table, column]);
56
- if (!colCheck.rows || colCheck.rows.length === 0) {
57
- // Distinguish table-not-found from column-not-found
58
- const tableCheck = await adapter.executeQuery(`SELECT 1 FROM information_schema.tables WHERE table_schema = $1 AND table_name = $2`, [schemaName, table]);
59
- if (!tableCheck.rows || tableCheck.rows.length === 0) {
59
+ try {
60
+ const { table, column, path, mode, schema, limit } = LtreeQuerySchema.parse(params);
61
+ const schemaName = schema ?? "public";
62
+ const queryMode = mode ?? "descendants";
63
+ const qualifiedTable = `"${schemaName}"."${table}"`;
64
+ const limitClause = limit !== undefined ? `LIMIT ${String(limit)}` : "";
65
+ // Validate column is ltree type
66
+ const colCheck = await adapter.executeQuery(`SELECT udt_name FROM information_schema.columns WHERE table_schema = $1 AND table_name = $2 AND column_name = $3`, [schemaName, table, column]);
67
+ if (!colCheck.rows || colCheck.rows.length === 0) {
68
+ // Distinguish table-not-found from column-not-found
69
+ const tableCheck = await adapter.executeQuery(`SELECT 1 FROM information_schema.tables WHERE table_schema = $1 AND table_name = $2`, [schemaName, table]);
70
+ if (!tableCheck.rows || tableCheck.rows.length === 0) {
71
+ return {
72
+ success: false,
73
+ error: `Table ${qualifiedTable} does not exist.`,
74
+ };
75
+ }
60
76
  return {
61
77
  success: false,
62
- error: `Table ${qualifiedTable} does not exist.`,
78
+ error: `Column "${column}" not found in table ${qualifiedTable}.`,
63
79
  };
64
80
  }
65
- return {
66
- success: false,
67
- error: `Column "${column}" not found in table ${qualifiedTable}.`,
68
- };
69
- }
70
- const udtName = colCheck.rows[0]?.["udt_name"];
71
- if (udtName !== "ltree") {
72
- return {
73
- success: false,
74
- error: `Column "${column}" is not an ltree type (found: ${udtName}). Use an ltree column or convert with pg_ltree_convert_column.`,
75
- };
76
- }
77
- // Detect if path contains lquery pattern characters
78
- const isLqueryPattern = /[*?{!@|]/.test(path);
79
- // Get total count when limit is applied for truncation indicators
80
- let totalCount;
81
- if (limit !== undefined) {
82
- let countSql;
81
+ const udtName = colCheck.rows[0]?.["udt_name"];
82
+ if (udtName !== "ltree") {
83
+ return {
84
+ success: false,
85
+ error: `Column "${column}" is not an ltree type (found: ${udtName}). Use an ltree column or convert with pg_ltree_convert_column.`,
86
+ };
87
+ }
88
+ // Detect if path contains lquery pattern characters
89
+ const isLqueryPattern = /[*?{!@|]/.test(path);
90
+ // Get total count when limit is applied for truncation indicators
91
+ let totalCount;
92
+ if (limit !== undefined) {
93
+ let countSql;
94
+ if (isLqueryPattern) {
95
+ countSql = `SELECT COUNT(*)::int as total FROM ${qualifiedTable} WHERE "${column}" ~ $1::lquery`;
96
+ }
97
+ else {
98
+ let operator;
99
+ switch (queryMode) {
100
+ case "ancestors":
101
+ operator = "@>";
102
+ break;
103
+ case "exact":
104
+ operator = "=";
105
+ break;
106
+ default:
107
+ operator = "<@";
108
+ }
109
+ countSql = `SELECT COUNT(*)::int as total FROM ${qualifiedTable} WHERE "${column}" ${operator} $1::ltree`;
110
+ }
111
+ const countResult = await adapter.executeQuery(countSql, [path]);
112
+ totalCount = countResult.rows?.[0]?.["total"];
113
+ }
114
+ let sql;
83
115
  if (isLqueryPattern) {
84
- countSql = `SELECT COUNT(*)::int as total FROM ${qualifiedTable} WHERE "${column}" ~ $1::lquery`;
116
+ sql = `SELECT *, nlevel("${column}") as depth FROM ${qualifiedTable} WHERE "${column}" ~ $1::lquery ORDER BY "${column}" ${limitClause}`;
85
117
  }
86
118
  else {
87
119
  let operator;
@@ -95,50 +127,38 @@ function createLtreeQueryTool(adapter) {
95
127
  default:
96
128
  operator = "<@";
97
129
  }
98
- countSql = `SELECT COUNT(*)::int as total FROM ${qualifiedTable} WHERE "${column}" ${operator} $1::ltree`;
130
+ sql = `SELECT *, nlevel("${column}") as depth FROM ${qualifiedTable} WHERE "${column}" ${operator} $1::ltree ORDER BY "${column}" ${limitClause}`;
99
131
  }
100
- const countResult = await adapter.executeQuery(countSql, [path]);
101
- totalCount = countResult.rows?.[0]?.["total"];
102
- }
103
- let sql;
104
- if (isLqueryPattern) {
105
- // Use lquery pattern matching with ~ operator
106
- sql = `SELECT *, nlevel("${column}") as depth FROM ${qualifiedTable} WHERE "${column}" ~ $1::lquery ORDER BY "${column}" ${limitClause}`;
107
- }
108
- else {
109
- // Use standard ltree hierarchy operators
110
- // @> means "is ancestor of" (left contains right)
111
- // <@ means "is descendant of" (left is contained by right)
112
- let operator;
113
- switch (queryMode) {
114
- // ancestors: column @> path means column contains path, i.e., column is ancestor of path
115
- case "ancestors":
116
- operator = "@>";
117
- break;
118
- case "exact":
119
- operator = "=";
120
- break;
121
- // descendants: column <@ path means column is contained by path, i.e., column is descendant of path
122
- default:
123
- operator = "<@";
132
+ const result = await adapter.executeQuery(sql, [path]);
133
+ const resultCount = result.rows?.length ?? 0;
134
+ const response = {
135
+ path,
136
+ mode: isLqueryPattern ? "pattern" : queryMode,
137
+ isPattern: isLqueryPattern,
138
+ results: result.rows ?? [],
139
+ count: resultCount,
140
+ };
141
+ // Add truncation indicators when limit is applied
142
+ if (limit !== undefined && totalCount !== undefined) {
143
+ response["truncated"] = resultCount < totalCount;
144
+ response["totalCount"] = totalCount;
124
145
  }
125
- sql = `SELECT *, nlevel("${column}") as depth FROM ${qualifiedTable} WHERE "${column}" ${operator} $1::ltree ORDER BY "${column}" ${limitClause}`;
146
+ return response;
126
147
  }
127
- const result = await adapter.executeQuery(sql, [path]);
128
- const resultCount = result.rows?.length ?? 0;
129
- const response = {
130
- path,
131
- mode: isLqueryPattern ? "pattern" : queryMode,
132
- isPattern: isLqueryPattern,
133
- results: result.rows ?? [],
134
- count: resultCount,
135
- };
136
- // Add truncation indicators when limit is applied
137
- if (limit !== undefined && totalCount !== undefined) {
138
- response["truncated"] = resultCount < totalCount;
139
- response["totalCount"] = totalCount;
148
+ catch (error) {
149
+ if (error instanceof z.ZodError) {
150
+ return {
151
+ success: false,
152
+ error: error.issues.map((i) => i.message).join("; "),
153
+ };
154
+ }
155
+ return {
156
+ success: false,
157
+ error: formatPostgresError(error, {
158
+ tool: "pg_ltree_query",
159
+ }),
160
+ };
140
161
  }
141
- return response;
142
162
  },
143
163
  };
144
164
  }
@@ -152,33 +172,49 @@ function createLtreeSubpathTool(adapter) {
152
172
  annotations: readOnly("Ltree Subpath"),
153
173
  icons: getToolIcons("ltree", readOnly("Ltree Subpath")),
154
174
  handler: async (params, _context) => {
155
- const { path, offset, length } = LtreeSubpathSchema.parse(params);
156
- // First get the path depth for validation
157
- const depthResult = await adapter.executeQuery(`SELECT nlevel($1::ltree) as depth`, [path]);
158
- const pathDepth = depthResult.rows?.[0]?.["depth"];
159
- // Validate offset is within bounds
160
- const effectiveOffset = offset < 0 ? pathDepth + offset : offset;
161
- if (effectiveOffset < 0 || effectiveOffset >= pathDepth) {
175
+ try {
176
+ const { path, offset, length } = LtreeSubpathSchema.parse(params);
177
+ // First get the path depth for validation
178
+ const depthResult = await adapter.executeQuery(`SELECT nlevel($1::ltree) as depth`, [path]);
179
+ const pathDepth = depthResult.rows?.[0]?.["depth"];
180
+ // Validate offset is within bounds
181
+ const effectiveOffset = offset < 0 ? pathDepth + offset : offset;
182
+ if (effectiveOffset < 0 || effectiveOffset >= pathDepth) {
183
+ return {
184
+ success: false,
185
+ error: `Invalid offset: ${String(offset)}. Path "${path}" has ${String(pathDepth)} labels (valid offset range: 0 to ${String(pathDepth - 1)}, or -${String(pathDepth)} to -1 for negative indexing).`,
186
+ originalPath: path,
187
+ pathDepth,
188
+ };
189
+ }
190
+ const sql = length !== undefined
191
+ ? `SELECT subpath($1::ltree, $2, $3) as subpath, nlevel($1::ltree) as original_depth`
192
+ : `SELECT subpath($1::ltree, $2) as subpath, nlevel($1::ltree) as original_depth`;
193
+ const queryParams = length !== undefined ? [path, offset, length] : [path, offset];
194
+ const result = await adapter.executeQuery(sql, queryParams);
195
+ const row = result.rows?.[0];
162
196
  return {
163
- success: false,
164
- error: `Invalid offset: ${String(offset)}. Path "${path}" has ${String(pathDepth)} labels (valid offset range: 0 to ${String(pathDepth - 1)}, or -${String(pathDepth)} to -1 for negative indexing).`,
165
197
  originalPath: path,
166
- pathDepth,
198
+ offset,
199
+ length: length ?? "to end",
200
+ subpath: row?.["subpath"],
201
+ originalDepth: row?.["original_depth"],
202
+ };
203
+ }
204
+ catch (error) {
205
+ if (error instanceof z.ZodError) {
206
+ return {
207
+ success: false,
208
+ error: error.issues.map((i) => i.message).join("; "),
209
+ };
210
+ }
211
+ return {
212
+ success: false,
213
+ error: formatPostgresError(error, {
214
+ tool: "pg_ltree_subpath",
215
+ }),
167
216
  };
168
217
  }
169
- const sql = length !== undefined
170
- ? `SELECT subpath($1::ltree, $2, $3) as subpath, nlevel($1::ltree) as original_depth`
171
- : `SELECT subpath($1::ltree, $2) as subpath, nlevel($1::ltree) as original_depth`;
172
- const queryParams = length !== undefined ? [path, offset, length] : [path, offset];
173
- const result = await adapter.executeQuery(sql, queryParams);
174
- const row = result.rows?.[0];
175
- return {
176
- originalPath: path,
177
- offset,
178
- length: length ?? "to end",
179
- subpath: row?.["subpath"],
180
- originalDepth: row?.["original_depth"],
181
- };
182
218
  },
183
219
  };
184
220
  }
@@ -192,9 +228,19 @@ function createLtreeLcaTool(adapter) {
192
228
  annotations: readOnly("Ltree LCA"),
193
229
  icons: getToolIcons("ltree", readOnly("Ltree LCA")),
194
230
  handler: async (params, _context) => {
195
- let parsed;
196
231
  try {
197
- parsed = LtreeLcaSchema.parse(params);
232
+ const { paths } = LtreeLcaSchema.parse(params);
233
+ const arrayLiteral = paths
234
+ .map((p) => `'${p.replace(/'/g, "''")}'::ltree`)
235
+ .join(", ");
236
+ const sql = `SELECT lca(ARRAY[${arrayLiteral}]) as lca`;
237
+ const result = await adapter.executeQuery(sql);
238
+ const lca = result.rows?.[0]?.["lca"];
239
+ return {
240
+ paths,
241
+ longestCommonAncestor: lca ?? "",
242
+ hasCommonAncestor: lca !== null && lca !== "",
243
+ };
198
244
  }
199
245
  catch (error) {
200
246
  if (error instanceof z.ZodError) {
@@ -203,20 +249,13 @@ function createLtreeLcaTool(adapter) {
203
249
  error: error.issues.map((i) => i.message).join("; "),
204
250
  };
205
251
  }
206
- throw error;
252
+ return {
253
+ success: false,
254
+ error: formatPostgresError(error, {
255
+ tool: "pg_ltree_lca",
256
+ }),
257
+ };
207
258
  }
208
- const { paths } = parsed;
209
- const arrayLiteral = paths
210
- .map((p) => `'${p.replace(/'/g, "''")}'::ltree`)
211
- .join(", ");
212
- const sql = `SELECT lca(ARRAY[${arrayLiteral}]) as lca`;
213
- const result = await adapter.executeQuery(sql);
214
- const lca = result.rows?.[0]?.["lca"];
215
- return {
216
- paths,
217
- longestCommonAncestor: lca ?? "",
218
- hasCommonAncestor: lca !== null && lca !== "",
219
- };
220
259
  },
221
260
  };
222
261
  }
@@ -230,33 +269,33 @@ function createLtreeMatchTool(adapter) {
230
269
  annotations: readOnly("Ltree Match"),
231
270
  icons: getToolIcons("ltree", readOnly("Ltree Match")),
232
271
  handler: async (params, _context) => {
233
- const { table, column, pattern, schema, limit } = LtreeMatchSchema.parse(params);
234
- const schemaName = schema ?? "public";
235
- const qualifiedTable = `"${schemaName}"."${table}"`;
236
- const limitClause = limit !== undefined ? `LIMIT ${String(limit)}` : "";
237
- // Validate table exists and column is ltree type
238
- const colCheck = await adapter.executeQuery(`SELECT udt_name FROM information_schema.columns WHERE table_schema = $1 AND table_name = $2 AND column_name = $3`, [schemaName, table, column]);
239
- if (!colCheck.rows || colCheck.rows.length === 0) {
240
- const tableCheck = await adapter.executeQuery(`SELECT 1 FROM information_schema.tables WHERE table_schema = $1 AND table_name = $2`, [schemaName, table]);
241
- if (!tableCheck.rows || tableCheck.rows.length === 0) {
272
+ try {
273
+ const { table, column, pattern, schema, limit } = LtreeMatchSchema.parse(params);
274
+ const schemaName = schema ?? "public";
275
+ const qualifiedTable = `"${schemaName}"."${table}"`;
276
+ const limitClause = limit !== undefined ? `LIMIT ${String(limit)}` : "";
277
+ // Validate table exists and column is ltree type
278
+ const colCheck = await adapter.executeQuery(`SELECT udt_name FROM information_schema.columns WHERE table_schema = $1 AND table_name = $2 AND column_name = $3`, [schemaName, table, column]);
279
+ if (!colCheck.rows || colCheck.rows.length === 0) {
280
+ const tableCheck = await adapter.executeQuery(`SELECT 1 FROM information_schema.tables WHERE table_schema = $1 AND table_name = $2`, [schemaName, table]);
281
+ if (!tableCheck.rows || tableCheck.rows.length === 0) {
282
+ return {
283
+ success: false,
284
+ error: `Table ${qualifiedTable} does not exist.`,
285
+ };
286
+ }
242
287
  return {
243
288
  success: false,
244
- error: `Table ${qualifiedTable} does not exist.`,
289
+ error: `Column "${column}" not found in table ${qualifiedTable}.`,
290
+ };
291
+ }
292
+ const udtName = colCheck.rows[0]?.["udt_name"];
293
+ if (udtName !== "ltree") {
294
+ return {
295
+ success: false,
296
+ error: `Column "${column}" is not an ltree type (found: ${udtName}). Use an ltree column or convert with pg_ltree_convert_column.`,
245
297
  };
246
298
  }
247
- return {
248
- success: false,
249
- error: `Column "${column}" not found in table ${qualifiedTable}.`,
250
- };
251
- }
252
- const udtName = colCheck.rows[0]?.["udt_name"];
253
- if (udtName !== "ltree") {
254
- return {
255
- success: false,
256
- error: `Column "${column}" is not an ltree type (found: ${udtName}). Use an ltree column or convert with pg_ltree_convert_column.`,
257
- };
258
- }
259
- try {
260
299
  // Get total count when limit is applied for truncation indicators
261
300
  let totalCount;
262
301
  if (limit !== undefined) {
@@ -280,13 +319,17 @@ function createLtreeMatchTool(adapter) {
280
319
  return response;
281
320
  }
282
321
  catch (error) {
322
+ if (error instanceof z.ZodError) {
323
+ return {
324
+ success: false,
325
+ error: error.issues.map((i) => i.message).join("; "),
326
+ };
327
+ }
283
328
  return {
284
329
  success: false,
285
- error: parsePostgresError(error, {
330
+ error: formatPostgresError(error, {
286
331
  tool: "pg_ltree_match",
287
- table,
288
- schema: schemaName,
289
- }).message,
332
+ }),
290
333
  };
291
334
  }
292
335
  },
@@ -302,19 +345,35 @@ function createLtreeListColumnsTool(adapter) {
302
345
  annotations: readOnly("List Ltree Columns"),
303
346
  icons: getToolIcons("ltree", readOnly("List Ltree Columns")),
304
347
  handler: async (params, _context) => {
305
- const { schema } = LtreeListColumnsSchema.parse(params);
306
- const conditions = [
307
- "udt_name = 'ltree'",
308
- "table_schema NOT IN ('pg_catalog', 'information_schema')",
309
- ];
310
- const queryParams = [];
311
- if (schema !== undefined) {
312
- conditions.push(`table_schema = $1`);
313
- queryParams.push(schema);
348
+ try {
349
+ const { schema } = LtreeListColumnsSchema.parse(params);
350
+ const conditions = [
351
+ "udt_name = 'ltree'",
352
+ "table_schema NOT IN ('pg_catalog', 'information_schema')",
353
+ ];
354
+ const queryParams = [];
355
+ if (schema !== undefined) {
356
+ conditions.push(`table_schema = $1`);
357
+ queryParams.push(schema);
358
+ }
359
+ const sql = `SELECT table_schema, table_name, column_name, is_nullable, column_default FROM information_schema.columns WHERE ${conditions.join(" AND ")} ORDER BY table_schema, table_name, ordinal_position`;
360
+ const result = await adapter.executeQuery(sql, queryParams);
361
+ return { columns: result.rows ?? [], count: result.rows?.length ?? 0 };
362
+ }
363
+ catch (error) {
364
+ if (error instanceof z.ZodError) {
365
+ return {
366
+ success: false,
367
+ error: error.issues.map((i) => i.message).join("; "),
368
+ };
369
+ }
370
+ return {
371
+ success: false,
372
+ error: formatPostgresError(error, {
373
+ tool: "pg_ltree_list_columns",
374
+ }),
375
+ };
314
376
  }
315
- const sql = `SELECT table_schema, table_name, column_name, is_nullable, column_default FROM information_schema.columns WHERE ${conditions.join(" AND ")} ORDER BY table_schema, table_name, ordinal_position`;
316
- const result = await adapter.executeQuery(sql, queryParams);
317
- return { columns: result.rows ?? [], count: result.rows?.length ?? 0 };
318
377
  },
319
378
  };
320
379
  }
@@ -328,88 +387,88 @@ function createLtreeConvertColumnTool(adapter) {
328
387
  annotations: write("Convert to Ltree"),
329
388
  icons: getToolIcons("ltree", write("Convert to Ltree")),
330
389
  handler: async (params, _context) => {
331
- const { table, column, schema } = LtreeConvertColumnSchema.parse(params);
332
- const schemaName = schema ?? "public";
333
- const qualifiedTable = `"${schemaName}"."${table}"`;
334
- // Check if ltree extension is installed
335
- const extCheck = await adapter.executeQuery(`
336
- SELECT EXISTS(
337
- SELECT 1 FROM pg_extension WHERE extname = 'ltree'
338
- ) as installed
339
- `);
340
- const hasExt = extCheck.rows?.[0]?.["installed"] ?? false;
341
- if (!hasExt) {
342
- return {
343
- success: false,
344
- error: "ltree extension is not installed. Run pg_ltree_create_extension first.",
345
- };
346
- }
347
- const colCheck = await adapter.executeQuery(`SELECT data_type, udt_name FROM information_schema.columns WHERE table_schema = $1 AND table_name = $2 AND column_name = $3`, [schemaName, table, column]);
348
- if (!colCheck.rows || colCheck.rows.length === 0) {
349
- // Distinguish table-not-found from column-not-found
350
- const tableCheck = await adapter.executeQuery(`SELECT 1 FROM information_schema.tables WHERE table_schema = $1 AND table_name = $2`, [schemaName, table]);
351
- if (!tableCheck.rows || tableCheck.rows.length === 0) {
390
+ try {
391
+ const { table, column, schema } = LtreeConvertColumnSchema.parse(params);
392
+ const schemaName = schema ?? "public";
393
+ const qualifiedTable = `"${schemaName}"."${table}"`;
394
+ // Check if ltree extension is installed
395
+ const extCheck = await adapter.executeQuery(`
396
+ SELECT EXISTS(
397
+ SELECT 1 FROM pg_extension WHERE extname = 'ltree'
398
+ ) as installed
399
+ `);
400
+ const hasExt = extCheck.rows?.[0]?.["installed"] ?? false;
401
+ if (!hasExt) {
352
402
  return {
353
403
  success: false,
354
- error: `Table ${qualifiedTable} does not exist. Verify the table name.`,
404
+ error: "ltree extension is not installed. Run pg_ltree_create_extension first.",
405
+ };
406
+ }
407
+ const colCheck = await adapter.executeQuery(`SELECT data_type, udt_name FROM information_schema.columns WHERE table_schema = $1 AND table_name = $2 AND column_name = $3`, [schemaName, table, column]);
408
+ if (!colCheck.rows || colCheck.rows.length === 0) {
409
+ // Distinguish table-not-found from column-not-found
410
+ const tableCheck = await adapter.executeQuery(`SELECT 1 FROM information_schema.tables WHERE table_schema = $1 AND table_name = $2`, [schemaName, table]);
411
+ if (!tableCheck.rows || tableCheck.rows.length === 0) {
412
+ return {
413
+ success: false,
414
+ error: `Table ${qualifiedTable} does not exist. Verify the table name.`,
415
+ };
416
+ }
417
+ return {
418
+ success: false,
419
+ error: `Column "${column}" not found in table ${qualifiedTable}. Verify the column name.`,
420
+ };
421
+ }
422
+ const dataType = colCheck.rows[0]?.["data_type"];
423
+ const udtName = colCheck.rows[0]?.["udt_name"];
424
+ const currentType = dataType === "USER-DEFINED" ? udtName : dataType;
425
+ if (udtName === "ltree") {
426
+ return {
427
+ success: true,
428
+ message: `Column ${column} is already ltree`,
429
+ table: qualifiedTable,
430
+ previousType: "ltree",
431
+ wasAlreadyLtree: true,
432
+ };
433
+ }
434
+ // Validate source column is text-based (like citext tool does)
435
+ const allowedTypes = ["text", "varchar", "character varying", "bpchar"];
436
+ const normalizedType = dataType.toLowerCase();
437
+ if (!allowedTypes.includes(normalizedType)) {
438
+ return {
439
+ success: false,
440
+ error: `Cannot convert column "${column}" of type "${currentType}" to ltree. Only text-based columns can be converted.`,
441
+ currentType,
442
+ allowedTypes: ["text", "varchar", "character varying"],
443
+ suggestion: "Create a new TEXT column with ltree-formatted paths, then convert that column.",
444
+ };
445
+ }
446
+ // Check for dependent views before attempting the conversion
447
+ const depCheck = await adapter.executeQuery(`
448
+ SELECT DISTINCT
449
+ c.relname as dependent_view,
450
+ n.nspname as view_schema
451
+ FROM pg_depend d
452
+ JOIN pg_rewrite r ON d.objid = r.oid
453
+ JOIN pg_class c ON r.ev_class = c.oid
454
+ JOIN pg_namespace n ON c.relnamespace = n.oid
455
+ JOIN pg_class t ON d.refobjid = t.oid
456
+ JOIN pg_namespace tn ON t.relnamespace = tn.oid
457
+ JOIN pg_attribute a ON d.refobjid = a.attrelid AND d.refobjsubid = a.attnum
458
+ WHERE c.relkind = 'v'
459
+ AND tn.nspname = $1
460
+ AND t.relname = $2
461
+ AND a.attname = $3
462
+ `, [schemaName, table, column]);
463
+ const dependentViews = depCheck.rows ?? [];
464
+ if (dependentViews.length > 0) {
465
+ return {
466
+ success: false,
467
+ error: "Column has dependent views that must be dropped before conversion",
468
+ dependentViews: dependentViews.map((v) => `${v["view_schema"]}.${v["dependent_view"]}`),
469
+ hint: "Drop the listed views, run this conversion, then recreate the views. PostgreSQL cannot ALTER COLUMN TYPE when views depend on it.",
355
470
  };
356
471
  }
357
- return {
358
- success: false,
359
- error: `Column "${column}" not found in table ${qualifiedTable}. Verify the column name.`,
360
- };
361
- }
362
- const dataType = colCheck.rows[0]?.["data_type"];
363
- const udtName = colCheck.rows[0]?.["udt_name"];
364
- const currentType = dataType === "USER-DEFINED" ? udtName : dataType;
365
- if (udtName === "ltree") {
366
- return {
367
- success: true,
368
- message: `Column ${column} is already ltree`,
369
- table: qualifiedTable,
370
- previousType: "ltree",
371
- wasAlreadyLtree: true,
372
- };
373
- }
374
- // Validate source column is text-based (like citext tool does)
375
- const allowedTypes = ["text", "varchar", "character varying", "bpchar"];
376
- const normalizedType = dataType.toLowerCase();
377
- if (!allowedTypes.includes(normalizedType)) {
378
- return {
379
- success: false,
380
- error: `Cannot convert column "${column}" of type "${currentType}" to ltree. Only text-based columns can be converted.`,
381
- currentType,
382
- allowedTypes: ["text", "varchar", "character varying"],
383
- suggestion: "Create a new TEXT column with ltree-formatted paths, then convert that column.",
384
- };
385
- }
386
- // Check for dependent views before attempting the conversion
387
- const depCheck = await adapter.executeQuery(`
388
- SELECT DISTINCT
389
- c.relname as dependent_view,
390
- n.nspname as view_schema
391
- FROM pg_depend d
392
- JOIN pg_rewrite r ON d.objid = r.oid
393
- JOIN pg_class c ON r.ev_class = c.oid
394
- JOIN pg_namespace n ON c.relnamespace = n.oid
395
- JOIN pg_class t ON d.refobjid = t.oid
396
- JOIN pg_namespace tn ON t.relnamespace = tn.oid
397
- JOIN pg_attribute a ON d.refobjid = a.attrelid AND d.refobjsubid = a.attnum
398
- WHERE c.relkind = 'v'
399
- AND tn.nspname = $1
400
- AND t.relname = $2
401
- AND a.attname = $3
402
- `, [schemaName, table, column]);
403
- const dependentViews = depCheck.rows ?? [];
404
- if (dependentViews.length > 0) {
405
- return {
406
- success: false,
407
- error: "Column has dependent views that must be dropped before conversion",
408
- dependentViews: dependentViews.map((v) => `${v["view_schema"]}.${v["dependent_view"]}`),
409
- hint: "Drop the listed views, run this conversion, then recreate the views. PostgreSQL cannot ALTER COLUMN TYPE when views depend on it.",
410
- };
411
- }
412
- try {
413
472
  await adapter.executeQuery(`ALTER TABLE ${qualifiedTable} ALTER COLUMN "${column}" TYPE ltree USING "${column}"::ltree`);
414
473
  return {
415
474
  success: true,
@@ -419,11 +478,17 @@ function createLtreeConvertColumnTool(adapter) {
419
478
  };
420
479
  }
421
480
  catch (error) {
422
- const errorMessage = error instanceof Error ? error.message : String(error);
481
+ if (error instanceof z.ZodError) {
482
+ return {
483
+ success: false,
484
+ error: error.issues.map((i) => i.message).join("; "),
485
+ };
486
+ }
423
487
  return {
424
488
  success: false,
425
- error: `Failed to convert column: ${errorMessage}`,
426
- hint: "If views depend on this column, they may need to be dropped and recreated",
489
+ error: formatPostgresError(error, {
490
+ tool: "pg_ltree_convert_column",
491
+ }),
427
492
  };
428
493
  }
429
494
  },
@@ -439,33 +504,34 @@ function createLtreeCreateIndexTool(adapter) {
439
504
  annotations: write("Create Ltree Index"),
440
505
  icons: getToolIcons("ltree", write("Create Ltree Index")),
441
506
  handler: async (params, _context) => {
442
- const { table, column, indexName, schema } = LtreeIndexSchema.parse(params);
443
- const schemaName = schema ?? "public";
444
- const qualifiedTable = `"${schemaName}"."${table}"`;
445
- const idxName = indexName ?? `idx_${table}_${column}_ltree`;
446
- // Validate table exists and column is ltree type
447
- const colCheck = await adapter.executeQuery(`SELECT udt_name FROM information_schema.columns WHERE table_schema = $1 AND table_name = $2 AND column_name = $3`, [schemaName, table, column]);
448
- if (!colCheck.rows || colCheck.rows.length === 0) {
449
- const tableCheck = await adapter.executeQuery(`SELECT 1 FROM information_schema.tables WHERE table_schema = $1 AND table_name = $2`, [schemaName, table]);
450
- if (!tableCheck.rows || tableCheck.rows.length === 0) {
507
+ try {
508
+ const { table, column, indexName, schema } = LtreeIndexSchema.parse(params);
509
+ const schemaName = schema ?? "public";
510
+ const qualifiedTable = `"${schemaName}"."${table}"`;
511
+ const idxName = indexName ?? `idx_${table}_${column}_ltree`;
512
+ // Validate table exists and column is ltree type
513
+ const colCheck = await adapter.executeQuery(`SELECT udt_name FROM information_schema.columns WHERE table_schema = $1 AND table_name = $2 AND column_name = $3`, [schemaName, table, column]);
514
+ if (!colCheck.rows || colCheck.rows.length === 0) {
515
+ const tableCheck = await adapter.executeQuery(`SELECT 1 FROM information_schema.tables WHERE table_schema = $1 AND table_name = $2`, [schemaName, table]);
516
+ if (!tableCheck.rows || tableCheck.rows.length === 0) {
517
+ return {
518
+ success: false,
519
+ error: `Table ${qualifiedTable} does not exist.`,
520
+ };
521
+ }
451
522
  return {
452
523
  success: false,
453
- error: `Table ${qualifiedTable} does not exist.`,
524
+ error: `Column "${column}" not found in table ${qualifiedTable}.`,
454
525
  };
455
526
  }
456
- return {
457
- success: false,
458
- error: `Column "${column}" not found in table ${qualifiedTable}.`,
459
- };
460
- }
461
- const udtName = colCheck.rows[0]?.["udt_name"];
462
- if (udtName !== "ltree") {
463
- return {
464
- success: false,
465
- error: `Column "${column}" is not an ltree type (found: ${udtName}). Use an ltree column or convert with pg_ltree_convert_column.`,
466
- };
467
- }
468
- try {
527
+ const udtName = colCheck.rows[0]?.["udt_name"];
528
+ if (udtName !== "ltree") {
529
+ return {
530
+ success: false,
531
+ error: `Column "${column}" is not an ltree type (found: ${udtName}). Use an ltree column or convert with pg_ltree_convert_column.`,
532
+ };
533
+ }
534
+ // Check for existing index by name
469
535
  const idxCheck = await adapter.executeQuery(`SELECT EXISTS(SELECT 1 FROM pg_indexes WHERE schemaname = $1 AND indexname = $2) as exists`, [schemaName, idxName]);
470
536
  if (idxCheck.rows?.[0]?.["exists"])
471
537
  return {
@@ -477,6 +543,23 @@ function createLtreeCreateIndexTool(adapter) {
477
543
  indexType: "gist",
478
544
  alreadyExists: true,
479
545
  };
546
+ // Check for existing GiST index on same table+column (semantic duplicate)
547
+ const semanticCheck = await adapter.executeQuery(`SELECT indexname FROM pg_indexes
548
+ WHERE schemaname = $1 AND tablename = $2
549
+ AND indexdef ILIKE '%using gist%'
550
+ AND (indexdef ILIKE $3 OR indexdef ILIKE $4)`, [schemaName, table, `%(${column})%`, `%("${column}")%`]);
551
+ if (semanticCheck.rows && semanticCheck.rows.length > 0) {
552
+ const existingName = semanticCheck.rows[0]?.["indexname"];
553
+ return {
554
+ success: true,
555
+ message: `GiST index already exists on column "${column}" as "${existingName}"`,
556
+ indexName: existingName,
557
+ table: qualifiedTable,
558
+ column,
559
+ indexType: "gist",
560
+ alreadyExists: true,
561
+ };
562
+ }
480
563
  await adapter.executeQuery(`CREATE INDEX "${idxName}" ON ${qualifiedTable} USING GIST ("${column}")`);
481
564
  return {
482
565
  success: true,
@@ -488,14 +571,17 @@ function createLtreeCreateIndexTool(adapter) {
488
571
  };
489
572
  }
490
573
  catch (error) {
574
+ if (error instanceof z.ZodError) {
575
+ return {
576
+ success: false,
577
+ error: error.issues.map((i) => i.message).join("; "),
578
+ };
579
+ }
491
580
  return {
492
581
  success: false,
493
- error: parsePostgresError(error, {
582
+ error: formatPostgresError(error, {
494
583
  tool: "pg_ltree_create_index",
495
- table,
496
- schema: schemaName,
497
- index: idxName,
498
- }).message,
584
+ }),
499
585
  };
500
586
  }
501
587
  },