@dotdo/postgres 0.1.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 (1129) hide show
  1. package/README.md +868 -0
  2. package/dist/cdc/change-stream.d.ts +44 -0
  3. package/dist/cdc/change-stream.d.ts.map +1 -0
  4. package/dist/cdc/change-stream.js +95 -0
  5. package/dist/cdc/change-stream.js.map +1 -0
  6. package/dist/cdc/filter.d.ts +58 -0
  7. package/dist/cdc/filter.d.ts.map +1 -0
  8. package/dist/cdc/filter.js +520 -0
  9. package/dist/cdc/filter.js.map +1 -0
  10. package/dist/cdc/index.d.ts +47 -0
  11. package/dist/cdc/index.d.ts.map +1 -0
  12. package/dist/cdc/index.js +50 -0
  13. package/dist/cdc/index.js.map +1 -0
  14. package/dist/cdc/resume-token.d.ts +60 -0
  15. package/dist/cdc/resume-token.d.ts.map +1 -0
  16. package/dist/cdc/resume-token.js +228 -0
  17. package/dist/cdc/resume-token.js.map +1 -0
  18. package/dist/cdc/transport/index.d.ts +7 -0
  19. package/dist/cdc/transport/index.d.ts.map +1 -0
  20. package/dist/cdc/transport/index.js +7 -0
  21. package/dist/cdc/transport/index.js.map +1 -0
  22. package/dist/cdc/transport/sse.d.ts +120 -0
  23. package/dist/cdc/transport/sse.d.ts.map +1 -0
  24. package/dist/cdc/transport/sse.js +590 -0
  25. package/dist/cdc/transport/sse.js.map +1 -0
  26. package/dist/cdc/transport/websocket.d.ts +130 -0
  27. package/dist/cdc/transport/websocket.d.ts.map +1 -0
  28. package/dist/cdc/transport/websocket.js +688 -0
  29. package/dist/cdc/transport/websocket.js.map +1 -0
  30. package/dist/cdc/types.d.ts +306 -0
  31. package/dist/cdc/types.d.ts.map +1 -0
  32. package/dist/cdc/types.js +8 -0
  33. package/dist/cdc/types.js.map +1 -0
  34. package/dist/config/index.d.ts +25 -0
  35. package/dist/config/index.d.ts.map +1 -0
  36. package/dist/config/index.js +25 -0
  37. package/dist/config/index.js.map +1 -0
  38. package/dist/config/memory.d.ts +139 -0
  39. package/dist/config/memory.d.ts.map +1 -0
  40. package/dist/config/memory.js +157 -0
  41. package/dist/config/memory.js.map +1 -0
  42. package/dist/config/storage.d.ts +157 -0
  43. package/dist/config/storage.d.ts.map +1 -0
  44. package/dist/config/storage.js +178 -0
  45. package/dist/config/storage.js.map +1 -0
  46. package/dist/config/streaming.d.ts +117 -0
  47. package/dist/config/streaming.d.ts.map +1 -0
  48. package/dist/config/streaming.js +132 -0
  49. package/dist/config/streaming.js.map +1 -0
  50. package/dist/config/timeouts.d.ts +168 -0
  51. package/dist/config/timeouts.d.ts.map +1 -0
  52. package/dist/config/timeouts.js +192 -0
  53. package/dist/config/timeouts.js.map +1 -0
  54. package/dist/extensions/config.d.ts +89 -0
  55. package/dist/extensions/config.d.ts.map +1 -0
  56. package/dist/extensions/config.js +216 -0
  57. package/dist/extensions/config.js.map +1 -0
  58. package/dist/extensions/geo.d.ts +452 -0
  59. package/dist/extensions/geo.d.ts.map +1 -0
  60. package/dist/extensions/geo.js +583 -0
  61. package/dist/extensions/geo.js.map +1 -0
  62. package/dist/extensions/index.d.ts +167 -0
  63. package/dist/extensions/index.d.ts.map +1 -0
  64. package/dist/extensions/index.js +99 -0
  65. package/dist/extensions/index.js.map +1 -0
  66. package/dist/extensions/loader.d.ts +226 -0
  67. package/dist/extensions/loader.d.ts.map +1 -0
  68. package/dist/extensions/loader.js +456 -0
  69. package/dist/extensions/loader.js.map +1 -0
  70. package/dist/extensions/pgmq-lite.d.ts +330 -0
  71. package/dist/extensions/pgmq-lite.d.ts.map +1 -0
  72. package/dist/extensions/pgmq-lite.js +648 -0
  73. package/dist/extensions/pgmq-lite.js.map +1 -0
  74. package/dist/extensions/plugins.d.ts +260 -0
  75. package/dist/extensions/plugins.d.ts.map +1 -0
  76. package/dist/extensions/plugins.js +535 -0
  77. package/dist/extensions/plugins.js.map +1 -0
  78. package/dist/extensions/registry.d.ts +93 -0
  79. package/dist/extensions/registry.d.ts.map +1 -0
  80. package/dist/extensions/registry.js +182 -0
  81. package/dist/extensions/registry.js.map +1 -0
  82. package/dist/extensions/vector.d.ts +106 -0
  83. package/dist/extensions/vector.d.ts.map +1 -0
  84. package/dist/extensions/vector.js +129 -0
  85. package/dist/extensions/vector.js.map +1 -0
  86. package/dist/iceberg/analytics.d.ts +279 -0
  87. package/dist/iceberg/analytics.d.ts.map +1 -0
  88. package/dist/iceberg/analytics.js +448 -0
  89. package/dist/iceberg/analytics.js.map +1 -0
  90. package/dist/iceberg/catalog-api.d.ts +39 -0
  91. package/dist/iceberg/catalog-api.d.ts.map +1 -0
  92. package/dist/iceberg/catalog-api.js +388 -0
  93. package/dist/iceberg/catalog-api.js.map +1 -0
  94. package/dist/iceberg/catalog.d.ts +401 -0
  95. package/dist/iceberg/catalog.d.ts.map +1 -0
  96. package/dist/iceberg/catalog.js +677 -0
  97. package/dist/iceberg/catalog.js.map +1 -0
  98. package/dist/iceberg/duckdb-wasm.d.ts +447 -0
  99. package/dist/iceberg/duckdb-wasm.d.ts.map +1 -0
  100. package/dist/iceberg/duckdb-wasm.js +600 -0
  101. package/dist/iceberg/duckdb-wasm.js.map +1 -0
  102. package/dist/iceberg/index.d.ts +92 -0
  103. package/dist/iceberg/index.d.ts.map +1 -0
  104. package/dist/iceberg/index.js +119 -0
  105. package/dist/iceberg/index.js.map +1 -0
  106. package/dist/iceberg/metadata.d.ts +214 -0
  107. package/dist/iceberg/metadata.d.ts.map +1 -0
  108. package/dist/iceberg/metadata.js +535 -0
  109. package/dist/iceberg/metadata.js.map +1 -0
  110. package/dist/iceberg/optimizer.d.ts +296 -0
  111. package/dist/iceberg/optimizer.d.ts.map +1 -0
  112. package/dist/iceberg/optimizer.js +889 -0
  113. package/dist/iceberg/optimizer.js.map +1 -0
  114. package/dist/iceberg/parquet.d.ts +447 -0
  115. package/dist/iceberg/parquet.d.ts.map +1 -0
  116. package/dist/iceberg/parquet.js +1225 -0
  117. package/dist/iceberg/parquet.js.map +1 -0
  118. package/dist/iceberg/r2-organization.d.ts +422 -0
  119. package/dist/iceberg/r2-organization.d.ts.map +1 -0
  120. package/dist/iceberg/r2-organization.js +672 -0
  121. package/dist/iceberg/r2-organization.js.map +1 -0
  122. package/dist/iceberg/scheduler-do-example.d.ts +158 -0
  123. package/dist/iceberg/scheduler-do-example.d.ts.map +1 -0
  124. package/dist/iceberg/scheduler-do-example.js +261 -0
  125. package/dist/iceberg/scheduler-do-example.js.map +1 -0
  126. package/dist/iceberg/scheduler.d.ts +434 -0
  127. package/dist/iceberg/scheduler.d.ts.map +1 -0
  128. package/dist/iceberg/scheduler.js +818 -0
  129. package/dist/iceberg/scheduler.js.map +1 -0
  130. package/dist/iceberg/schema.d.ts +149 -0
  131. package/dist/iceberg/schema.d.ts.map +1 -0
  132. package/dist/iceberg/schema.js +525 -0
  133. package/dist/iceberg/schema.js.map +1 -0
  134. package/dist/iceberg/snapshot-manager.d.ts +406 -0
  135. package/dist/iceberg/snapshot-manager.d.ts.map +1 -0
  136. package/dist/iceberg/snapshot-manager.js +934 -0
  137. package/dist/iceberg/snapshot-manager.js.map +1 -0
  138. package/dist/iceberg/sql-router.d.ts +194 -0
  139. package/dist/iceberg/sql-router.d.ts.map +1 -0
  140. package/dist/iceberg/sql-router.js +180 -0
  141. package/dist/iceberg/sql-router.js.map +1 -0
  142. package/dist/iceberg/test-fixtures.d.ts +151 -0
  143. package/dist/iceberg/test-fixtures.d.ts.map +1 -0
  144. package/dist/iceberg/test-fixtures.js +446 -0
  145. package/dist/iceberg/test-fixtures.js.map +1 -0
  146. package/dist/iceberg/time-travel-api.d.ts +102 -0
  147. package/dist/iceberg/time-travel-api.d.ts.map +1 -0
  148. package/dist/iceberg/time-travel-api.js +437 -0
  149. package/dist/iceberg/time-travel-api.js.map +1 -0
  150. package/dist/iceberg/time-travel.d.ts +293 -0
  151. package/dist/iceberg/time-travel.d.ts.map +1 -0
  152. package/dist/iceberg/time-travel.js +689 -0
  153. package/dist/iceberg/time-travel.js.map +1 -0
  154. package/dist/iceberg/transformer.d.ts +356 -0
  155. package/dist/iceberg/transformer.d.ts.map +1 -0
  156. package/dist/iceberg/transformer.js +770 -0
  157. package/dist/iceberg/transformer.js.map +1 -0
  158. package/dist/iceberg/types.d.ts +318 -0
  159. package/dist/iceberg/types.d.ts.map +1 -0
  160. package/dist/iceberg/types.js +9 -0
  161. package/dist/iceberg/types.js.map +1 -0
  162. package/dist/iceberg/writer.d.ts +144 -0
  163. package/dist/iceberg/writer.d.ts.map +1 -0
  164. package/dist/iceberg/writer.js +452 -0
  165. package/dist/iceberg/writer.js.map +1 -0
  166. package/dist/index.d.ts +50 -0
  167. package/dist/index.d.ts.map +1 -0
  168. package/dist/index.js +69 -0
  169. package/dist/index.js.map +1 -0
  170. package/dist/lineage/index.d.ts +11 -0
  171. package/dist/lineage/index.d.ts.map +1 -0
  172. package/dist/lineage/index.js +11 -0
  173. package/dist/lineage/index.js.map +1 -0
  174. package/dist/lineage/integration.d.ts +134 -0
  175. package/dist/lineage/integration.d.ts.map +1 -0
  176. package/dist/lineage/integration.js +258 -0
  177. package/dist/lineage/integration.js.map +1 -0
  178. package/dist/lineage/tracker.d.ts +189 -0
  179. package/dist/lineage/tracker.d.ts.map +1 -0
  180. package/dist/lineage/tracker.js +1352 -0
  181. package/dist/lineage/tracker.js.map +1 -0
  182. package/dist/lineage/types.d.ts +318 -0
  183. package/dist/lineage/types.d.ts.map +1 -0
  184. package/dist/lineage/types.js +9 -0
  185. package/dist/lineage/types.js.map +1 -0
  186. package/dist/middleware/index.d.ts +11 -0
  187. package/dist/middleware/index.d.ts.map +1 -0
  188. package/dist/middleware/index.js +16 -0
  189. package/dist/middleware/index.js.map +1 -0
  190. package/dist/middleware/rate-limit.d.ts +397 -0
  191. package/dist/middleware/rate-limit.d.ts.map +1 -0
  192. package/dist/middleware/rate-limit.js +507 -0
  193. package/dist/middleware/rate-limit.js.map +1 -0
  194. package/dist/migration-tooling/external-migration.d.ts +601 -0
  195. package/dist/migration-tooling/external-migration.d.ts.map +1 -0
  196. package/dist/migration-tooling/external-migration.js +1612 -0
  197. package/dist/migration-tooling/external-migration.js.map +1 -0
  198. package/dist/migration-tooling/index.d.ts +19 -0
  199. package/dist/migration-tooling/index.d.ts.map +1 -0
  200. package/dist/migration-tooling/index.js +19 -0
  201. package/dist/migration-tooling/index.js.map +1 -0
  202. package/dist/migrations/auto-migrator.d.ts +289 -0
  203. package/dist/migrations/auto-migrator.d.ts.map +1 -0
  204. package/dist/migrations/auto-migrator.js +396 -0
  205. package/dist/migrations/auto-migrator.js.map +1 -0
  206. package/dist/migrations/bulk-orchestrator.d.ts +403 -0
  207. package/dist/migrations/bulk-orchestrator.d.ts.map +1 -0
  208. package/dist/migrations/bulk-orchestrator.js +646 -0
  209. package/dist/migrations/bulk-orchestrator.js.map +1 -0
  210. package/dist/migrations/compatibility.d.ts +216 -0
  211. package/dist/migrations/compatibility.d.ts.map +1 -0
  212. package/dist/migrations/compatibility.js +651 -0
  213. package/dist/migrations/compatibility.js.map +1 -0
  214. package/dist/migrations/do-migrations.d.ts +101 -0
  215. package/dist/migrations/do-migrations.d.ts.map +1 -0
  216. package/dist/migrations/do-migrations.js +1060 -0
  217. package/dist/migrations/do-migrations.js.map +1 -0
  218. package/dist/migrations/do-migrations.types.d.ts +550 -0
  219. package/dist/migrations/do-migrations.types.d.ts.map +1 -0
  220. package/dist/migrations/do-migrations.types.js +15 -0
  221. package/dist/migrations/do-migrations.types.js.map +1 -0
  222. package/dist/migrations/drizzle-compat.d.ts +163 -0
  223. package/dist/migrations/drizzle-compat.d.ts.map +1 -0
  224. package/dist/migrations/drizzle-compat.js +273 -0
  225. package/dist/migrations/drizzle-compat.js.map +1 -0
  226. package/dist/migrations/index.d.ts +109 -0
  227. package/dist/migrations/index.d.ts.map +1 -0
  228. package/dist/migrations/index.js +127 -0
  229. package/dist/migrations/index.js.map +1 -0
  230. package/dist/migrations/migration-api.d.ts +161 -0
  231. package/dist/migrations/migration-api.d.ts.map +1 -0
  232. package/dist/migrations/migration-api.js +499 -0
  233. package/dist/migrations/migration-api.js.map +1 -0
  234. package/dist/migrations/progress-tracker-do.d.ts +195 -0
  235. package/dist/migrations/progress-tracker-do.d.ts.map +1 -0
  236. package/dist/migrations/progress-tracker-do.js +339 -0
  237. package/dist/migrations/progress-tracker-do.js.map +1 -0
  238. package/dist/migrations/progress-tracker-kv.d.ts +103 -0
  239. package/dist/migrations/progress-tracker-kv.d.ts.map +1 -0
  240. package/dist/migrations/progress-tracker-kv.js +231 -0
  241. package/dist/migrations/progress-tracker-kv.js.map +1 -0
  242. package/dist/migrations/progress-tracker.d.ts +320 -0
  243. package/dist/migrations/progress-tracker.d.ts.map +1 -0
  244. package/dist/migrations/progress-tracker.js +443 -0
  245. package/dist/migrations/progress-tracker.js.map +1 -0
  246. package/dist/migrations/registry.d.ts +231 -0
  247. package/dist/migrations/registry.d.ts.map +1 -0
  248. package/dist/migrations/registry.js +376 -0
  249. package/dist/migrations/registry.js.map +1 -0
  250. package/dist/migrations/runner.d.ts +197 -0
  251. package/dist/migrations/runner.d.ts.map +1 -0
  252. package/dist/migrations/runner.js +1167 -0
  253. package/dist/migrations/runner.js.map +1 -0
  254. package/dist/migrations/schema-generator.d.ts +111 -0
  255. package/dist/migrations/schema-generator.d.ts.map +1 -0
  256. package/dist/migrations/schema-generator.js +335 -0
  257. package/dist/migrations/schema-generator.js.map +1 -0
  258. package/dist/migrations/testing.d.ts +321 -0
  259. package/dist/migrations/testing.d.ts.map +1 -0
  260. package/dist/migrations/testing.js +645 -0
  261. package/dist/migrations/testing.js.map +1 -0
  262. package/dist/migrations/types.d.ts +503 -0
  263. package/dist/migrations/types.d.ts.map +1 -0
  264. package/dist/migrations/types.js +11 -0
  265. package/dist/migrations/types.js.map +1 -0
  266. package/dist/migrations/validator.d.ts +215 -0
  267. package/dist/migrations/validator.d.ts.map +1 -0
  268. package/dist/migrations/validator.js +494 -0
  269. package/dist/migrations/validator.js.map +1 -0
  270. package/dist/observability/alerting.d.ts +116 -0
  271. package/dist/observability/alerting.d.ts.map +1 -0
  272. package/dist/observability/alerting.js +353 -0
  273. package/dist/observability/alerting.js.map +1 -0
  274. package/dist/observability/analytics-engine.d.ts +357 -0
  275. package/dist/observability/analytics-engine.d.ts.map +1 -0
  276. package/dist/observability/analytics-engine.js +430 -0
  277. package/dist/observability/analytics-engine.js.map +1 -0
  278. package/dist/observability/cost-metrics.d.ts +269 -0
  279. package/dist/observability/cost-metrics.d.ts.map +1 -0
  280. package/dist/observability/cost-metrics.js +560 -0
  281. package/dist/observability/cost-metrics.js.map +1 -0
  282. package/dist/observability/cross-do-tracing.d.ts +305 -0
  283. package/dist/observability/cross-do-tracing.d.ts.map +1 -0
  284. package/dist/observability/cross-do-tracing.js +431 -0
  285. package/dist/observability/cross-do-tracing.js.map +1 -0
  286. package/dist/observability/error-rate-collector.d.ts +163 -0
  287. package/dist/observability/error-rate-collector.d.ts.map +1 -0
  288. package/dist/observability/error-rate-collector.js +306 -0
  289. package/dist/observability/error-rate-collector.js.map +1 -0
  290. package/dist/observability/exporters.d.ts +231 -0
  291. package/dist/observability/exporters.d.ts.map +1 -0
  292. package/dist/observability/exporters.js +479 -0
  293. package/dist/observability/exporters.js.map +1 -0
  294. package/dist/observability/health-check.d.ts +106 -0
  295. package/dist/observability/health-check.d.ts.map +1 -0
  296. package/dist/observability/health-check.js +243 -0
  297. package/dist/observability/health-check.js.map +1 -0
  298. package/dist/observability/index.d.ts +297 -0
  299. package/dist/observability/index.d.ts.map +1 -0
  300. package/dist/observability/index.js +455 -0
  301. package/dist/observability/index.js.map +1 -0
  302. package/dist/observability/instrumentation.d.ts +222 -0
  303. package/dist/observability/instrumentation.d.ts.map +1 -0
  304. package/dist/observability/instrumentation.js +532 -0
  305. package/dist/observability/instrumentation.js.map +1 -0
  306. package/dist/observability/memory-metrics.d.ts +227 -0
  307. package/dist/observability/memory-metrics.d.ts.map +1 -0
  308. package/dist/observability/memory-metrics.js +688 -0
  309. package/dist/observability/memory-metrics.js.map +1 -0
  310. package/dist/observability/metrics-endpoint.d.ts +91 -0
  311. package/dist/observability/metrics-endpoint.d.ts.map +1 -0
  312. package/dist/observability/metrics-endpoint.js +246 -0
  313. package/dist/observability/metrics-endpoint.js.map +1 -0
  314. package/dist/observability/metrics.d.ts +88 -0
  315. package/dist/observability/metrics.d.ts.map +1 -0
  316. package/dist/observability/metrics.js +253 -0
  317. package/dist/observability/metrics.js.map +1 -0
  318. package/dist/observability/observability-features.d.ts +488 -0
  319. package/dist/observability/observability-features.d.ts.map +1 -0
  320. package/dist/observability/observability-features.js +773 -0
  321. package/dist/observability/observability-features.js.map +1 -0
  322. package/dist/observability/prometheus.d.ts +39 -0
  323. package/dist/observability/prometheus.d.ts.map +1 -0
  324. package/dist/observability/prometheus.js +120 -0
  325. package/dist/observability/prometheus.js.map +1 -0
  326. package/dist/observability/propagation.d.ts +126 -0
  327. package/dist/observability/propagation.d.ts.map +1 -0
  328. package/dist/observability/propagation.js +234 -0
  329. package/dist/observability/propagation.js.map +1 -0
  330. package/dist/observability/query-latency.d.ts +243 -0
  331. package/dist/observability/query-latency.d.ts.map +1 -0
  332. package/dist/observability/query-latency.js +292 -0
  333. package/dist/observability/query-latency.js.map +1 -0
  334. package/dist/observability/query-performance.d.ts +169 -0
  335. package/dist/observability/query-performance.d.ts.map +1 -0
  336. package/dist/observability/query-performance.js +290 -0
  337. package/dist/observability/query-performance.js.map +1 -0
  338. package/dist/observability/storage-tier-metrics.d.ts +174 -0
  339. package/dist/observability/storage-tier-metrics.d.ts.map +1 -0
  340. package/dist/observability/storage-tier-metrics.js +306 -0
  341. package/dist/observability/storage-tier-metrics.js.map +1 -0
  342. package/dist/observability/tier-cost-optimizer.d.ts +155 -0
  343. package/dist/observability/tier-cost-optimizer.d.ts.map +1 -0
  344. package/dist/observability/tier-cost-optimizer.js +536 -0
  345. package/dist/observability/tier-cost-optimizer.js.map +1 -0
  346. package/dist/observability/tracer.d.ts +149 -0
  347. package/dist/observability/tracer.d.ts.map +1 -0
  348. package/dist/observability/tracer.js +435 -0
  349. package/dist/observability/tracer.js.map +1 -0
  350. package/dist/observability/types.d.ts +402 -0
  351. package/dist/observability/types.d.ts.map +1 -0
  352. package/dist/observability/types.js +103 -0
  353. package/dist/observability/types.js.map +1 -0
  354. package/dist/pglite/workers-pglite.d.ts +138 -0
  355. package/dist/pglite/workers-pglite.d.ts.map +1 -0
  356. package/dist/pglite/workers-pglite.js +143 -0
  357. package/dist/pglite/workers-pglite.js.map +1 -0
  358. package/dist/pglite-assets/pglite.data +0 -0
  359. package/dist/pglite-assets/pglite.wasm +0 -0
  360. package/dist/playground/index.d.ts +52 -0
  361. package/dist/playground/index.d.ts.map +1 -0
  362. package/dist/playground/index.js +55 -0
  363. package/dist/playground/index.js.map +1 -0
  364. package/dist/playground/keyboard-shortcuts.d.ts +116 -0
  365. package/dist/playground/keyboard-shortcuts.d.ts.map +1 -0
  366. package/dist/playground/keyboard-shortcuts.js +588 -0
  367. package/dist/playground/keyboard-shortcuts.js.map +1 -0
  368. package/dist/playground/playground.d.ts +82 -0
  369. package/dist/playground/playground.d.ts.map +1 -0
  370. package/dist/playground/playground.js +271 -0
  371. package/dist/playground/playground.js.map +1 -0
  372. package/dist/playground/query-executor.d.ts +115 -0
  373. package/dist/playground/query-executor.d.ts.map +1 -0
  374. package/dist/playground/query-executor.js +558 -0
  375. package/dist/playground/query-executor.js.map +1 -0
  376. package/dist/playground/query-history.d.ts +92 -0
  377. package/dist/playground/query-history.d.ts.map +1 -0
  378. package/dist/playground/query-history.js +259 -0
  379. package/dist/playground/query-history.js.map +1 -0
  380. package/dist/playground/result-formatter.d.ts +59 -0
  381. package/dist/playground/result-formatter.d.ts.map +1 -0
  382. package/dist/playground/result-formatter.js +341 -0
  383. package/dist/playground/result-formatter.js.map +1 -0
  384. package/dist/playground/sample-datasets.d.ts +77 -0
  385. package/dist/playground/sample-datasets.d.ts.map +1 -0
  386. package/dist/playground/sample-datasets.js +641 -0
  387. package/dist/playground/sample-datasets.js.map +1 -0
  388. package/dist/playground/sample-queries.d.ts +73 -0
  389. package/dist/playground/sample-queries.d.ts.map +1 -0
  390. package/dist/playground/sample-queries.js +1095 -0
  391. package/dist/playground/sample-queries.js.map +1 -0
  392. package/dist/playground/schema-explorer.d.ts +55 -0
  393. package/dist/playground/schema-explorer.d.ts.map +1 -0
  394. package/dist/playground/schema-explorer.js +473 -0
  395. package/dist/playground/schema-explorer.js.map +1 -0
  396. package/dist/playground/types.d.ts +430 -0
  397. package/dist/playground/types.d.ts.map +1 -0
  398. package/dist/playground/types.js +10 -0
  399. package/dist/playground/types.js.map +1 -0
  400. package/dist/readonly/cache-reader.d.ts +145 -0
  401. package/dist/readonly/cache-reader.d.ts.map +1 -0
  402. package/dist/readonly/cache-reader.js +198 -0
  403. package/dist/readonly/cache-reader.js.map +1 -0
  404. package/dist/readonly/config.d.ts +74 -0
  405. package/dist/readonly/config.d.ts.map +1 -0
  406. package/dist/readonly/config.js +67 -0
  407. package/dist/readonly/config.js.map +1 -0
  408. package/dist/readonly/index.d.ts +22 -0
  409. package/dist/readonly/index.d.ts.map +1 -0
  410. package/dist/readonly/index.js +17 -0
  411. package/dist/readonly/index.js.map +1 -0
  412. package/dist/readonly/pglite-wrapper.d.ts +82 -0
  413. package/dist/readonly/pglite-wrapper.d.ts.map +1 -0
  414. package/dist/readonly/pglite-wrapper.js +123 -0
  415. package/dist/readonly/pglite-wrapper.js.map +1 -0
  416. package/dist/readonly/worker.d.ts +142 -0
  417. package/dist/readonly/worker.d.ts.map +1 -0
  418. package/dist/readonly/worker.js +187 -0
  419. package/dist/readonly/worker.js.map +1 -0
  420. package/dist/readonly/write-blocker.d.ts +47 -0
  421. package/dist/readonly/write-blocker.d.ts.map +1 -0
  422. package/dist/readonly/write-blocker.js +136 -0
  423. package/dist/readonly/write-blocker.js.map +1 -0
  424. package/dist/recovery/disaster-recovery.d.ts +326 -0
  425. package/dist/recovery/disaster-recovery.d.ts.map +1 -0
  426. package/dist/recovery/disaster-recovery.js +799 -0
  427. package/dist/recovery/disaster-recovery.js.map +1 -0
  428. package/dist/recovery/index.d.ts +12 -0
  429. package/dist/recovery/index.d.ts.map +1 -0
  430. package/dist/recovery/index.js +12 -0
  431. package/dist/recovery/index.js.map +1 -0
  432. package/dist/recovery/parquet-parser.d.ts +321 -0
  433. package/dist/recovery/parquet-parser.d.ts.map +1 -0
  434. package/dist/recovery/parquet-parser.js +797 -0
  435. package/dist/recovery/parquet-parser.js.map +1 -0
  436. package/dist/retention/index.d.ts +50 -0
  437. package/dist/retention/index.d.ts.map +1 -0
  438. package/dist/retention/index.js +50 -0
  439. package/dist/retention/index.js.map +1 -0
  440. package/dist/retention/policy.d.ts +344 -0
  441. package/dist/retention/policy.d.ts.map +1 -0
  442. package/dist/retention/policy.js +472 -0
  443. package/dist/retention/policy.js.map +1 -0
  444. package/dist/retention/purger.d.ts +187 -0
  445. package/dist/retention/purger.d.ts.map +1 -0
  446. package/dist/retention/purger.js +411 -0
  447. package/dist/retention/purger.js.map +1 -0
  448. package/dist/rls/auth-integration.d.ts +280 -0
  449. package/dist/rls/auth-integration.d.ts.map +1 -0
  450. package/dist/rls/auth-integration.js +399 -0
  451. package/dist/rls/auth-integration.js.map +1 -0
  452. package/dist/rls/generator.d.ts +249 -0
  453. package/dist/rls/generator.d.ts.map +1 -0
  454. package/dist/rls/generator.js +495 -0
  455. package/dist/rls/generator.js.map +1 -0
  456. package/dist/rls/index.d.ts +26 -0
  457. package/dist/rls/index.d.ts.map +1 -0
  458. package/dist/rls/index.js +58 -0
  459. package/dist/rls/index.js.map +1 -0
  460. package/dist/rls/policy.d.ts +116 -0
  461. package/dist/rls/policy.d.ts.map +1 -0
  462. package/dist/rls/policy.js +77 -0
  463. package/dist/rls/policy.js.map +1 -0
  464. package/dist/rls/validator.d.ts +155 -0
  465. package/dist/rls/validator.d.ts.map +1 -0
  466. package/dist/rls/validator.js +792 -0
  467. package/dist/rls/validator.js.map +1 -0
  468. package/dist/routing/adaptive-router.d.ts +317 -0
  469. package/dist/routing/adaptive-router.d.ts.map +1 -0
  470. package/dist/routing/adaptive-router.js +554 -0
  471. package/dist/routing/adaptive-router.js.map +1 -0
  472. package/dist/routing/circuit-breaker.d.ts +339 -0
  473. package/dist/routing/circuit-breaker.d.ts.map +1 -0
  474. package/dist/routing/circuit-breaker.js +620 -0
  475. package/dist/routing/circuit-breaker.js.map +1 -0
  476. package/dist/routing/cost-metrics.d.ts +133 -0
  477. package/dist/routing/cost-metrics.d.ts.map +1 -0
  478. package/dist/routing/cost-metrics.js +259 -0
  479. package/dist/routing/cost-metrics.js.map +1 -0
  480. package/dist/routing/do-connection-pool.d.ts +243 -0
  481. package/dist/routing/do-connection-pool.d.ts.map +1 -0
  482. package/dist/routing/do-connection-pool.js +572 -0
  483. package/dist/routing/do-connection-pool.js.map +1 -0
  484. package/dist/routing/index.d.ts +59 -0
  485. package/dist/routing/index.d.ts.map +1 -0
  486. package/dist/routing/index.js +59 -0
  487. package/dist/routing/index.js.map +1 -0
  488. package/dist/routing/query-complexity-estimator.d.ts +73 -0
  489. package/dist/routing/query-complexity-estimator.d.ts.map +1 -0
  490. package/dist/routing/query-complexity-estimator.js +327 -0
  491. package/dist/routing/query-complexity-estimator.js.map +1 -0
  492. package/dist/routing/request-coalescing.d.ts +178 -0
  493. package/dist/routing/request-coalescing.d.ts.map +1 -0
  494. package/dist/routing/request-coalescing.js +325 -0
  495. package/dist/routing/request-coalescing.js.map +1 -0
  496. package/dist/routing/runtime-router.d.ts +107 -0
  497. package/dist/routing/runtime-router.d.ts.map +1 -0
  498. package/dist/routing/runtime-router.js +246 -0
  499. package/dist/routing/runtime-router.js.map +1 -0
  500. package/dist/routing/tenant-router.d.ts +848 -0
  501. package/dist/routing/tenant-router.d.ts.map +1 -0
  502. package/dist/routing/tenant-router.js +1056 -0
  503. package/dist/routing/tenant-router.js.map +1 -0
  504. package/dist/routing/websocket-pool.d.ts +119 -0
  505. package/dist/routing/websocket-pool.d.ts.map +1 -0
  506. package/dist/routing/websocket-pool.js +436 -0
  507. package/dist/routing/websocket-pool.js.map +1 -0
  508. package/dist/storage/cache-layer.d.ts +159 -0
  509. package/dist/storage/cache-layer.d.ts.map +1 -0
  510. package/dist/storage/cache-layer.js +245 -0
  511. package/dist/storage/cache-layer.js.map +1 -0
  512. package/dist/storage/cost-aware-tiering.d.ts +258 -0
  513. package/dist/storage/cost-aware-tiering.d.ts.map +1 -0
  514. package/dist/storage/cost-aware-tiering.js +526 -0
  515. package/dist/storage/cost-aware-tiering.js.map +1 -0
  516. package/dist/storage/index.d.ts +87 -0
  517. package/dist/storage/index.d.ts.map +1 -0
  518. package/dist/storage/index.js +78 -0
  519. package/dist/storage/index.js.map +1 -0
  520. package/dist/storage/interfaces.d.ts +856 -0
  521. package/dist/storage/interfaces.d.ts.map +1 -0
  522. package/dist/storage/interfaces.js +69 -0
  523. package/dist/storage/interfaces.js.map +1 -0
  524. package/dist/storage/r2-layer.d.ts +226 -0
  525. package/dist/storage/r2-layer.d.ts.map +1 -0
  526. package/dist/storage/r2-layer.js +307 -0
  527. package/dist/storage/r2-layer.js.map +1 -0
  528. package/dist/storage/r2-overflow.d.ts +344 -0
  529. package/dist/storage/r2-overflow.d.ts.map +1 -0
  530. package/dist/storage/r2-overflow.js +730 -0
  531. package/dist/storage/r2-overflow.js.map +1 -0
  532. package/dist/storage/r2-page-vfs.d.ts +374 -0
  533. package/dist/storage/r2-page-vfs.d.ts.map +1 -0
  534. package/dist/storage/r2-page-vfs.js +754 -0
  535. package/dist/storage/r2-page-vfs.js.map +1 -0
  536. package/dist/storage/swr-cache.d.ts +181 -0
  537. package/dist/storage/swr-cache.d.ts.map +1 -0
  538. package/dist/storage/swr-cache.js +295 -0
  539. package/dist/storage/swr-cache.js.map +1 -0
  540. package/dist/storage/tiered-orchestrator.d.ts +951 -0
  541. package/dist/storage/tiered-orchestrator.d.ts.map +1 -0
  542. package/dist/storage/tiered-orchestrator.js +1731 -0
  543. package/dist/storage/tiered-orchestrator.js.map +1 -0
  544. package/dist/storage/tiered-vfs-swr.d.ts +279 -0
  545. package/dist/storage/tiered-vfs-swr.d.ts.map +1 -0
  546. package/dist/storage/tiered-vfs-swr.js +584 -0
  547. package/dist/storage/tiered-vfs-swr.js.map +1 -0
  548. package/dist/storage/tiered-vfs.d.ts +405 -0
  549. package/dist/storage/tiered-vfs.d.ts.map +1 -0
  550. package/dist/storage/tiered-vfs.js +833 -0
  551. package/dist/storage/tiered-vfs.js.map +1 -0
  552. package/dist/streaming/backpressure-controller.d.ts +173 -0
  553. package/dist/streaming/backpressure-controller.d.ts.map +1 -0
  554. package/dist/streaming/backpressure-controller.js +344 -0
  555. package/dist/streaming/backpressure-controller.js.map +1 -0
  556. package/dist/streaming/buffer-pool.d.ts +241 -0
  557. package/dist/streaming/buffer-pool.d.ts.map +1 -0
  558. package/dist/streaming/buffer-pool.js +381 -0
  559. package/dist/streaming/buffer-pool.js.map +1 -0
  560. package/dist/streaming/cdc-iceberg-connector.d.ts +272 -0
  561. package/dist/streaming/cdc-iceberg-connector.d.ts.map +1 -0
  562. package/dist/streaming/cdc-iceberg-connector.js +408 -0
  563. package/dist/streaming/cdc-iceberg-connector.js.map +1 -0
  564. package/dist/streaming/index.d.ts +111 -0
  565. package/dist/streaming/index.d.ts.map +1 -0
  566. package/dist/streaming/index.js +128 -0
  567. package/dist/streaming/index.js.map +1 -0
  568. package/dist/streaming/live-cdc-stream.d.ts +400 -0
  569. package/dist/streaming/live-cdc-stream.d.ts.map +1 -0
  570. package/dist/streaming/live-cdc-stream.js +703 -0
  571. package/dist/streaming/live-cdc-stream.js.map +1 -0
  572. package/dist/streaming/memory-bounded-stream.d.ts +207 -0
  573. package/dist/streaming/memory-bounded-stream.d.ts.map +1 -0
  574. package/dist/streaming/memory-bounded-stream.js +340 -0
  575. package/dist/streaming/memory-bounded-stream.js.map +1 -0
  576. package/dist/streaming/query-streamer.d.ts +379 -0
  577. package/dist/streaming/query-streamer.d.ts.map +1 -0
  578. package/dist/streaming/query-streamer.js +495 -0
  579. package/dist/streaming/query-streamer.js.map +1 -0
  580. package/dist/streaming/response-streaming.d.ts +203 -0
  581. package/dist/streaming/response-streaming.d.ts.map +1 -0
  582. package/dist/streaming/response-streaming.js +449 -0
  583. package/dist/streaming/response-streaming.js.map +1 -0
  584. package/dist/types/branded.d.ts +859 -0
  585. package/dist/types/branded.d.ts.map +1 -0
  586. package/dist/types/branded.js +891 -0
  587. package/dist/types/branded.js.map +1 -0
  588. package/dist/types/utilities.d.ts +757 -0
  589. package/dist/types/utilities.d.ts.map +1 -0
  590. package/dist/types/utilities.js +447 -0
  591. package/dist/types/utilities.js.map +1 -0
  592. package/dist/wal/replay-engine.d.ts +344 -0
  593. package/dist/wal/replay-engine.d.ts.map +1 -0
  594. package/dist/wal/replay-engine.js +975 -0
  595. package/dist/wal/replay-engine.js.map +1 -0
  596. package/dist/worker/__mocks__/capnweb.d.ts +13 -0
  597. package/dist/worker/__mocks__/capnweb.d.ts.map +1 -0
  598. package/dist/worker/__mocks__/capnweb.js +15 -0
  599. package/dist/worker/__mocks__/capnweb.js.map +1 -0
  600. package/dist/worker/__mocks__/cloudflare-workers.d.ts +31 -0
  601. package/dist/worker/__mocks__/cloudflare-workers.d.ts.map +1 -0
  602. package/dist/worker/__mocks__/cloudflare-workers.js +33 -0
  603. package/dist/worker/__mocks__/cloudflare-workers.js.map +1 -0
  604. package/dist/worker/__mocks__/pglite.data.d.ts +3 -0
  605. package/dist/worker/__mocks__/pglite.data.d.ts.map +1 -0
  606. package/dist/worker/__mocks__/pglite.data.js +20 -0
  607. package/dist/worker/__mocks__/pglite.data.js.map +1 -0
  608. package/dist/worker/__mocks__/pglite.wasm.d.ts +3 -0
  609. package/dist/worker/__mocks__/pglite.wasm.d.ts.map +1 -0
  610. package/dist/worker/__mocks__/pglite.wasm.js +30 -0
  611. package/dist/worker/__mocks__/pglite.wasm.js.map +1 -0
  612. package/dist/worker/auth-rate-limiter.d.ts +270 -0
  613. package/dist/worker/auth-rate-limiter.d.ts.map +1 -0
  614. package/dist/worker/auth-rate-limiter.js +332 -0
  615. package/dist/worker/auth-rate-limiter.js.map +1 -0
  616. package/dist/worker/auth.d.ts +345 -0
  617. package/dist/worker/auth.d.ts.map +1 -0
  618. package/dist/worker/auth.js +837 -0
  619. package/dist/worker/auth.js.map +1 -0
  620. package/dist/worker/cdc-backpressure.d.ts +338 -0
  621. package/dist/worker/cdc-backpressure.d.ts.map +1 -0
  622. package/dist/worker/cdc-backpressure.js +619 -0
  623. package/dist/worker/cdc-backpressure.js.map +1 -0
  624. package/dist/worker/cdc-sse.d.ts +277 -0
  625. package/dist/worker/cdc-sse.d.ts.map +1 -0
  626. package/dist/worker/cdc-sse.js +528 -0
  627. package/dist/worker/cdc-sse.js.map +1 -0
  628. package/dist/worker/cdc-websocket.d.ts +252 -0
  629. package/dist/worker/cdc-websocket.d.ts.map +1 -0
  630. package/dist/worker/cdc-websocket.js +940 -0
  631. package/dist/worker/cdc-websocket.js.map +1 -0
  632. package/dist/worker/cdc.d.ts +95 -0
  633. package/dist/worker/cdc.d.ts.map +1 -0
  634. package/dist/worker/cdc.js +211 -0
  635. package/dist/worker/cdc.js.map +1 -0
  636. package/dist/worker/concerns/auth-concern.d.ts +50 -0
  637. package/dist/worker/concerns/auth-concern.d.ts.map +1 -0
  638. package/dist/worker/concerns/auth-concern.js +131 -0
  639. package/dist/worker/concerns/auth-concern.js.map +1 -0
  640. package/dist/worker/concerns/cdc-concern.d.ts +99 -0
  641. package/dist/worker/concerns/cdc-concern.d.ts.map +1 -0
  642. package/dist/worker/concerns/cdc-concern.js +137 -0
  643. package/dist/worker/concerns/cdc-concern.js.map +1 -0
  644. package/dist/worker/concerns/index.d.ts +22 -0
  645. package/dist/worker/concerns/index.d.ts.map +1 -0
  646. package/dist/worker/concerns/index.js +13 -0
  647. package/dist/worker/concerns/index.js.map +1 -0
  648. package/dist/worker/concerns/query-execution-concern.d.ts +104 -0
  649. package/dist/worker/concerns/query-execution-concern.d.ts.map +1 -0
  650. package/dist/worker/concerns/query-execution-concern.js +95 -0
  651. package/dist/worker/concerns/query-execution-concern.js.map +1 -0
  652. package/dist/worker/concerns/storage-orchestration-concern.d.ts +78 -0
  653. package/dist/worker/concerns/storage-orchestration-concern.d.ts.map +1 -0
  654. package/dist/worker/concerns/storage-orchestration-concern.js +240 -0
  655. package/dist/worker/concerns/storage-orchestration-concern.js.map +1 -0
  656. package/dist/worker/do-auth-manager.d.ts +108 -0
  657. package/dist/worker/do-auth-manager.d.ts.map +1 -0
  658. package/dist/worker/do-auth-manager.js +212 -0
  659. package/dist/worker/do-auth-manager.js.map +1 -0
  660. package/dist/worker/do-pglite-manager.d.ts +137 -0
  661. package/dist/worker/do-pglite-manager.d.ts.map +1 -0
  662. package/dist/worker/do-pglite-manager.js +228 -0
  663. package/dist/worker/do-pglite-manager.js.map +1 -0
  664. package/dist/worker/do.d.ts +556 -0
  665. package/dist/worker/do.d.ts.map +1 -0
  666. package/dist/worker/do.js +1441 -0
  667. package/dist/worker/do.js.map +1 -0
  668. package/dist/worker/entry.d.ts +23 -0
  669. package/dist/worker/entry.d.ts.map +1 -0
  670. package/dist/worker/entry.js +362 -0
  671. package/dist/worker/entry.js.map +1 -0
  672. package/dist/worker/errors.d.ts +106 -0
  673. package/dist/worker/errors.d.ts.map +1 -0
  674. package/dist/worker/errors.js +178 -0
  675. package/dist/worker/errors.js.map +1 -0
  676. package/dist/worker/health-check-manager.d.ts +141 -0
  677. package/dist/worker/health-check-manager.d.ts.map +1 -0
  678. package/dist/worker/health-check-manager.js +145 -0
  679. package/dist/worker/health-check-manager.js.map +1 -0
  680. package/dist/worker/index.d.ts +60 -0
  681. package/dist/worker/index.d.ts.map +1 -0
  682. package/dist/worker/index.js +67 -0
  683. package/dist/worker/index.js.map +1 -0
  684. package/dist/worker/memory-pressure.d.ts +892 -0
  685. package/dist/worker/memory-pressure.d.ts.map +1 -0
  686. package/dist/worker/memory-pressure.js +1990 -0
  687. package/dist/worker/memory-pressure.js.map +1 -0
  688. package/dist/worker/migration-manager.d.ts +153 -0
  689. package/dist/worker/migration-manager.d.ts.map +1 -0
  690. package/dist/worker/migration-manager.js +461 -0
  691. package/dist/worker/migration-manager.js.map +1 -0
  692. package/dist/worker/plugin-manager.d.ts +147 -0
  693. package/dist/worker/plugin-manager.d.ts.map +1 -0
  694. package/dist/worker/plugin-manager.js +408 -0
  695. package/dist/worker/plugin-manager.js.map +1 -0
  696. package/dist/worker/proxy.d.ts +330 -0
  697. package/dist/worker/proxy.d.ts.map +1 -0
  698. package/dist/worker/proxy.js +504 -0
  699. package/dist/worker/proxy.js.map +1 -0
  700. package/dist/worker/query-execution-manager.d.ts +107 -0
  701. package/dist/worker/query-execution-manager.d.ts.map +1 -0
  702. package/dist/worker/query-execution-manager.js +155 -0
  703. package/dist/worker/query-execution-manager.js.map +1 -0
  704. package/dist/worker/query-executor.d.ts +163 -0
  705. package/dist/worker/query-executor.d.ts.map +1 -0
  706. package/dist/worker/query-executor.js +413 -0
  707. package/dist/worker/query-executor.js.map +1 -0
  708. package/dist/worker/query-stats-manager.d.ts +117 -0
  709. package/dist/worker/query-stats-manager.d.ts.map +1 -0
  710. package/dist/worker/query-stats-manager.js +162 -0
  711. package/dist/worker/query-stats-manager.js.map +1 -0
  712. package/dist/worker/result-handler.d.ts +192 -0
  713. package/dist/worker/result-handler.d.ts.map +1 -0
  714. package/dist/worker/result-handler.js +346 -0
  715. package/dist/worker/result-handler.js.map +1 -0
  716. package/dist/worker/routes.d.ts +135 -0
  717. package/dist/worker/routes.d.ts.map +1 -0
  718. package/dist/worker/routes.js +460 -0
  719. package/dist/worker/routes.js.map +1 -0
  720. package/dist/worker/rpc-methods-manager.d.ts +142 -0
  721. package/dist/worker/rpc-methods-manager.d.ts.map +1 -0
  722. package/dist/worker/rpc-methods-manager.js +195 -0
  723. package/dist/worker/rpc-methods-manager.js.map +1 -0
  724. package/dist/worker/rpc.d.ts +259 -0
  725. package/dist/worker/rpc.d.ts.map +1 -0
  726. package/dist/worker/rpc.js +398 -0
  727. package/dist/worker/rpc.js.map +1 -0
  728. package/dist/worker/schema-version.d.ts +209 -0
  729. package/dist/worker/schema-version.d.ts.map +1 -0
  730. package/dist/worker/schema-version.js +450 -0
  731. package/dist/worker/schema-version.js.map +1 -0
  732. package/dist/worker/session-manager.d.ts +282 -0
  733. package/dist/worker/session-manager.d.ts.map +1 -0
  734. package/dist/worker/session-manager.js +523 -0
  735. package/dist/worker/session-manager.js.map +1 -0
  736. package/dist/worker/shutdown-manager.d.ts +188 -0
  737. package/dist/worker/shutdown-manager.d.ts.map +1 -0
  738. package/dist/worker/shutdown-manager.js +347 -0
  739. package/dist/worker/shutdown-manager.js.map +1 -0
  740. package/dist/worker/sql-transform.d.ts +61 -0
  741. package/dist/worker/sql-transform.d.ts.map +1 -0
  742. package/dist/worker/sql-transform.js +312 -0
  743. package/dist/worker/sql-transform.js.map +1 -0
  744. package/dist/worker/types.d.ts +738 -0
  745. package/dist/worker/types.d.ts.map +1 -0
  746. package/dist/worker/types.js +6 -0
  747. package/dist/worker/types.js.map +1 -0
  748. package/dist/worker/user-routes.d.ts +76 -0
  749. package/dist/worker/user-routes.d.ts.map +1 -0
  750. package/dist/worker/user-routes.js +188 -0
  751. package/dist/worker/user-routes.js.map +1 -0
  752. package/dist/worker/wal-facade.d.ts +138 -0
  753. package/dist/worker/wal-facade.d.ts.map +1 -0
  754. package/dist/worker/wal-facade.js +184 -0
  755. package/dist/worker/wal-facade.js.map +1 -0
  756. package/dist/worker/wal-r2.d.ts +271 -0
  757. package/dist/worker/wal-r2.d.ts.map +1 -0
  758. package/dist/worker/wal-r2.js +689 -0
  759. package/dist/worker/wal-r2.js.map +1 -0
  760. package/dist/worker/wal-replay.d.ts +361 -0
  761. package/dist/worker/wal-replay.d.ts.map +1 -0
  762. package/dist/worker/wal-replay.js +628 -0
  763. package/dist/worker/wal-replay.js.map +1 -0
  764. package/dist/worker/wal-retention.d.ts +389 -0
  765. package/dist/worker/wal-retention.d.ts.map +1 -0
  766. package/dist/worker/wal-retention.js +763 -0
  767. package/dist/worker/wal-retention.js.map +1 -0
  768. package/dist/worker/wal.d.ts +278 -0
  769. package/dist/worker/wal.d.ts.map +1 -0
  770. package/dist/worker/wal.js +467 -0
  771. package/dist/worker/wal.js.map +1 -0
  772. package/dist/worker/websocket.d.ts +85 -0
  773. package/dist/worker/websocket.d.ts.map +1 -0
  774. package/dist/worker/websocket.js +227 -0
  775. package/dist/worker/websocket.js.map +1 -0
  776. package/package.json +108 -0
  777. package/src/cdc/change-stream.ts +137 -0
  778. package/src/cdc/filter.ts +646 -0
  779. package/src/cdc/index.ts +112 -0
  780. package/src/cdc/resume-token.ts +280 -0
  781. package/src/cdc/transport/index.ts +7 -0
  782. package/src/cdc/transport/sse.ts +723 -0
  783. package/src/cdc/transport/websocket.ts +873 -0
  784. package/src/cdc/types.ts +346 -0
  785. package/src/config/index.ts +25 -0
  786. package/src/config/memory.ts +177 -0
  787. package/src/config/storage.ts +204 -0
  788. package/src/config/streaming.ts +147 -0
  789. package/src/config/timeouts.ts +221 -0
  790. package/src/extensions/config.test.ts +187 -0
  791. package/src/extensions/config.ts +278 -0
  792. package/src/extensions/geo.test.ts +455 -0
  793. package/src/extensions/geo.ts +858 -0
  794. package/src/extensions/index.test.ts +259 -0
  795. package/src/extensions/index.ts +227 -0
  796. package/src/extensions/loader.test.ts +555 -0
  797. package/src/extensions/loader.ts +588 -0
  798. package/src/extensions/pgmq-lite.test.ts +727 -0
  799. package/src/extensions/pgmq-lite.ts +770 -0
  800. package/src/extensions/plugins.test.ts +528 -0
  801. package/src/extensions/plugins.ts +718 -0
  802. package/src/extensions/registry.test.ts +202 -0
  803. package/src/extensions/registry.ts +267 -0
  804. package/src/extensions/vector.test.ts +195 -0
  805. package/src/extensions/vector.ts +217 -0
  806. package/src/iceberg/SCHEDULER.md +580 -0
  807. package/src/iceberg/analytics.test.ts +703 -0
  808. package/src/iceberg/analytics.ts +727 -0
  809. package/src/iceberg/catalog-api.test.ts +838 -0
  810. package/src/iceberg/catalog-api.ts +520 -0
  811. package/src/iceberg/catalog.test.ts +680 -0
  812. package/src/iceberg/catalog.ts +1007 -0
  813. package/src/iceberg/iceberg.test.ts +705 -0
  814. package/src/iceberg/index.ts +406 -0
  815. package/src/iceberg/metadata.test.ts +632 -0
  816. package/src/iceberg/metadata.ts +649 -0
  817. package/src/iceberg/optimizer.test.ts +868 -0
  818. package/src/iceberg/optimizer.ts +1287 -0
  819. package/src/iceberg/parquet.test.ts +899 -0
  820. package/src/iceberg/parquet.ts +1640 -0
  821. package/src/iceberg/r2-organization.test.ts +615 -0
  822. package/src/iceberg/r2-organization.ts +951 -0
  823. package/src/iceberg/scheduler-do-example.ts +364 -0
  824. package/src/iceberg/scheduler.test.ts +861 -0
  825. package/src/iceberg/scheduler.ts +1201 -0
  826. package/src/iceberg/schema.test.ts +547 -0
  827. package/src/iceberg/schema.ts +616 -0
  828. package/src/iceberg/snapshot-manager.test.ts +919 -0
  829. package/src/iceberg/snapshot-manager.ts +1369 -0
  830. package/src/iceberg/sql-router.test.ts +334 -0
  831. package/src/iceberg/sql-router.ts +337 -0
  832. package/src/iceberg/test-fixtures.ts +605 -0
  833. package/src/iceberg/time-travel-api.test.ts +1029 -0
  834. package/src/iceberg/time-travel-api.ts +731 -0
  835. package/src/iceberg/time-travel.test.ts +1218 -0
  836. package/src/iceberg/time-travel.ts +1052 -0
  837. package/src/iceberg/transformer.test.ts +689 -0
  838. package/src/iceberg/transformer.ts +1029 -0
  839. package/src/iceberg/types.ts +373 -0
  840. package/src/iceberg/writer.test.ts +716 -0
  841. package/src/iceberg/writer.ts +590 -0
  842. package/src/index.ts +212 -0
  843. package/src/lineage/index.ts +42 -0
  844. package/src/lineage/integration.ts +334 -0
  845. package/src/lineage/tracker.ts +1618 -0
  846. package/src/lineage/types.ts +354 -0
  847. package/src/middleware/index.ts +36 -0
  848. package/src/middleware/rate-limit-concurrent.test.ts +794 -0
  849. package/src/middleware/rate-limit.test.ts +1568 -0
  850. package/src/middleware/rate-limit.ts +840 -0
  851. package/src/migration-tooling/external-migration.test.ts +1864 -0
  852. package/src/migration-tooling/external-migration.ts +2355 -0
  853. package/src/migration-tooling/index.ts +19 -0
  854. package/src/migrations/ARCHITECTURE.md +474 -0
  855. package/src/migrations/PROGRESS_TRACKING.md +485 -0
  856. package/src/migrations/auto-migrator.test.ts +732 -0
  857. package/src/migrations/auto-migrator.ts +531 -0
  858. package/src/migrations/bulk-orchestrator.test.ts +801 -0
  859. package/src/migrations/bulk-orchestrator.ts +1039 -0
  860. package/src/migrations/compatibility.test.ts +958 -0
  861. package/src/migrations/compatibility.ts +902 -0
  862. package/src/migrations/do-migrations.test.ts +2620 -0
  863. package/src/migrations/do-migrations.ts +1289 -0
  864. package/src/migrations/do-migrations.types.ts +715 -0
  865. package/src/migrations/drizzle-compat.test.ts +210 -0
  866. package/src/migrations/drizzle-compat.ts +337 -0
  867. package/src/migrations/index.ts +334 -0
  868. package/src/migrations/migration-api.test.ts +438 -0
  869. package/src/migrations/migration-api.ts +704 -0
  870. package/src/migrations/progress-tracker-do.ts +518 -0
  871. package/src/migrations/progress-tracker-kv.ts +305 -0
  872. package/src/migrations/progress-tracker.test.ts +937 -0
  873. package/src/migrations/progress-tracker.ts +665 -0
  874. package/src/migrations/registry.test.ts +331 -0
  875. package/src/migrations/registry.ts +468 -0
  876. package/src/migrations/rollback.test.ts +644 -0
  877. package/src/migrations/runner.test.ts +807 -0
  878. package/src/migrations/runner.test.ts.backup +759 -0
  879. package/src/migrations/runner.ts +1459 -0
  880. package/src/migrations/schema-generator.test.ts +649 -0
  881. package/src/migrations/schema-generator.ts +513 -0
  882. package/src/migrations/testing.ts +1037 -0
  883. package/src/migrations/types.ts +573 -0
  884. package/src/migrations/validator.test.ts +660 -0
  885. package/src/migrations/validator.ts +741 -0
  886. package/src/observability/alerting.test.ts +1133 -0
  887. package/src/observability/alerting.ts +455 -0
  888. package/src/observability/analytics-engine.ts +733 -0
  889. package/src/observability/cost-metrics.ts +804 -0
  890. package/src/observability/cross-do-tracing.test.ts +516 -0
  891. package/src/observability/cross-do-tracing.ts +588 -0
  892. package/src/observability/dashboards/postgres-do-overview.json +1656 -0
  893. package/src/observability/error-rate-collector.test.ts +977 -0
  894. package/src/observability/error-rate-collector.ts +518 -0
  895. package/src/observability/exporters.test.ts +365 -0
  896. package/src/observability/exporters.ts +650 -0
  897. package/src/observability/health-check.test.ts +353 -0
  898. package/src/observability/health-check.ts +341 -0
  899. package/src/observability/index.test.ts +298 -0
  900. package/src/observability/index.ts +885 -0
  901. package/src/observability/instrumentation.test.ts +428 -0
  902. package/src/observability/instrumentation.ts +788 -0
  903. package/src/observability/memory-metrics.test.ts +355 -0
  904. package/src/observability/memory-metrics.ts +990 -0
  905. package/src/observability/metrics-endpoint.test.ts +402 -0
  906. package/src/observability/metrics-endpoint.ts +374 -0
  907. package/src/observability/metrics.test.ts +291 -0
  908. package/src/observability/metrics.ts +315 -0
  909. package/src/observability/observability-features.ts +1296 -0
  910. package/src/observability/prometheus.test.ts +292 -0
  911. package/src/observability/prometheus.ts +170 -0
  912. package/src/observability/propagation.test.ts +417 -0
  913. package/src/observability/propagation.ts +294 -0
  914. package/src/observability/query-latency.ts +586 -0
  915. package/src/observability/query-performance.test.ts +406 -0
  916. package/src/observability/query-performance.ts +491 -0
  917. package/src/observability/storage-tier-metrics.test.ts +633 -0
  918. package/src/observability/storage-tier-metrics.ts +570 -0
  919. package/src/observability/tier-cost-optimizer.ts +740 -0
  920. package/src/observability/tracer.test.ts +346 -0
  921. package/src/observability/tracer.ts +585 -0
  922. package/src/observability/types.test.ts +726 -0
  923. package/src/observability/types.ts +434 -0
  924. package/src/pglite/auto-demotion.test.ts +477 -0
  925. package/src/pglite/auto-demotion.ts +385 -0
  926. package/src/pglite/auto-promotion.test.ts +824 -0
  927. package/src/pglite/auto-promotion.ts +547 -0
  928. package/src/pglite/cache-layer.test.ts +469 -0
  929. package/src/pglite/cache-layer.ts +271 -0
  930. package/src/pglite/cold-start-manager.ts +1260 -0
  931. package/src/pglite/cold-start-optimizer.test.ts +937 -0
  932. package/src/pglite/cold-start-optimizer.ts +1895 -0
  933. package/src/pglite/dovfs-adapter.ts +1122 -0
  934. package/src/pglite/dovfs.ts +1258 -0
  935. package/src/pglite/etag-cache.test.ts +844 -0
  936. package/src/pglite/etag-cache.ts +526 -0
  937. package/src/pglite/index.ts +442 -0
  938. package/src/pglite/init.test.ts +455 -0
  939. package/src/pglite/init.ts +574 -0
  940. package/src/pglite/lifecycle.test.ts +599 -0
  941. package/src/pglite/lifecycle.ts +704 -0
  942. package/src/pglite/parallel-loader.test.ts +586 -0
  943. package/src/pglite/parallel-loader.ts +481 -0
  944. package/src/pglite/production-pglite.test.ts +666 -0
  945. package/src/pglite/production-pglite.ts +537 -0
  946. package/src/pglite/query-executor.ts +614 -0
  947. package/src/pglite/r2-layer.test.ts +501 -0
  948. package/src/pglite/r2-layer.ts +322 -0
  949. package/src/pglite/tiered-init.test.ts +725 -0
  950. package/src/pglite/tiered-init.ts +556 -0
  951. package/src/pglite/tiered-vfs.test.ts +726 -0
  952. package/src/pglite/tiered-vfs.ts +33 -0
  953. package/src/pglite/tiering-stats.test.ts +531 -0
  954. package/src/pglite/tiering-stats.ts +407 -0
  955. package/src/pglite/transaction-hooks.ts +343 -0
  956. package/src/pglite/warm-loader.test.ts +1701 -0
  957. package/src/pglite/warm-loader.ts +528 -0
  958. package/src/pglite/workers-pglite.ts +224 -0
  959. package/src/pglite-assets/pglite.data +0 -0
  960. package/src/pglite-assets/pglite.wasm +0 -0
  961. package/src/pglite.d.ts +47 -0
  962. package/src/playground/index.ts +137 -0
  963. package/src/playground/keyboard-shortcuts.ts +677 -0
  964. package/src/playground/playground.ts +323 -0
  965. package/src/playground/query-executor.ts +669 -0
  966. package/src/playground/query-history.ts +328 -0
  967. package/src/playground/result-formatter.ts +420 -0
  968. package/src/playground/sample-datasets.ts +674 -0
  969. package/src/playground/sample-queries.ts +1168 -0
  970. package/src/playground/schema-explorer.ts +558 -0
  971. package/src/playground/types.ts +518 -0
  972. package/src/readonly/cache-reader.test.ts +460 -0
  973. package/src/readonly/cache-reader.ts +313 -0
  974. package/src/readonly/config.test.ts +187 -0
  975. package/src/readonly/config.ts +128 -0
  976. package/src/readonly/index.ts +50 -0
  977. package/src/readonly/pglite-wrapper.test.ts +278 -0
  978. package/src/readonly/pglite-wrapper.ts +184 -0
  979. package/src/readonly/worker.test.ts +533 -0
  980. package/src/readonly/worker.ts +341 -0
  981. package/src/readonly/write-blocker.test.ts +459 -0
  982. package/src/readonly/write-blocker.ts +175 -0
  983. package/src/recovery/disaster-recovery.test.ts +618 -0
  984. package/src/recovery/disaster-recovery.ts +1181 -0
  985. package/src/recovery/index.ts +43 -0
  986. package/src/recovery/parquet-parser.ts +974 -0
  987. package/src/retention/index.ts +74 -0
  988. package/src/retention/policy.test.ts +571 -0
  989. package/src/retention/policy.ts +774 -0
  990. package/src/retention/purger.test.ts +465 -0
  991. package/src/retention/purger.ts +558 -0
  992. package/src/rls/auth-integration.test.ts +752 -0
  993. package/src/rls/auth-integration.ts +533 -0
  994. package/src/rls/generator.test.ts +829 -0
  995. package/src/rls/generator.ts +573 -0
  996. package/src/rls/index.ts +128 -0
  997. package/src/rls/policy.ts +208 -0
  998. package/src/rls/rls.test.ts +1071 -0
  999. package/src/rls/validator.test.ts +930 -0
  1000. package/src/rls/validator.ts +895 -0
  1001. package/src/routing/adaptive-router.test.ts +884 -0
  1002. package/src/routing/adaptive-router.ts +845 -0
  1003. package/src/routing/circuit-breaker.test.ts +1505 -0
  1004. package/src/routing/circuit-breaker.ts +852 -0
  1005. package/src/routing/cost-metrics.test.ts +565 -0
  1006. package/src/routing/cost-metrics.ts +408 -0
  1007. package/src/routing/do-connection-pool.test.ts +1109 -0
  1008. package/src/routing/do-connection-pool.ts +828 -0
  1009. package/src/routing/index.ts +158 -0
  1010. package/src/routing/query-complexity-estimator.test.ts +356 -0
  1011. package/src/routing/query-complexity-estimator.ts +444 -0
  1012. package/src/routing/request-coalescing.test.ts +738 -0
  1013. package/src/routing/request-coalescing.ts +475 -0
  1014. package/src/routing/runtime-router.test.ts +436 -0
  1015. package/src/routing/runtime-router.ts +357 -0
  1016. package/src/routing/tenant-router.test.ts +2493 -0
  1017. package/src/routing/tenant-router.ts +1908 -0
  1018. package/src/routing/websocket-pool.test.ts +551 -0
  1019. package/src/routing/websocket-pool.ts +577 -0
  1020. package/src/storage/access-pattern-tracker.test.ts +874 -0
  1021. package/src/storage/cache-layer.test.ts +560 -0
  1022. package/src/storage/cache-layer.ts +328 -0
  1023. package/src/storage/cost-aware-tiering.test.ts +652 -0
  1024. package/src/storage/cost-aware-tiering.ts +794 -0
  1025. package/src/storage/do-sqlite-blobs.test.ts +937 -0
  1026. package/src/storage/index.ts +272 -0
  1027. package/src/storage/interfaces.ts +974 -0
  1028. package/src/storage/r2-layer.test.ts +653 -0
  1029. package/src/storage/r2-layer.ts +434 -0
  1030. package/src/storage/r2-overflow.ts +920 -0
  1031. package/src/storage/r2-page-vfs.test.ts +2348 -0
  1032. package/src/storage/r2-page-vfs.ts +1054 -0
  1033. package/src/storage/swr-cache.test.ts +832 -0
  1034. package/src/storage/swr-cache.ts +398 -0
  1035. package/src/storage/swr-tiered-integration.test.ts +617 -0
  1036. package/src/storage/tiered-orchestrator.test.ts +2441 -0
  1037. package/src/storage/tiered-orchestrator.ts +2081 -0
  1038. package/src/storage/tiered-vfs-swr.test.ts +736 -0
  1039. package/src/storage/tiered-vfs-swr.ts +735 -0
  1040. package/src/storage/tiered-vfs.test.ts +793 -0
  1041. package/src/storage/tiered-vfs.ts +1082 -0
  1042. package/src/streaming/backpressure-controller.ts +452 -0
  1043. package/src/streaming/buffer-pool.ts +484 -0
  1044. package/src/streaming/cdc-iceberg-connector.ts +605 -0
  1045. package/src/streaming/index.ts +225 -0
  1046. package/src/streaming/live-cdc-stream.ts +985 -0
  1047. package/src/streaming/memory-bounded-stream.ts +443 -0
  1048. package/src/streaming/query-streamer.ts +662 -0
  1049. package/src/streaming/response-streaming.ts +557 -0
  1050. package/src/types/branded.ts +1075 -0
  1051. package/src/types/branded.ts.backup +273 -0
  1052. package/src/types/utilities.ts +1023 -0
  1053. package/src/types/wasm.d.ts +30 -0
  1054. package/src/validation/typed-errors.test.ts +420 -0
  1055. package/src/wal/replay-engine.ts +1264 -0
  1056. package/src/worker/__mocks__/capnweb.ts +15 -0
  1057. package/src/worker/__mocks__/pglite.data.ts +22 -0
  1058. package/src/worker/__mocks__/pglite.wasm.ts +33 -0
  1059. package/src/worker/auth-rate-limiter.test.ts +272 -0
  1060. package/src/worker/auth-rate-limiter.ts +448 -0
  1061. package/src/worker/auth.security-red.test.ts +1236 -0
  1062. package/src/worker/auth.security.test.ts +822 -0
  1063. package/src/worker/auth.test.ts +469 -0
  1064. package/src/worker/auth.ts +1104 -0
  1065. package/src/worker/cdc-backpressure.test.ts +726 -0
  1066. package/src/worker/cdc-backpressure.ts +866 -0
  1067. package/src/worker/cdc-sse.test.ts +780 -0
  1068. package/src/worker/cdc-sse.ts +728 -0
  1069. package/src/worker/cdc-websocket.ts +1229 -0
  1070. package/src/worker/cdc-ws.test.ts +1009 -0
  1071. package/src/worker/cdc.test.ts +327 -0
  1072. package/src/worker/cdc.ts +289 -0
  1073. package/src/worker/concerns/auth-concern.ts +179 -0
  1074. package/src/worker/concerns/cdc-concern.ts +247 -0
  1075. package/src/worker/concerns/index.ts +58 -0
  1076. package/src/worker/concerns/query-execution-concern.ts +194 -0
  1077. package/src/worker/concerns/storage-orchestration-concern.ts +373 -0
  1078. package/src/worker/discriminated-types.test.ts +280 -0
  1079. package/src/worker/do-auth-manager.ts +257 -0
  1080. package/src/worker/do-decomposition.test.ts +1236 -0
  1081. package/src/worker/do-pglite-manager.ts +302 -0
  1082. package/src/worker/do.test.ts +2254 -0
  1083. package/src/worker/do.ts +1878 -0
  1084. package/src/worker/entry.ts +417 -0
  1085. package/src/worker/errors.ts +285 -0
  1086. package/src/worker/health-check-manager.test.ts +261 -0
  1087. package/src/worker/health-check-manager.ts +231 -0
  1088. package/src/worker/index.ts +389 -0
  1089. package/src/worker/memory-pressure.test.ts +1460 -0
  1090. package/src/worker/memory-pressure.ts +2650 -0
  1091. package/src/worker/migration-manager.ts +582 -0
  1092. package/src/worker/neon-compat.test.ts +332 -0
  1093. package/src/worker/plugin-manager.ts +485 -0
  1094. package/src/worker/postgres.do-rpc.d.ts +76 -0
  1095. package/src/worker/proxy.ts +694 -0
  1096. package/src/worker/query-execution-manager.test.ts +303 -0
  1097. package/src/worker/query-execution-manager.ts +219 -0
  1098. package/src/worker/query-executor.test.ts +282 -0
  1099. package/src/worker/query-executor.ts +560 -0
  1100. package/src/worker/query-stats-manager.ts +229 -0
  1101. package/src/worker/result-handler.test.ts +364 -0
  1102. package/src/worker/result-handler.ts +510 -0
  1103. package/src/worker/routes.test.ts +795 -0
  1104. package/src/worker/routes.ts +650 -0
  1105. package/src/worker/rpc-methods-manager.test.ts +326 -0
  1106. package/src/worker/rpc-methods-manager.ts +276 -0
  1107. package/src/worker/rpc.ts +524 -0
  1108. package/src/worker/schema-version.ts +605 -0
  1109. package/src/worker/session-manager.test.ts +506 -0
  1110. package/src/worker/session-manager.ts +732 -0
  1111. package/src/worker/shutdown-manager.ts +469 -0
  1112. package/src/worker/sql-transform.test.ts +286 -0
  1113. package/src/worker/sql-transform.ts +368 -0
  1114. package/src/worker/supabase-compat.test.ts +621 -0
  1115. package/src/worker/types.test.ts +292 -0
  1116. package/src/worker/types.ts +873 -0
  1117. package/src/worker/user-routes.test.ts +703 -0
  1118. package/src/worker/user-routes.ts +303 -0
  1119. package/src/worker/wal-facade.ts +235 -0
  1120. package/src/worker/wal-r2.test.ts +570 -0
  1121. package/src/worker/wal-r2.ts +930 -0
  1122. package/src/worker/wal-replay.test.ts +845 -0
  1123. package/src/worker/wal-replay.ts +897 -0
  1124. package/src/worker/wal-retention.test.ts +758 -0
  1125. package/src/worker/wal-retention.ts +1075 -0
  1126. package/src/worker/wal.test.ts +618 -0
  1127. package/src/worker/wal.ts +697 -0
  1128. package/src/worker/websocket.test.ts +296 -0
  1129. package/src/worker/websocket.ts +284 -0
@@ -0,0 +1,1618 @@
1
+ /**
2
+ * Data Lineage Tracker
3
+ * Task: postgres-zce - Data lineage tracking
4
+ *
5
+ * Tracks data origin and transformations across tables, integrating with WAL capture
6
+ * and Iceberg storage for complete lineage history.
7
+ */
8
+
9
+ import type { SerializedWALEntry } from '../worker/wal'
10
+ import type {
11
+ LineageNode,
12
+ LineageEdge,
13
+ LineageGraph,
14
+ LineageTrackerConfig,
15
+ LineageStats,
16
+ LineageQueryResult,
17
+ RowLineage,
18
+ LineageParseResult,
19
+ LineageVisualizationGraph,
20
+ LineageVisualizationNode,
21
+ LineageVisualizationEdge,
22
+ LineageJoinType,
23
+ LineageAggregateFunction,
24
+ JoinDependency,
25
+ AggregateDependency,
26
+ IcebergLineageMetadata,
27
+ LineageOperationType,
28
+ } from './types'
29
+ import { parseWriteOperation } from '../worker/wal'
30
+
31
+ /**
32
+ * Default lineage tracker configuration
33
+ */
34
+ const DEFAULT_CONFIG: Required<LineageTrackerConfig> = {
35
+ enabled: true,
36
+ trackColumns: true,
37
+ trackRows: false,
38
+ maxDepth: 10,
39
+ includeTables: [],
40
+ excludeTables: [],
41
+ operations: [],
42
+ storeInIceberg: true,
43
+ useSeparateCatalog: false,
44
+ }
45
+
46
+ /**
47
+ * Generate a unique node ID
48
+ */
49
+ function generateNodeId(schema: string, table: string): string {
50
+ return `${schema}.${table}`
51
+ }
52
+
53
+ /**
54
+ * Generate a unique edge ID
55
+ */
56
+ function generateEdgeId(sourceId: string, targetId: string, timestamp: number): string {
57
+ return `${sourceId}->${targetId}@${timestamp}`
58
+ }
59
+
60
+ /**
61
+ * Parse SQL to extract lineage information
62
+ */
63
+ export function parseLineage(sql: string): LineageParseResult | null {
64
+ // Normalize SQL
65
+ const normalized = sql.trim().replace(/\s+/g, ' ')
66
+ const upperSql = normalized.toUpperCase()
67
+
68
+ // Parse CTEs first (WITH clause) - extract source tables from CTEs
69
+ const ctes = extractCTEs(normalized)
70
+ const cteSourceTables = ctes.flatMap((cte) => cte.sourceTables)
71
+ const cteNames = new Set(ctes.map((cte) => cte.name))
72
+
73
+ // For CTEs, we need to get the SQL after the CTE definitions for main operation detection
74
+ const mainSql = stripCTEs(normalized)
75
+ const mainUpperSql = mainSql.toUpperCase()
76
+
77
+ // Parse INSERT INTO ... SELECT FROM
78
+ if (upperSql.includes('INSERT INTO') && upperSql.includes('SELECT')) {
79
+ const result = parseInsertSelect(normalized)
80
+ if (result) {
81
+ // Add CTE source tables
82
+ result.sourceTables = [...result.sourceTables, ...cteSourceTables]
83
+ // Add aggregations if present
84
+ result.aggregations = extractAggregations(normalized)
85
+ }
86
+ return result
87
+ }
88
+
89
+ // Parse UPDATE ... FROM
90
+ if (upperSql.includes('UPDATE') && upperSql.includes('FROM')) {
91
+ const result = parseUpdateFrom(normalized)
92
+ if (result) {
93
+ result.sourceTables = [...result.sourceTables, ...cteSourceTables]
94
+ }
95
+ return result
96
+ }
97
+
98
+ // Parse CREATE TABLE AS SELECT (CTAS)
99
+ if (upperSql.includes('CREATE TABLE') && upperSql.includes('AS') && upperSql.includes('SELECT')) {
100
+ return parseCreateTableAs(normalized)
101
+ }
102
+
103
+ // Parse DELETE with subqueries - must check before generic subquery handler
104
+ if (mainUpperSql.startsWith('DELETE')) {
105
+ const writeOp = parseWriteOperation(sql)
106
+ if (writeOp && writeOp.operation === 'DELETE') {
107
+ // Extract source tables from subqueries
108
+ const subqueries = extractSubqueries(normalized)
109
+ const subquerySourceTables = subqueries.flatMap((sq) => sq.sourceTables)
110
+ return {
111
+ operation: 'DELETE',
112
+ targetTable: {
113
+ schema: writeOp.schema,
114
+ table: writeOp.table,
115
+ },
116
+ sourceTables: [
117
+ {
118
+ schema: writeOp.schema,
119
+ table: writeOp.table,
120
+ },
121
+ ...subquerySourceTables,
122
+ ...cteSourceTables,
123
+ ],
124
+ }
125
+ }
126
+ }
127
+
128
+ // Parse SELECT with JOINs
129
+ if (upperSql.includes('SELECT') && upperSql.includes('JOIN')) {
130
+ const result = parseSelectJoin(normalized)
131
+ if (result) {
132
+ result.sourceTables = [...result.sourceTables, ...cteSourceTables]
133
+ result.aggregations = extractAggregations(normalized)
134
+ }
135
+ return result
136
+ }
137
+
138
+ // Parse SELECT with aggregations (GROUP BY)
139
+ if (upperSql.includes('SELECT') && (upperSql.includes('GROUP BY') || hasAggregateFunction(upperSql))) {
140
+ const result = parseSelectAggregate(normalized)
141
+ if (result) {
142
+ result.sourceTables = [...result.sourceTables, ...cteSourceTables]
143
+ }
144
+ return result
145
+ }
146
+
147
+ // Parse SELECT with subqueries - check if main statement (not in CTE) starts with SELECT
148
+ // For CTEs followed by SELECT, we should return SELECT not SUBQUERY
149
+ if (upperSql.includes('SELECT') && normalized.includes('(SELECT')) {
150
+ // If we have CTEs and main SQL starts with SELECT (e.g., WITH ... SELECT), preserve SELECT operation
151
+ // But only if the (SELECT is part of a CTE definition, not a subquery in WHERE/FROM
152
+ if (ctes.length > 0 && mainUpperSql.startsWith('SELECT') && !mainSql.includes('(SELECT')) {
153
+ const sourceTables = extractSourceTables(mainSql)
154
+ // Filter out CTE names from source tables
155
+ const filteredSourceTables = sourceTables.filter((t) => !cteNames.has(t.table.toLowerCase()))
156
+ return {
157
+ operation: 'SELECT',
158
+ sourceTables: [...filteredSourceTables, ...cteSourceTables],
159
+ }
160
+ }
161
+ const result = parseSelectSubquery(normalized)
162
+ if (result) {
163
+ result.sourceTables = [...result.sourceTables, ...cteSourceTables]
164
+ }
165
+ return result
166
+ }
167
+
168
+ // Parse simple SELECT (including CTEs followed by SELECT)
169
+ if (mainUpperSql.startsWith('SELECT') && mainUpperSql.includes('FROM')) {
170
+ const sourceTables = extractSourceTables(mainSql)
171
+ // Filter out CTE names from source tables
172
+ const filteredSourceTables = sourceTables.filter((t) => !cteNames.has(t.table.toLowerCase()))
173
+ if (filteredSourceTables.length > 0 || cteSourceTables.length > 0) {
174
+ return {
175
+ operation: 'SELECT',
176
+ sourceTables: [...filteredSourceTables, ...cteSourceTables],
177
+ }
178
+ }
179
+ }
180
+
181
+ // Parse simple INSERT - use local parsing for embedded quotes support
182
+ const simpleInsertResult = parseSimpleInsert(normalized)
183
+ if (simpleInsertResult) {
184
+ return {
185
+ ...simpleInsertResult,
186
+ sourceTables: [...simpleInsertResult.sourceTables, ...cteSourceTables],
187
+ }
188
+ }
189
+
190
+ // Parse simple UPDATE
191
+ const writeOp = parseWriteOperation(sql)
192
+ if (writeOp && writeOp.operation === 'UPDATE') {
193
+ return {
194
+ operation: 'UPDATE',
195
+ targetTable: {
196
+ schema: writeOp.schema,
197
+ table: writeOp.table,
198
+ },
199
+ sourceTables: [
200
+ {
201
+ schema: writeOp.schema,
202
+ table: writeOp.table,
203
+ },
204
+ ...cteSourceTables,
205
+ ],
206
+ }
207
+ }
208
+
209
+ // Parse simple DELETE
210
+ if (writeOp && writeOp.operation === 'DELETE') {
211
+ return {
212
+ operation: 'DELETE',
213
+ targetTable: {
214
+ schema: writeOp.schema,
215
+ table: writeOp.table,
216
+ },
217
+ sourceTables: [
218
+ {
219
+ schema: writeOp.schema,
220
+ table: writeOp.table,
221
+ },
222
+ ...cteSourceTables,
223
+ ],
224
+ }
225
+ }
226
+
227
+ return null
228
+ }
229
+
230
+ /**
231
+ * Strip CTE definitions from SQL to get the main statement
232
+ */
233
+ function stripCTEs(sql: string): string {
234
+ // Match WITH clause and all CTE definitions
235
+ const ctePattern = /^WITH\s+(?:RECURSIVE\s+)?(?:[a-z_][a-z0-9_]*\s+AS\s*\([^)]+\)\s*,?\s*)+/i
236
+ return sql.replace(ctePattern, '').trim()
237
+ }
238
+
239
+ /**
240
+ * Parse simple INSERT statement with embedded quote support
241
+ */
242
+ function parseSimpleInsert(sql: string): LineageParseResult | null {
243
+ // Match INSERT INTO with support for:
244
+ // - [catalog.][schema.]table (3-part or 2-part names)
245
+ // - "Table""Name" (embedded quotes)
246
+ const insertMatch = sql.match(/^INSERT\s+INTO\s+(?:([a-z_][a-z0-9_]*)\s*\.\s*)?(?:([a-z_][a-z0-9_]*)\s*\.\s*)?([a-z_][a-z0-9_]*|"(?:[^"]|"")+")(?:\s|$|\()/i)
247
+ if (!insertMatch) return null
248
+
249
+ // Handle 3-part names: catalog.schema.table vs 2-part: schema.table vs 1-part: table
250
+ let targetSchema: string
251
+ let targetTable: string
252
+ if (insertMatch[2]) {
253
+ // 3-part name: insertMatch[1] is catalog, [2] is schema, [3] is table
254
+ // Or 2-part: [1] is schema, [2] is extra (shouldn't happen with this regex)
255
+ targetSchema = insertMatch[2].toLowerCase()
256
+ targetTable = unquoteIdentifier(insertMatch[3]!)
257
+ } else if (insertMatch[1]) {
258
+ targetSchema = insertMatch[1].toLowerCase()
259
+ targetTable = unquoteIdentifier(insertMatch[3]!)
260
+ } else {
261
+ targetSchema = 'public'
262
+ targetTable = unquoteIdentifier(insertMatch[3]!)
263
+ }
264
+
265
+ return {
266
+ operation: 'INSERT',
267
+ targetTable: {
268
+ schema: targetSchema,
269
+ table: targetTable,
270
+ },
271
+ sourceTables: [],
272
+ }
273
+ }
274
+
275
+ /**
276
+ * Check if SQL contains aggregate functions
277
+ */
278
+ function hasAggregateFunction(upperSql: string): boolean {
279
+ const aggregateFunctions = ['COUNT(', 'SUM(', 'AVG(', 'MIN(', 'MAX(', 'ARRAY_AGG(', 'STRING_AGG(', 'JSON_AGG(', 'JSONB_AGG(']
280
+ return aggregateFunctions.some((fn) => upperSql.includes(fn))
281
+ }
282
+
283
+ /**
284
+ * Parse INSERT INTO ... SELECT FROM statement
285
+ */
286
+ function parseInsertSelect(sql: string): LineageParseResult | null {
287
+ const insertMatch = sql.match(/INSERT\s+INTO\s+(?:([a-z_][a-z0-9_]*)\s*\.\s*)?([a-z_][a-z0-9_]*|"[^"]+")/i)
288
+ if (!insertMatch) return null
289
+
290
+ const targetSchema = insertMatch[1]?.toLowerCase() ?? 'public'
291
+ const targetTable = unquoteIdentifier(insertMatch[2]!)
292
+
293
+ // Extract source tables from SELECT clause
294
+ const sourceTables = extractSourceTables(sql)
295
+
296
+ return {
297
+ operation: 'INSERT',
298
+ targetTable: {
299
+ schema: targetSchema,
300
+ table: targetTable,
301
+ },
302
+ sourceTables,
303
+ }
304
+ }
305
+
306
+ /**
307
+ * Parse UPDATE ... FROM statement
308
+ */
309
+ function parseUpdateFrom(sql: string): LineageParseResult | null {
310
+ const updateMatch = sql.match(/UPDATE\s+(?:([a-z_][a-z0-9_]*)\s*\.\s*)?([a-z_][a-z0-9_]*|"[^"]+")/i)
311
+ if (!updateMatch) return null
312
+
313
+ const targetSchema = updateMatch[1]?.toLowerCase() ?? 'public'
314
+ const targetTable = unquoteIdentifier(updateMatch[2]!)
315
+
316
+ // Extract source tables from FROM clause
317
+ const sourceTables = extractSourceTables(sql)
318
+
319
+ return {
320
+ operation: 'UPDATE',
321
+ targetTable: {
322
+ schema: targetSchema,
323
+ table: targetTable,
324
+ },
325
+ sourceTables,
326
+ }
327
+ }
328
+
329
+ /**
330
+ * Parse SELECT with JOIN
331
+ */
332
+ function parseSelectJoin(sql: string): LineageParseResult | null {
333
+ // Extract source tables
334
+ const sourceTables = extractSourceTables(sql)
335
+
336
+ // Extract JOIN dependencies
337
+ const joins = extractJoins(sql)
338
+
339
+ // Extract WHERE filter
340
+ const whereFilter = extractWhereFilter(sql)
341
+
342
+ return {
343
+ operation: 'SELECT',
344
+ sourceTables,
345
+ joins,
346
+ whereFilter,
347
+ }
348
+ }
349
+
350
+ /**
351
+ * Parse CREATE TABLE AS SELECT (CTAS)
352
+ */
353
+ function parseCreateTableAs(sql: string): LineageParseResult | null {
354
+ // Match CREATE TABLE [schema.]table AS SELECT
355
+ const createMatch = sql.match(/CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?(?:([a-z_][a-z0-9_]*)\s*\.\s*)?([a-z_][a-z0-9_]*|"[^"]+")\s+AS\s+SELECT/i)
356
+ if (!createMatch) return null
357
+
358
+ const targetSchema = createMatch[1]?.toLowerCase() ?? 'public'
359
+ const targetTable = unquoteIdentifier(createMatch[2]!)
360
+
361
+ // Extract source tables from the SELECT part
362
+ const sourceTables = extractSourceTables(sql)
363
+
364
+ // Extract joins if present
365
+ const joins = extractJoins(sql)
366
+
367
+ // Extract aggregations if present
368
+ const aggregations = extractAggregations(sql)
369
+
370
+ return {
371
+ operation: 'INSERT', // CTAS is effectively an INSERT
372
+ targetTable: {
373
+ schema: targetSchema,
374
+ table: targetTable,
375
+ },
376
+ sourceTables,
377
+ joins: joins.length > 0 ? joins : undefined,
378
+ aggregations: aggregations.length > 0 ? aggregations : undefined,
379
+ }
380
+ }
381
+
382
+ /**
383
+ * Parse SELECT with aggregations
384
+ */
385
+ function parseSelectAggregate(sql: string): LineageParseResult | null {
386
+ // Extract source tables
387
+ const sourceTables = extractSourceTables(sql)
388
+
389
+ // Extract aggregations
390
+ const aggregations = extractAggregations(sql)
391
+
392
+ // Extract WHERE filter
393
+ const whereFilter = extractWhereFilter(sql)
394
+
395
+ return {
396
+ operation: 'AGGREGATE',
397
+ sourceTables,
398
+ aggregations: aggregations.length > 0 ? aggregations : undefined,
399
+ whereFilter,
400
+ }
401
+ }
402
+
403
+ /**
404
+ * Parse SELECT with subqueries
405
+ */
406
+ function parseSelectSubquery(sql: string): LineageParseResult | null {
407
+ // Extract main source tables
408
+ const sourceTables = extractSourceTables(sql)
409
+
410
+ // Extract subqueries and their source tables
411
+ const subqueries = extractSubqueries(sql)
412
+ const subquerySourceTables = subqueries.flatMap((sq) => sq.sourceTables)
413
+
414
+ // Combine all source tables (deduplicated)
415
+ const allSourceTables = [...sourceTables]
416
+ const seen = new Set(sourceTables.map((t) => `${t.schema}.${t.table}`))
417
+
418
+ for (const st of subquerySourceTables) {
419
+ const key = `${st.schema}.${st.table}`
420
+ if (!seen.has(key)) {
421
+ seen.add(key)
422
+ allSourceTables.push(st)
423
+ }
424
+ }
425
+
426
+ return {
427
+ operation: 'SUBQUERY',
428
+ sourceTables: allSourceTables,
429
+ }
430
+ }
431
+
432
+ /**
433
+ * Extract WHERE filter from SQL
434
+ */
435
+ function extractWhereFilter(sql: string): string | undefined {
436
+ const whereMatch = sql.match(/WHERE\s+([^;]+?)(?:\s+GROUP|\s+ORDER|\s+LIMIT|\s+HAVING|\s*$|\s*;)/i)
437
+ if (whereMatch) {
438
+ return whereMatch[1]!.trim()
439
+ }
440
+ return undefined
441
+ }
442
+
443
+ /**
444
+ * Extract source tables from SQL
445
+ */
446
+ function extractSourceTables(sql: string): { schema: string; table: string; alias?: string }[] {
447
+ const tables: { schema: string; table: string; alias?: string }[] = []
448
+ const seen = new Set<string>()
449
+
450
+ // Match FROM clause - capture everything until WHERE, GROUP, ORDER, LIMIT, JOIN, UNION, INTERSECT, EXCEPT, or end
451
+ // Use a non-greedy match and explicitly handle the end case
452
+ // Updated regex to allow dots in table names (for schema.table)
453
+ const fromMatch = sql.match(/FROM\s+((?:[a-z_][a-z0-9_.]*(?:\s+(?:AS\s+)?[a-z_][a-z0-9_]*)?(?:\s*,\s*)?)+)(?:\s+WHERE|\s+GROUP|\s+ORDER|\s+LIMIT|\s+(?:INNER|LEFT|RIGHT|FULL|CROSS)?\s*JOIN|\s+UNION|\s+INTERSECT|\s+EXCEPT|\s*$|\s*;)/i)
454
+ if (fromMatch) {
455
+ const fromClause = fromMatch[1]
456
+ if (!fromClause) return tables
457
+ // Match schema.table or just table, with optional alias
458
+ const tablePattern = /(?:([a-z_][a-z0-9_]*)\s*\.\s*)?([a-z_][a-z0-9_]*|"[^"]+")(?:\s+(?:AS\s+)?([a-z_][a-z0-9_]*))?/gi
459
+ const tableMatches = fromClause.matchAll(tablePattern)
460
+
461
+ for (const match of tableMatches) {
462
+ const schema = match[1]?.toLowerCase() ?? 'public'
463
+ const table = unquoteIdentifier(match[2]!)
464
+ const alias = match[3]?.toLowerCase()
465
+ const key = `${schema}.${table}`
466
+
467
+ if (!seen.has(key)) {
468
+ seen.add(key)
469
+ tables.push({ schema, table, ...(alias !== undefined && { alias }) })
470
+ }
471
+ }
472
+ }
473
+
474
+ // Match JOIN clauses - extract all JOINed tables
475
+ const joinPattern = /(?:INNER|LEFT|RIGHT|FULL|CROSS)?\s*JOIN\s+(?:([a-z_][a-z0-9_]*)\s*\.\s*)?([a-z_][a-z0-9_]*|"[^"]+")(?:\s+(?:AS\s+)?([a-z_][a-z0-9_]*))?/gi
476
+ const joinMatches = sql.matchAll(joinPattern)
477
+
478
+ for (const match of joinMatches) {
479
+ const schema = match[1]?.toLowerCase() ?? 'public'
480
+ const table = unquoteIdentifier(match[2]!)
481
+ const alias = match[3]?.toLowerCase()
482
+ const key = `${schema}.${table}`
483
+
484
+ if (!seen.has(key)) {
485
+ seen.add(key)
486
+ tables.push({ schema, table, ...(alias !== undefined && { alias }) })
487
+ }
488
+ }
489
+
490
+ // Match UNION/INTERSECT/EXCEPT source tables - find nested SELECTs
491
+ const unionPattern = /(?:UNION|INTERSECT|EXCEPT)(?:\s+ALL)?\s+SELECT\s+.*?\s+FROM\s+(?:([a-z_][a-z0-9_]*)\s*\.\s*)?([a-z_][a-z0-9_]*|"[^"]+")/gi
492
+ const unionMatches = sql.matchAll(unionPattern)
493
+
494
+ for (const match of unionMatches) {
495
+ const schema = match[1]?.toLowerCase() ?? 'public'
496
+ const table = unquoteIdentifier(match[2]!)
497
+ const key = `${schema}.${table}`
498
+
499
+ if (!seen.has(key)) {
500
+ seen.add(key)
501
+ tables.push({ schema, table })
502
+ }
503
+ }
504
+
505
+ return tables
506
+ }
507
+
508
+ /**
509
+ * Extract JOIN dependencies from SQL with proper left table tracking
510
+ */
511
+ function extractJoins(sql: string): JoinDependency[] {
512
+ const joins: JoinDependency[] = []
513
+ const tables = extractSourceTables(sql)
514
+
515
+ // Extract the primary table from the FROM clause (first table)
516
+ let currentLeftTable = tables[0] ?? { schema: 'public', table: 'unknown' }
517
+
518
+ // Enhanced JOIN pattern with ON clause capture
519
+ const joinPattern = /(INNER|LEFT|RIGHT|FULL|CROSS)?\s*JOIN\s+(?:([a-z_][a-z0-9_]*)\s*\.\s*)?([a-z_][a-z0-9_]*|"[^"]+")(?:\s+(?:AS\s+)?([a-z_][a-z0-9_]*))?\s+ON\s+([^;]+?)(?=\s+(?:INNER|LEFT|RIGHT|FULL|CROSS)?\s*JOIN|\s+WHERE|\s+GROUP|\s+ORDER|\s+LIMIT|\s*$|\s*;)/gi
520
+
521
+ const matches = sql.matchAll(joinPattern)
522
+ for (const match of matches) {
523
+ const joinType = (match[1]?.toUpperCase() || 'INNER') as LineageJoinType
524
+ const schema = match[2]?.toLowerCase() ?? 'public'
525
+ const table = unquoteIdentifier(match[3]!)
526
+ const alias = match[4]?.toLowerCase()
527
+ const onClause = match[5]!
528
+
529
+ // Parse join columns from ON clause
530
+ const joinColumns = extractJoinColumns(onClause, currentLeftTable, { schema, table, ...(alias !== undefined && { alias }) })
531
+
532
+ joins.push({
533
+ joinType,
534
+ leftTable: { schema: currentLeftTable.schema, table: currentLeftTable.table },
535
+ rightTable: { schema, table },
536
+ joinColumns,
537
+ timestamp: Date.now(),
538
+ })
539
+
540
+ // Update current left table for chained joins
541
+ currentLeftTable = { schema, table, ...(alias !== undefined && { alias }) }
542
+ }
543
+
544
+ // If no ON clause detected, try simpler pattern
545
+ if (joins.length === 0) {
546
+ const simpleJoinPattern = /(INNER|LEFT|RIGHT|FULL|CROSS)?\s*JOIN\s+(?:([a-z_][a-z0-9_]*)\s*\.\s*)?([a-z_][a-z0-9_]*|"[^"]+")/gi
547
+ const simpleMatches = sql.matchAll(simpleJoinPattern)
548
+
549
+ for (const match of simpleMatches) {
550
+ const joinType = (match[1]?.toUpperCase() || 'INNER') as LineageJoinType
551
+ const schema = match[2]?.toLowerCase() ?? 'public'
552
+ const table = unquoteIdentifier(match[3]!)
553
+
554
+ joins.push({
555
+ joinType,
556
+ leftTable: { schema: currentLeftTable.schema, table: currentLeftTable.table },
557
+ rightTable: { schema, table },
558
+ joinColumns: [],
559
+ timestamp: Date.now(),
560
+ })
561
+
562
+ currentLeftTable = { schema, table }
563
+ }
564
+ }
565
+
566
+ return joins
567
+ }
568
+
569
+ /**
570
+ * Extract join columns from ON clause
571
+ */
572
+ function extractJoinColumns(
573
+ onClause: string,
574
+ leftTable: { schema: string; table: string; alias?: string },
575
+ rightTable: { schema: string; table: string; alias?: string }
576
+ ): { left: string; right: string }[] {
577
+ const columns: { left: string; right: string }[] = []
578
+
579
+ // Pattern to match column comparisons: table.column = table.column
580
+ const comparisonPattern = /([a-z_][a-z0-9_]*(?:\.[a-z_][a-z0-9_]*)?)\s*=\s*([a-z_][a-z0-9_]*(?:\.[a-z_][a-z0-9_]*)?)/gi
581
+ const matches = onClause.matchAll(comparisonPattern)
582
+
583
+ const leftNames = [leftTable.table, leftTable.alias].filter(Boolean) as string[]
584
+ const rightNames = [rightTable.table, rightTable.alias].filter(Boolean) as string[]
585
+
586
+ for (const match of matches) {
587
+ const col1 = match[1]!.toLowerCase()
588
+ const col2 = match[2]!.toLowerCase()
589
+
590
+ // Determine which column belongs to which table
591
+ const col1Parts = col1.split('.')
592
+ const col2Parts = col2.split('.')
593
+
594
+ let leftCol: string | undefined
595
+ let rightCol: string | undefined
596
+
597
+ // Check if col1 belongs to left or right table
598
+ if (col1Parts.length === 2) {
599
+ if (leftNames.includes(col1Parts[0]!)) {
600
+ leftCol = col1Parts[1]!
601
+ } else if (rightNames.includes(col1Parts[0]!)) {
602
+ rightCol = col1Parts[1]!
603
+ }
604
+ }
605
+
606
+ if (col2Parts.length === 2) {
607
+ if (leftNames.includes(col2Parts[0]!)) {
608
+ leftCol = leftCol || col2Parts[1]!
609
+ } else if (rightNames.includes(col2Parts[0]!)) {
610
+ rightCol = rightCol || col2Parts[1]!
611
+ }
612
+ }
613
+
614
+ // If both columns identified, add to result
615
+ if (leftCol && rightCol) {
616
+ columns.push({ left: leftCol, right: rightCol })
617
+ } else if (col1Parts.length === 1 && col2Parts.length === 1) {
618
+ // Unqualified columns - assume same column name on both sides
619
+ columns.push({ left: col1Parts[0]!, right: col2Parts[0]! })
620
+ }
621
+ }
622
+
623
+ return columns
624
+ }
625
+
626
+ /**
627
+ * Extract aggregations from SQL
628
+ */
629
+ function extractAggregations(sql: string): AggregateDependency[] {
630
+ const aggregations: AggregateDependency[] = []
631
+ const upperSql = sql.toUpperCase()
632
+
633
+ // Check if this is an aggregation query
634
+ const aggregateFunctions = ['COUNT', 'SUM', 'AVG', 'MIN', 'MAX', 'ARRAY_AGG', 'STRING_AGG', 'JSON_AGG', 'JSONB_AGG']
635
+ const hasAggregation = aggregateFunctions.some((fn) => upperSql.includes(fn + '('))
636
+
637
+ if (!hasAggregation) {
638
+ return aggregations
639
+ }
640
+
641
+ // Extract source tables
642
+ const sourceTables = extractSourceTables(sql)
643
+ if (sourceTables.length === 0) {
644
+ return aggregations
645
+ }
646
+
647
+ // Extract aggregate columns
648
+ const aggregatedColumns: { column: string; function: LineageAggregateFunction; alias?: string }[] = []
649
+
650
+ for (const fn of aggregateFunctions) {
651
+ // Match aggregation function calls: FUNC(column) AS alias or FUNC(column)
652
+ const fnPattern = new RegExp(
653
+ `${fn}\\s*\\(\\s*(?:DISTINCT\\s+)?([a-z_][a-z0-9_]*(?:\\.[a-z_][a-z0-9_]*)?|\\*)\\s*\\)(?:\\s+AS\\s+([a-z_][a-z0-9_]*))?`,
654
+ 'gi'
655
+ )
656
+ const matches = sql.matchAll(fnPattern)
657
+
658
+ for (const match of matches) {
659
+ const column = match[1]!.toLowerCase()
660
+ const alias = match[2]?.toLowerCase()
661
+
662
+ aggregatedColumns.push({
663
+ column,
664
+ function: fn as LineageAggregateFunction,
665
+ ...(alias !== undefined && { alias }),
666
+ })
667
+ }
668
+ }
669
+
670
+ // Extract GROUP BY columns
671
+ const groupByColumns: string[] = []
672
+ const groupByMatch = sql.match(/GROUP\s+BY\s+([^;]+?)(?:\s+HAVING|\s+ORDER|\s+LIMIT|\s*$|\s*;)/i)
673
+ if (groupByMatch) {
674
+ const groupByClause = groupByMatch[1]!
675
+ // Split by comma and extract column names
676
+ const cols = groupByClause.split(',').map((c) => c.trim().toLowerCase())
677
+ groupByColumns.push(...cols)
678
+ }
679
+
680
+ // Extract HAVING filter
681
+ let havingFilter: string | undefined
682
+ const havingMatch = sql.match(/HAVING\s+([^;]+?)(?:\s+ORDER|\s+LIMIT|\s*$|\s*;)/i)
683
+ if (havingMatch) {
684
+ havingFilter = havingMatch[1]!.trim()
685
+ }
686
+
687
+ // Create aggregation dependency for each source table
688
+ for (const sourceTable of sourceTables) {
689
+ aggregations.push({
690
+ sourceTable: {
691
+ schema: sourceTable.schema,
692
+ table: sourceTable.table,
693
+ },
694
+ aggregatedColumns,
695
+ groupByColumns,
696
+ havingFilter,
697
+ timestamp: Date.now(),
698
+ })
699
+ }
700
+
701
+ return aggregations
702
+ }
703
+
704
+ /**
705
+ * Extract CTEs (Common Table Expressions) from SQL
706
+ */
707
+ function extractCTEs(sql: string): { name: string; sourceTables: { schema: string; table: string }[] }[] {
708
+ const ctes: { name: string; sourceTables: { schema: string; table: string }[] }[] = []
709
+
710
+ // Match WITH clause CTEs
711
+ const ctePattern = /WITH\s+(?:RECURSIVE\s+)?([a-z_][a-z0-9_]*)\s+AS\s*\(\s*(SELECT[^)]+)\)/gi
712
+ const matches = sql.matchAll(ctePattern)
713
+
714
+ for (const match of matches) {
715
+ const cteName = match[1]!.toLowerCase()
716
+ const cteQuery = match[2]!
717
+
718
+ // Extract source tables from CTE query
719
+ const sourceTables = extractSourceTables(cteQuery)
720
+
721
+ ctes.push({
722
+ name: cteName,
723
+ sourceTables,
724
+ })
725
+ }
726
+
727
+ return ctes
728
+ }
729
+
730
+ /**
731
+ * Extract subqueries from SQL
732
+ */
733
+ function extractSubqueries(sql: string): { sourceTables: { schema: string; table: string }[]; alias?: string }[] {
734
+ const subqueries: { sourceTables: { schema: string; table: string }[]; alias?: string }[] = []
735
+
736
+ // Match subqueries in FROM clause: (SELECT ...) AS alias
737
+ const subqueryPattern = /\(\s*(SELECT[^)]+)\s*\)\s*(?:AS\s+)?([a-z_][a-z0-9_]*)?/gi
738
+ const matches = sql.matchAll(subqueryPattern)
739
+
740
+ for (const match of matches) {
741
+ const subquery = match[1]!
742
+ const alias = match[2]?.toLowerCase()
743
+
744
+ // Extract source tables from subquery
745
+ const sourceTables = extractSourceTables(subquery)
746
+
747
+ if (sourceTables.length > 0) {
748
+ subqueries.push({
749
+ sourceTables,
750
+ ...(alias !== undefined && { alias }),
751
+ })
752
+ }
753
+ }
754
+
755
+ return subqueries
756
+ }
757
+
758
+ /**
759
+ * Remove quotes from an identifier
760
+ */
761
+ function unquoteIdentifier(identifier: string): string {
762
+ if (identifier.startsWith('"') && identifier.endsWith('"')) {
763
+ return identifier.slice(1, -1).replace(/""/g, '"')
764
+ }
765
+ return identifier.toLowerCase()
766
+ }
767
+
768
+ /**
769
+ * Data Lineage Tracker
770
+ *
771
+ * Tracks data flow between tables, records transformations,
772
+ * and provides lineage queries for any row.
773
+ */
774
+ export class LineageTracker {
775
+ private config: Required<LineageTrackerConfig>
776
+ private graph: LineageGraph
777
+ private rowLineageMap: Map<string, RowLineage[]> = new Map()
778
+
779
+ constructor(config: LineageTrackerConfig = {}) {
780
+ this.config = { ...DEFAULT_CONFIG, ...config }
781
+ this.graph = {
782
+ nodes: new Map(),
783
+ edges: new Map(),
784
+ sourceIndex: new Map(),
785
+ targetIndex: new Map(),
786
+ }
787
+ }
788
+
789
+ /**
790
+ * Get current configuration
791
+ */
792
+ getConfig(): Required<LineageTrackerConfig> {
793
+ return { ...this.config }
794
+ }
795
+
796
+ /**
797
+ * Update configuration
798
+ */
799
+ setConfig(config: Partial<LineageTrackerConfig>): void {
800
+ this.config = { ...this.config, ...config }
801
+ }
802
+
803
+ /**
804
+ * Check if lineage tracking is enabled
805
+ */
806
+ isEnabled(): boolean {
807
+ return this.config.enabled
808
+ }
809
+
810
+ /**
811
+ * Enable or disable lineage tracking
812
+ */
813
+ setEnabled(enabled: boolean): void {
814
+ this.config.enabled = enabled
815
+ }
816
+
817
+ /**
818
+ * Track a WAL entry for lineage
819
+ */
820
+ trackWALEntry(entry: SerializedWALEntry): void {
821
+ if (!this.config.enabled) return
822
+
823
+ // Check table filters
824
+ if (this.config.includeTables.length > 0 && !this.config.includeTables.includes(entry.table)) {
825
+ return
826
+ }
827
+ if (this.config.excludeTables.includes(entry.table)) {
828
+ return
829
+ }
830
+
831
+ // Ensure target node exists
832
+ this.ensureNode(entry.schema, entry.table, 'table')
833
+
834
+ // Parse SQL for lineage if available
835
+ if (entry.sql) {
836
+ const lineage = parseLineage(entry.sql)
837
+ if (lineage) {
838
+ this.trackLineage(lineage, entry)
839
+ }
840
+ }
841
+
842
+ // Track row-level lineage if enabled
843
+ if (this.config.trackRows && entry.primaryKey) {
844
+ this.trackRowLineage(entry)
845
+ }
846
+ }
847
+
848
+ /**
849
+ * Track lineage from parsed SQL
850
+ */
851
+ private trackLineage(lineage: LineageParseResult, entry: SerializedWALEntry): void {
852
+ if (!lineage.targetTable) return
853
+
854
+ const targetNodeId = generateNodeId(lineage.targetTable.schema, lineage.targetTable.table)
855
+
856
+ // Track source tables
857
+ for (const source of lineage.sourceTables) {
858
+ const sourceNodeId = generateNodeId(source.schema, source.table)
859
+
860
+ // Ensure source node exists
861
+ this.ensureNode(source.schema, source.table, 'table')
862
+
863
+ // Create edge
864
+ this.addEdge({
865
+ id: generateEdgeId(sourceNodeId, targetNodeId, Date.now()),
866
+ sourceId: sourceNodeId,
867
+ targetId: targetNodeId,
868
+ operation: lineage.operation,
869
+ timestamp: entry.timestamp,
870
+ lsn: entry.lsn,
871
+ transactionId: entry.transactionId,
872
+ sql: entry.sql,
873
+ joinDependency: lineage.joins?.[0],
874
+ aggregateDependency: lineage.aggregations?.[0],
875
+ })
876
+ }
877
+ }
878
+
879
+ /**
880
+ * Track row-level lineage
881
+ */
882
+ private trackRowLineage(entry: SerializedWALEntry): void {
883
+ if (!entry.primaryKey) return
884
+
885
+ const rowKey = this.getRowKey(entry.schema, entry.table, entry.primaryKey)
886
+
887
+ const rowLineage: RowLineage = {
888
+ targetTable: {
889
+ schema: entry.schema,
890
+ table: entry.table,
891
+ },
892
+ targetPrimaryKey: entry.primaryKey,
893
+ sourceRows: [],
894
+ operation: entry.operation as LineageOperationType,
895
+ timestamp: entry.timestamp,
896
+ lsn: entry.lsn,
897
+ transactionId: entry.transactionId,
898
+ }
899
+
900
+ // For UPDATE operations, track the old row as source
901
+ if (entry.operation === 'UPDATE' && entry.oldRow) {
902
+ rowLineage.sourceRows.push({
903
+ table: {
904
+ schema: entry.schema,
905
+ table: entry.table,
906
+ },
907
+ primaryKey: entry.primaryKey,
908
+ contributionType: 'direct',
909
+ })
910
+ }
911
+
912
+ // Store row lineage
913
+ if (!this.rowLineageMap.has(rowKey)) {
914
+ this.rowLineageMap.set(rowKey, [])
915
+ }
916
+ this.rowLineageMap.get(rowKey)!.push(rowLineage)
917
+ }
918
+
919
+ /**
920
+ * Get row key for lineage map
921
+ */
922
+ private getRowKey(schema: string, table: string, primaryKey: Record<string, unknown>): string {
923
+ return `${schema}.${table}:${JSON.stringify(primaryKey)}`
924
+ }
925
+
926
+ /**
927
+ * Ensure a node exists in the graph
928
+ */
929
+ private ensureNode(schema: string, table: string, type: LineageNode['type']): void {
930
+ const nodeId = generateNodeId(schema, table)
931
+
932
+ if (!this.graph.nodes.has(nodeId)) {
933
+ const now = Date.now()
934
+ this.graph.nodes.set(nodeId, {
935
+ id: nodeId,
936
+ type,
937
+ schema,
938
+ name: table,
939
+ createdAt: now,
940
+ updatedAt: now,
941
+ })
942
+ } else {
943
+ // Update timestamp
944
+ const node = this.graph.nodes.get(nodeId)!
945
+ node.updatedAt = Date.now()
946
+ }
947
+ }
948
+
949
+ /**
950
+ * Add an edge to the graph
951
+ */
952
+ private addEdge(edge: LineageEdge): void {
953
+ // Add edge
954
+ this.graph.edges.set(edge.id, edge)
955
+
956
+ // Update source index
957
+ if (!this.graph.sourceIndex.has(edge.sourceId)) {
958
+ this.graph.sourceIndex.set(edge.sourceId, new Set())
959
+ }
960
+ this.graph.sourceIndex.get(edge.sourceId)!.add(edge.id)
961
+
962
+ // Update target index
963
+ if (!this.graph.targetIndex.has(edge.targetId)) {
964
+ this.graph.targetIndex.set(edge.targetId, new Set())
965
+ }
966
+ this.graph.targetIndex.get(edge.targetId)!.add(edge.id)
967
+ }
968
+
969
+ /**
970
+ * Get lineage for a specific table
971
+ */
972
+ getTableLineage(schema: string, table: string): {
973
+ upstreamTables: string[]
974
+ downstreamTables: string[]
975
+ edges: LineageEdge[]
976
+ } {
977
+ const nodeId = generateNodeId(schema, table)
978
+
979
+ // Get upstream (sources)
980
+ const upstreamEdgeIds = this.graph.targetIndex.get(nodeId) || new Set()
981
+ const upstreamTables = new Set<string>()
982
+ const edges: LineageEdge[] = []
983
+
984
+ for (const edgeId of upstreamEdgeIds) {
985
+ const edge = this.graph.edges.get(edgeId)
986
+ if (edge) {
987
+ upstreamTables.add(edge.sourceId)
988
+ edges.push(edge)
989
+ }
990
+ }
991
+
992
+ // Get downstream (targets)
993
+ const downstreamEdgeIds = this.graph.sourceIndex.get(nodeId) || new Set()
994
+ const downstreamTables = new Set<string>()
995
+
996
+ for (const edgeId of downstreamEdgeIds) {
997
+ const edge = this.graph.edges.get(edgeId)
998
+ if (edge) {
999
+ downstreamTables.add(edge.targetId)
1000
+ edges.push(edge)
1001
+ }
1002
+ }
1003
+
1004
+ return {
1005
+ upstreamTables: Array.from(upstreamTables),
1006
+ downstreamTables: Array.from(downstreamTables),
1007
+ edges,
1008
+ }
1009
+ }
1010
+
1011
+ /**
1012
+ * Query lineage for a specific row
1013
+ */
1014
+ queryRowLineage(
1015
+ schema: string,
1016
+ table: string,
1017
+ primaryKey: Record<string, unknown>
1018
+ ): LineageQueryResult | null {
1019
+ if (!this.config.trackRows) {
1020
+ throw new Error('Row-level lineage tracking is not enabled')
1021
+ }
1022
+
1023
+ const rowKey = this.getRowKey(schema, table, primaryKey)
1024
+ const lineagePath = this.rowLineageMap.get(rowKey)
1025
+
1026
+ if (!lineagePath) {
1027
+ return null
1028
+ }
1029
+
1030
+ // Calculate depth and source tables
1031
+ const depth = lineagePath.length
1032
+ const sourceTables = new Set<string>()
1033
+
1034
+ for (const lineage of lineagePath) {
1035
+ for (const source of lineage.sourceRows) {
1036
+ sourceTables.add(`${source.table.schema}.${source.table.table}`)
1037
+ }
1038
+ }
1039
+
1040
+ return {
1041
+ row: {
1042
+ schema,
1043
+ table,
1044
+ primaryKey,
1045
+ },
1046
+ lineagePath,
1047
+ depth,
1048
+ sourceTables: Array.from(sourceTables)
1049
+ .map((id) => {
1050
+ const [schema, table] = id.split('.')
1051
+ return schema && table ? { schema, table } : null
1052
+ })
1053
+ .filter((t): t is { schema: string; table: string } => t !== null),
1054
+ }
1055
+ }
1056
+
1057
+ /**
1058
+ * Visualize lineage graph for a table
1059
+ */
1060
+ visualizeLineage(schema: string, table: string, maxDepth?: number): LineageVisualizationGraph {
1061
+ // Use provided maxDepth, or fallback to config. When maxDepth is explicitly 0, use 0.
1062
+ const depth = maxDepth !== undefined ? maxDepth : this.config.maxDepth
1063
+ const nodeId = generateNodeId(schema, table)
1064
+
1065
+ const visitedNodes = new Set<string>()
1066
+ const visitedEdges = new Set<string>()
1067
+ const nodes: LineageVisualizationNode[] = []
1068
+ const edges: LineageVisualizationEdge[] = []
1069
+ const rootNodes = new Set<string>()
1070
+ const leafNodes = new Set<string>()
1071
+
1072
+ // Get the starting node
1073
+ const startingNode = this.graph.nodes.get(nodeId)
1074
+ if (!startingNode) {
1075
+ return {
1076
+ nodes: [],
1077
+ edges: [],
1078
+ maxDepth: 0,
1079
+ rootNodes: [],
1080
+ leafNodes: [],
1081
+ }
1082
+ }
1083
+
1084
+ // Add starting node
1085
+ nodes.push({
1086
+ id: startingNode.id,
1087
+ label: startingNode.name,
1088
+ type: startingNode.type,
1089
+ schema: startingNode.schema,
1090
+ table: startingNode.name,
1091
+ level: 0,
1092
+ })
1093
+
1094
+ // If maxDepth is 0, only return the starting node
1095
+ if (depth === 0) {
1096
+ // Check if starting node is root or leaf
1097
+ const hasUpstream = (this.graph.targetIndex.get(nodeId)?.size || 0) > 0
1098
+ const hasDownstream = (this.graph.sourceIndex.get(nodeId)?.size || 0) > 0
1099
+ if (!hasUpstream) rootNodes.add(nodeId)
1100
+ if (!hasDownstream) leafNodes.add(nodeId)
1101
+
1102
+ return {
1103
+ nodes,
1104
+ edges: [],
1105
+ maxDepth: 0,
1106
+ rootNodes: Array.from(rootNodes),
1107
+ leafNodes: Array.from(leafNodes),
1108
+ }
1109
+ }
1110
+
1111
+ // BFS traversal
1112
+ const queue: { nodeId: string; level: number; direction: 'up' | 'down' }[] = [
1113
+ { nodeId, level: 0, direction: 'up' },
1114
+ { nodeId, level: 0, direction: 'down' },
1115
+ ]
1116
+
1117
+ while (queue.length > 0) {
1118
+ const { nodeId: currentId, level, direction } = queue.shift()!
1119
+
1120
+ if (level >= depth) continue
1121
+ if (visitedNodes.has(`${currentId}:${direction}`)) continue
1122
+
1123
+ visitedNodes.add(`${currentId}:${direction}`)
1124
+
1125
+ const node = this.graph.nodes.get(currentId)
1126
+ if (!node) continue
1127
+
1128
+ // Add node to visualization (skip if already added as starting node)
1129
+ if (!nodes.find((n) => n.id === currentId)) {
1130
+ nodes.push({
1131
+ id: node.id,
1132
+ label: node.name,
1133
+ type: node.type,
1134
+ schema: node.schema,
1135
+ table: node.name,
1136
+ level,
1137
+ })
1138
+ }
1139
+
1140
+ // Traverse edges
1141
+ if (direction === 'up') {
1142
+ // Upstream (sources)
1143
+ const edgeIds = this.graph.targetIndex.get(currentId) || new Set()
1144
+
1145
+ if (edgeIds.size === 0) {
1146
+ rootNodes.add(currentId)
1147
+ }
1148
+
1149
+ for (const edgeId of edgeIds) {
1150
+ if (visitedEdges.has(edgeId)) continue
1151
+ visitedEdges.add(edgeId)
1152
+
1153
+ const edge = this.graph.edges.get(edgeId)
1154
+ if (!edge) continue
1155
+
1156
+ edges.push({
1157
+ id: edge.id,
1158
+ source: edge.sourceId,
1159
+ target: edge.targetId,
1160
+ operation: edge.operation,
1161
+ label: edge.operation,
1162
+ })
1163
+
1164
+ queue.push({ nodeId: edge.sourceId, level: level + 1, direction: 'up' })
1165
+ }
1166
+ } else {
1167
+ // Downstream (targets)
1168
+ const edgeIds = this.graph.sourceIndex.get(currentId) || new Set()
1169
+
1170
+ if (edgeIds.size === 0) {
1171
+ leafNodes.add(currentId)
1172
+ }
1173
+
1174
+ for (const edgeId of edgeIds) {
1175
+ if (visitedEdges.has(edgeId)) continue
1176
+ visitedEdges.add(edgeId)
1177
+
1178
+ const edge = this.graph.edges.get(edgeId)
1179
+ if (!edge) continue
1180
+
1181
+ edges.push({
1182
+ id: edge.id,
1183
+ source: edge.sourceId,
1184
+ target: edge.targetId,
1185
+ operation: edge.operation,
1186
+ label: edge.operation,
1187
+ })
1188
+
1189
+ queue.push({ nodeId: edge.targetId, level: level + 1, direction: 'down' })
1190
+ }
1191
+ }
1192
+ }
1193
+
1194
+ return {
1195
+ nodes,
1196
+ edges,
1197
+ maxDepth: nodes.length > 0 ? Math.max(...nodes.map((n) => n.level)) : 0,
1198
+ rootNodes: Array.from(rootNodes),
1199
+ leafNodes: Array.from(leafNodes),
1200
+ }
1201
+ }
1202
+
1203
+ /**
1204
+ * Get statistics about tracked lineage
1205
+ */
1206
+ getStats(): LineageStats {
1207
+ let totalDepth = 0
1208
+ let depthCount = 0
1209
+
1210
+ // Calculate average depth by sampling nodes
1211
+ for (const [nodeId] of this.graph.nodes) {
1212
+ const depth = this.calculateNodeDepth(nodeId)
1213
+ totalDepth += depth
1214
+ depthCount++
1215
+ }
1216
+
1217
+ // Estimate memory usage
1218
+ const graphSize =
1219
+ JSON.stringify(Array.from(this.graph.nodes.values())).length +
1220
+ JSON.stringify(Array.from(this.graph.edges.values())).length
1221
+ const rowLineageSize = JSON.stringify(Array.from(this.rowLineageMap.values())).length
1222
+
1223
+ return {
1224
+ totalNodes: this.graph.nodes.size,
1225
+ totalEdges: this.graph.edges.size,
1226
+ trackedTables: this.graph.nodes.size,
1227
+ transformationCount: Array.from(this.graph.edges.values()).filter(
1228
+ (e) => e.operation === 'JOIN' || e.operation === 'AGGREGATE'
1229
+ ).length,
1230
+ avgGraphDepth: depthCount > 0 ? totalDepth / depthCount : 0,
1231
+ lastUpdateAt: this.getLastUpdateTimestamp(),
1232
+ memoryBytes: graphSize + rowLineageSize,
1233
+ }
1234
+ }
1235
+
1236
+ /**
1237
+ * Calculate the depth of a node in the graph
1238
+ */
1239
+ private calculateNodeDepth(nodeId: string): number {
1240
+ let maxDepth = 0
1241
+ const visited = new Set<string>()
1242
+ const queue: { id: string; depth: number }[] = [{ id: nodeId, depth: 0 }]
1243
+
1244
+ while (queue.length > 0) {
1245
+ const { id, depth } = queue.shift()!
1246
+
1247
+ if (visited.has(id)) continue
1248
+ visited.add(id)
1249
+
1250
+ maxDepth = Math.max(maxDepth, depth)
1251
+
1252
+ const edgeIds = this.graph.targetIndex.get(id) || new Set()
1253
+ for (const edgeId of edgeIds) {
1254
+ const edge = this.graph.edges.get(edgeId)
1255
+ if (edge) {
1256
+ queue.push({ id: edge.sourceId, depth: depth + 1 })
1257
+ }
1258
+ }
1259
+ }
1260
+
1261
+ return maxDepth
1262
+ }
1263
+
1264
+ /**
1265
+ * Get the last update timestamp
1266
+ */
1267
+ private getLastUpdateTimestamp(): number | null {
1268
+ let lastUpdate: number | null = null
1269
+
1270
+ for (const [, node] of this.graph.nodes) {
1271
+ if (lastUpdate === null || node.updatedAt > lastUpdate) {
1272
+ lastUpdate = node.updatedAt
1273
+ }
1274
+ }
1275
+
1276
+ return lastUpdate
1277
+ }
1278
+
1279
+ /**
1280
+ * Export lineage metadata for Iceberg table properties
1281
+ */
1282
+ exportIcebergMetadata(schema: string, table: string): IcebergLineageMetadata {
1283
+ const lineage = this.getTableLineage(schema, table)
1284
+
1285
+ return {
1286
+ 'lineage.version': '1.0',
1287
+ 'lineage.sources': lineage.upstreamTables.join(','),
1288
+ 'lineage.operations': lineage.edges.map((e) => e.operation).join(','),
1289
+ 'lineage.updated-at': new Date().toISOString(),
1290
+ 'lineage.graph': JSON.stringify({
1291
+ upstreamTables: lineage.upstreamTables,
1292
+ downstreamTables: lineage.downstreamTables,
1293
+ edges: lineage.edges.map((e) => ({
1294
+ source: e.sourceId,
1295
+ target: e.targetId,
1296
+ operation: e.operation,
1297
+ })),
1298
+ }),
1299
+ }
1300
+ }
1301
+
1302
+ /**
1303
+ * Import lineage metadata from Iceberg table properties
1304
+ */
1305
+ importIcebergMetadata(schema: string, table: string, metadata: IcebergLineageMetadata): void {
1306
+ if (!metadata['lineage.graph']) return
1307
+
1308
+ try {
1309
+ const graph = JSON.parse(metadata['lineage.graph'])
1310
+
1311
+ // Ensure the target node exists
1312
+ this.ensureNode(schema, table, 'table')
1313
+
1314
+ // Import edges
1315
+ for (const edge of graph.edges || []) {
1316
+ const [sourceSchema, sourceTable] = edge.source.split('.')
1317
+ this.ensureNode(sourceSchema, sourceTable, 'table')
1318
+
1319
+ this.addEdge({
1320
+ id: generateEdgeId(edge.source, edge.target, Date.now()),
1321
+ sourceId: edge.source,
1322
+ targetId: edge.target,
1323
+ operation: edge.operation,
1324
+ timestamp: new Date(metadata['lineage.updated-at']).getTime(),
1325
+ })
1326
+ }
1327
+ } catch (error) {
1328
+ console.error('Failed to import lineage metadata:', error)
1329
+ }
1330
+ }
1331
+
1332
+ /**
1333
+ * Query all upstream tables (data sources) for a given table
1334
+ * Traverses the graph recursively to find all tables that feed into this one
1335
+ */
1336
+ queryUpstreamLineage(schema: string, table: string, maxDepth?: number): {
1337
+ tables: { schema: string; table: string; depth: number }[]
1338
+ edges: LineageEdge[]
1339
+ totalDepth: number
1340
+ } {
1341
+ // Use provided maxDepth, or fallback to config. When maxDepth is explicitly 0, use 0.
1342
+ const depth = maxDepth !== undefined ? maxDepth : this.config.maxDepth
1343
+ const nodeId = generateNodeId(schema, table)
1344
+
1345
+ const tables: { schema: string; table: string; depth: number }[] = []
1346
+ const edges: LineageEdge[] = []
1347
+ const visited = new Set<string>()
1348
+ const visitedEdges = new Set<string>()
1349
+
1350
+ // If maxDepth is 0, return empty results (no traversal)
1351
+ if (depth === 0) {
1352
+ return { tables, edges, totalDepth: 0 }
1353
+ }
1354
+
1355
+ const queue: { id: string; depth: number }[] = [{ id: nodeId, depth: 0 }]
1356
+ let totalDepth = 0
1357
+
1358
+ while (queue.length > 0) {
1359
+ const { id, depth: currentDepth } = queue.shift()!
1360
+
1361
+ if (visited.has(id) || currentDepth >= depth) continue
1362
+ visited.add(id)
1363
+
1364
+ // Get upstream edges (edges where this node is the target)
1365
+ const upstreamEdgeIds = this.graph.targetIndex.get(id) || new Set()
1366
+
1367
+ for (const edgeId of upstreamEdgeIds) {
1368
+ if (visitedEdges.has(edgeId)) continue
1369
+ visitedEdges.add(edgeId)
1370
+
1371
+ const edge = this.graph.edges.get(edgeId)
1372
+ if (!edge) continue
1373
+
1374
+ edges.push(edge)
1375
+
1376
+ // Add source node to results
1377
+ const sourceNode = this.graph.nodes.get(edge.sourceId)
1378
+ if (sourceNode && !visited.has(edge.sourceId)) {
1379
+ tables.push({
1380
+ schema: sourceNode.schema,
1381
+ table: sourceNode.name,
1382
+ depth: currentDepth + 1,
1383
+ })
1384
+ totalDepth = Math.max(totalDepth, currentDepth + 1)
1385
+ queue.push({ id: edge.sourceId, depth: currentDepth + 1 })
1386
+ }
1387
+ }
1388
+ }
1389
+
1390
+ return { tables, edges, totalDepth }
1391
+ }
1392
+
1393
+ /**
1394
+ * Query all downstream tables (data consumers) for a given table
1395
+ * Traverses the graph recursively to find all tables that are derived from this one
1396
+ */
1397
+ queryDownstreamLineage(schema: string, table: string, maxDepth?: number): {
1398
+ tables: { schema: string; table: string; depth: number }[]
1399
+ edges: LineageEdge[]
1400
+ totalDepth: number
1401
+ } {
1402
+ const depth = maxDepth || this.config.maxDepth
1403
+ const nodeId = generateNodeId(schema, table)
1404
+
1405
+ const tables: { schema: string; table: string; depth: number }[] = []
1406
+ const edges: LineageEdge[] = []
1407
+ const visited = new Set<string>()
1408
+ const visitedEdges = new Set<string>()
1409
+
1410
+ const queue: { id: string; depth: number }[] = [{ id: nodeId, depth: 0 }]
1411
+ let totalDepth = 0
1412
+
1413
+ while (queue.length > 0) {
1414
+ const { id, depth: currentDepth } = queue.shift()!
1415
+
1416
+ if (visited.has(id) || currentDepth > depth) continue
1417
+ visited.add(id)
1418
+
1419
+ // Get downstream edges (edges where this node is the source)
1420
+ const downstreamEdgeIds = this.graph.sourceIndex.get(id) || new Set()
1421
+
1422
+ for (const edgeId of downstreamEdgeIds) {
1423
+ if (visitedEdges.has(edgeId)) continue
1424
+ visitedEdges.add(edgeId)
1425
+
1426
+ const edge = this.graph.edges.get(edgeId)
1427
+ if (!edge) continue
1428
+
1429
+ edges.push(edge)
1430
+
1431
+ // Add target node to results
1432
+ const targetNode = this.graph.nodes.get(edge.targetId)
1433
+ if (targetNode && !visited.has(edge.targetId)) {
1434
+ tables.push({
1435
+ schema: targetNode.schema,
1436
+ table: targetNode.name,
1437
+ depth: currentDepth + 1,
1438
+ })
1439
+ totalDepth = Math.max(totalDepth, currentDepth + 1)
1440
+ queue.push({ id: edge.targetId, depth: currentDepth + 1 })
1441
+ }
1442
+ }
1443
+ }
1444
+
1445
+ return { tables, edges, totalDepth }
1446
+ }
1447
+
1448
+ /**
1449
+ * Find the shortest path between two tables in the lineage graph
1450
+ */
1451
+ findLineagePath(
1452
+ sourceSchema: string,
1453
+ sourceTable: string,
1454
+ targetSchema: string,
1455
+ targetTable: string
1456
+ ): { path: string[]; edges: LineageEdge[] } | null {
1457
+ const sourceId = generateNodeId(sourceSchema, sourceTable)
1458
+ const targetId = generateNodeId(targetSchema, targetTable)
1459
+
1460
+ if (!this.graph.nodes.has(sourceId) || !this.graph.nodes.has(targetId)) {
1461
+ return null
1462
+ }
1463
+
1464
+ // BFS to find shortest path
1465
+ const visited = new Set<string>()
1466
+ const parent = new Map<string, { nodeId: string; edge: LineageEdge }>()
1467
+ const queue: string[] = [sourceId]
1468
+
1469
+ visited.add(sourceId)
1470
+
1471
+ while (queue.length > 0) {
1472
+ const current = queue.shift()!
1473
+
1474
+ if (current === targetId) {
1475
+ // Reconstruct path
1476
+ const path: string[] = []
1477
+ const edges: LineageEdge[] = []
1478
+ let node = targetId
1479
+
1480
+ while (node !== sourceId) {
1481
+ path.unshift(node)
1482
+ const parentInfo = parent.get(node)!
1483
+ edges.unshift(parentInfo.edge)
1484
+ node = parentInfo.nodeId
1485
+ }
1486
+ path.unshift(sourceId)
1487
+
1488
+ return { path, edges }
1489
+ }
1490
+
1491
+ // Explore downstream edges
1492
+ const downstreamEdgeIds = this.graph.sourceIndex.get(current) || new Set()
1493
+ for (const edgeId of downstreamEdgeIds) {
1494
+ const edge = this.graph.edges.get(edgeId)
1495
+ if (edge && !visited.has(edge.targetId)) {
1496
+ visited.add(edge.targetId)
1497
+ parent.set(edge.targetId, { nodeId: current, edge })
1498
+ queue.push(edge.targetId)
1499
+ }
1500
+ }
1501
+ }
1502
+
1503
+ return null // No path found
1504
+ }
1505
+
1506
+ /**
1507
+ * Get impact analysis: all tables that would be affected by changes to a source table
1508
+ */
1509
+ getImpactAnalysis(schema: string, table: string): {
1510
+ directlyAffected: { schema: string; table: string }[]
1511
+ transitivelyAffected: { schema: string; table: string; hops: number }[]
1512
+ totalAffected: number
1513
+ } {
1514
+ const downstream = this.queryDownstreamLineage(schema, table)
1515
+
1516
+ const directlyAffected = downstream.tables
1517
+ .filter((t) => t.depth === 1)
1518
+ .map((t) => ({ schema: t.schema, table: t.table }))
1519
+
1520
+ const transitivelyAffected = downstream.tables
1521
+ .filter((t) => t.depth > 1)
1522
+ .map((t) => ({ schema: t.schema, table: t.table, hops: t.depth }))
1523
+
1524
+ return {
1525
+ directlyAffected,
1526
+ transitivelyAffected,
1527
+ totalAffected: downstream.tables.length,
1528
+ }
1529
+ }
1530
+
1531
+ /**
1532
+ * Get data provenance: full lineage history for understanding data origin
1533
+ */
1534
+ getDataProvenance(schema: string, table: string): {
1535
+ rootSources: { schema: string; table: string }[]
1536
+ transformationChain: { table: string; operation: LineageOperationType; timestamp: number }[]
1537
+ depth: number
1538
+ } {
1539
+ const upstream = this.queryUpstreamLineage(schema, table)
1540
+
1541
+ // Find root sources (tables with no upstream dependencies)
1542
+ const rootSources: { schema: string; table: string }[] = []
1543
+ for (const t of upstream.tables) {
1544
+ const nodeId = generateNodeId(t.schema, t.table)
1545
+ const hasUpstream = (this.graph.targetIndex.get(nodeId)?.size || 0) > 0
1546
+ if (!hasUpstream) {
1547
+ rootSources.push({ schema: t.schema, table: t.table })
1548
+ }
1549
+ }
1550
+
1551
+ // Build transformation chain
1552
+ const transformationChain = upstream.edges
1553
+ .sort((a, b) => a.timestamp - b.timestamp)
1554
+ .map((e) => ({
1555
+ table: e.targetId,
1556
+ operation: e.operation,
1557
+ timestamp: e.timestamp,
1558
+ }))
1559
+
1560
+ return {
1561
+ rootSources,
1562
+ transformationChain,
1563
+ depth: upstream.totalDepth,
1564
+ }
1565
+ }
1566
+
1567
+ /**
1568
+ * List all tracked tables
1569
+ */
1570
+ listTrackedTables(): { schema: string; table: string; type: LineageNode['type'] }[] {
1571
+ const tables: { schema: string; table: string; type: LineageNode['type'] }[] = []
1572
+
1573
+ for (const [, node] of this.graph.nodes) {
1574
+ tables.push({
1575
+ schema: node.schema,
1576
+ table: node.name,
1577
+ type: node.type,
1578
+ })
1579
+ }
1580
+
1581
+ return tables
1582
+ }
1583
+
1584
+ /**
1585
+ * Get node by ID
1586
+ */
1587
+ getNode(schema: string, table: string): LineageNode | null {
1588
+ const nodeId = generateNodeId(schema, table)
1589
+ return this.graph.nodes.get(nodeId) || null
1590
+ }
1591
+
1592
+ /**
1593
+ * Clear all lineage data
1594
+ */
1595
+ clear(): void {
1596
+ this.graph = {
1597
+ nodes: new Map(),
1598
+ edges: new Map(),
1599
+ sourceIndex: new Map(),
1600
+ targetIndex: new Map(),
1601
+ }
1602
+ this.rowLineageMap.clear()
1603
+ }
1604
+
1605
+ /**
1606
+ * Get the full lineage graph
1607
+ */
1608
+ getGraph(): LineageGraph {
1609
+ return this.graph
1610
+ }
1611
+ }
1612
+
1613
+ /**
1614
+ * Create a lineage tracker with default configuration
1615
+ */
1616
+ export function createLineageTracker(config?: LineageTrackerConfig): LineageTracker {
1617
+ return new LineageTracker(config)
1618
+ }