@quereus/quereus 4.7.0 → 4.9.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 (218) hide show
  1. package/dist/src/common/types.d.ts +19 -0
  2. package/dist/src/common/types.d.ts.map +1 -1
  3. package/dist/src/common/types.js.map +1 -1
  4. package/dist/src/core/database.d.ts +45 -1
  5. package/dist/src/core/database.d.ts.map +1 -1
  6. package/dist/src/core/database.js +212 -2
  7. package/dist/src/core/database.js.map +1 -1
  8. package/dist/src/core/statement.d.ts.map +1 -1
  9. package/dist/src/core/statement.js +86 -0
  10. package/dist/src/core/statement.js.map +1 -1
  11. package/dist/src/func/builtins/aggregate.d.ts.map +1 -1
  12. package/dist/src/func/builtins/aggregate.js +3 -2
  13. package/dist/src/func/builtins/aggregate.js.map +1 -1
  14. package/dist/src/func/builtins/conversion.d.ts +5 -0
  15. package/dist/src/func/builtins/conversion.d.ts.map +1 -1
  16. package/dist/src/func/builtins/conversion.js +16 -2
  17. package/dist/src/func/builtins/conversion.js.map +1 -1
  18. package/dist/src/func/builtins/index.d.ts.map +1 -1
  19. package/dist/src/func/builtins/index.js +5 -2
  20. package/dist/src/func/builtins/index.js.map +1 -1
  21. package/dist/src/func/builtins/string.d.ts +2 -0
  22. package/dist/src/func/builtins/string.d.ts.map +1 -1
  23. package/dist/src/func/builtins/string.js +60 -4
  24. package/dist/src/func/builtins/string.js.map +1 -1
  25. package/dist/src/index.d.ts +11 -4
  26. package/dist/src/index.d.ts.map +1 -1
  27. package/dist/src/index.js +18 -3
  28. package/dist/src/index.js.map +1 -1
  29. package/dist/src/planner/building/constraint-builder.js +1 -1
  30. package/dist/src/planner/building/constraint-builder.js.map +1 -1
  31. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.d.ts.map +1 -1
  32. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js +121 -51
  33. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js.map +1 -1
  34. package/dist/src/planner/rules/shared/index-style-context.d.ts +14 -4
  35. package/dist/src/planner/rules/shared/index-style-context.d.ts.map +1 -1
  36. package/dist/src/planner/rules/shared/index-style-context.js +14 -4
  37. package/dist/src/planner/rules/shared/index-style-context.js.map +1 -1
  38. package/dist/src/runtime/emit/alter-table.d.ts.map +1 -1
  39. package/dist/src/runtime/emit/alter-table.js +212 -155
  40. package/dist/src/runtime/emit/alter-table.js.map +1 -1
  41. package/dist/src/runtime/emit/assertion-drop-guard.d.ts +26 -12
  42. package/dist/src/runtime/emit/assertion-drop-guard.d.ts.map +1 -1
  43. package/dist/src/runtime/emit/assertion-drop-guard.js +45 -26
  44. package/dist/src/runtime/emit/assertion-drop-guard.js.map +1 -1
  45. package/dist/src/runtime/emit/assertion-rename-helpers.d.ts +6 -6
  46. package/dist/src/runtime/emit/assertion-rename-helpers.d.ts.map +1 -1
  47. package/dist/src/runtime/emit/assertion-rename-helpers.js +18 -20
  48. package/dist/src/runtime/emit/assertion-rename-helpers.js.map +1 -1
  49. package/dist/src/runtime/emit/binary.d.ts.map +1 -1
  50. package/dist/src/runtime/emit/binary.js +12 -10
  51. package/dist/src/runtime/emit/binary.js.map +1 -1
  52. package/dist/src/runtime/emit/column-rename-cascade.d.ts +84 -0
  53. package/dist/src/runtime/emit/column-rename-cascade.d.ts.map +1 -0
  54. package/dist/src/runtime/emit/column-rename-cascade.js +134 -0
  55. package/dist/src/runtime/emit/column-rename-cascade.js.map +1 -0
  56. package/dist/src/runtime/emit/drop-column-guards.d.ts +82 -53
  57. package/dist/src/runtime/emit/drop-column-guards.d.ts.map +1 -1
  58. package/dist/src/runtime/emit/drop-column-guards.js +155 -90
  59. package/dist/src/runtime/emit/drop-column-guards.js.map +1 -1
  60. package/dist/src/runtime/emit/drop-table.d.ts.map +1 -1
  61. package/dist/src/runtime/emit/drop-table.js +5 -0
  62. package/dist/src/runtime/emit/drop-table.js.map +1 -1
  63. package/dist/src/runtime/emit/drop-view.d.ts.map +1 -1
  64. package/dist/src/runtime/emit/drop-view.js +5 -0
  65. package/dist/src/runtime/emit/drop-view.js.map +1 -1
  66. package/dist/src/runtime/emit/expression-drop-guard.d.ts +57 -0
  67. package/dist/src/runtime/emit/expression-drop-guard.d.ts.map +1 -0
  68. package/dist/src/runtime/emit/expression-drop-guard.js +82 -0
  69. package/dist/src/runtime/emit/expression-drop-guard.js.map +1 -0
  70. package/dist/src/runtime/emit/materialized-view-helpers.d.ts +26 -9
  71. package/dist/src/runtime/emit/materialized-view-helpers.d.ts.map +1 -1
  72. package/dist/src/runtime/emit/materialized-view-helpers.js +37 -17
  73. package/dist/src/runtime/emit/materialized-view-helpers.js.map +1 -1
  74. package/dist/src/runtime/emit/materialized-view.d.ts.map +1 -1
  75. package/dist/src/runtime/emit/materialized-view.js +3 -0
  76. package/dist/src/runtime/emit/materialized-view.js.map +1 -1
  77. package/dist/src/runtime/emit/remote-query.d.ts.map +1 -1
  78. package/dist/src/runtime/emit/remote-query.js +8 -3
  79. package/dist/src/runtime/emit/remote-query.js.map +1 -1
  80. package/dist/src/runtime/emit/scan.d.ts.map +1 -1
  81. package/dist/src/runtime/emit/scan.js +4 -1
  82. package/dist/src/runtime/emit/scan.js.map +1 -1
  83. package/dist/src/runtime/emit/schema-declarative.js +2 -2
  84. package/dist/src/runtime/emit/schema-declarative.js.map +1 -1
  85. package/dist/src/runtime/parallel-driver.d.ts +4 -3
  86. package/dist/src/runtime/parallel-driver.d.ts.map +1 -1
  87. package/dist/src/runtime/parallel-driver.js +8 -3
  88. package/dist/src/runtime/parallel-driver.js.map +1 -1
  89. package/dist/src/runtime/types.d.ts +10 -0
  90. package/dist/src/runtime/types.d.ts.map +1 -1
  91. package/dist/src/runtime/types.js.map +1 -1
  92. package/dist/src/runtime/utils.d.ts.map +1 -1
  93. package/dist/src/runtime/utils.js +11 -0
  94. package/dist/src/runtime/utils.js.map +1 -1
  95. package/dist/src/schema/assertion.d.ts +58 -0
  96. package/dist/src/schema/assertion.d.ts.map +1 -1
  97. package/dist/src/schema/assertion.js +78 -0
  98. package/dist/src/schema/assertion.js.map +1 -1
  99. package/dist/src/schema/catalog-persistability.d.ts +11 -3
  100. package/dist/src/schema/catalog-persistability.d.ts.map +1 -1
  101. package/dist/src/schema/catalog-persistability.js +48 -29
  102. package/dist/src/schema/catalog-persistability.js.map +1 -1
  103. package/dist/src/schema/catalog.d.ts +22 -0
  104. package/dist/src/schema/catalog.d.ts.map +1 -1
  105. package/dist/src/schema/catalog.js +4 -1
  106. package/dist/src/schema/catalog.js.map +1 -1
  107. package/dist/src/schema/column-republication.d.ts +126 -0
  108. package/dist/src/schema/column-republication.d.ts.map +1 -0
  109. package/dist/src/schema/column-republication.js +121 -0
  110. package/dist/src/schema/column-republication.js.map +1 -0
  111. package/dist/src/schema/column-source-resolver.d.ts +29 -6
  112. package/dist/src/schema/column-source-resolver.d.ts.map +1 -1
  113. package/dist/src/schema/column-source-resolver.js +78 -9
  114. package/dist/src/schema/column-source-resolver.js.map +1 -1
  115. package/dist/src/schema/expression-dependents.d.ts +160 -0
  116. package/dist/src/schema/expression-dependents.d.ts.map +1 -0
  117. package/dist/src/schema/expression-dependents.js +228 -0
  118. package/dist/src/schema/expression-dependents.js.map +1 -0
  119. package/dist/src/schema/object-dependency-closure.d.ts +127 -0
  120. package/dist/src/schema/object-dependency-closure.d.ts.map +1 -0
  121. package/dist/src/schema/object-dependency-closure.js +117 -0
  122. package/dist/src/schema/object-dependency-closure.js.map +1 -0
  123. package/dist/src/schema/object-ref-resolver.d.ts +83 -0
  124. package/dist/src/schema/object-ref-resolver.d.ts.map +1 -0
  125. package/dist/src/schema/object-ref-resolver.js +135 -0
  126. package/dist/src/schema/object-ref-resolver.js.map +1 -0
  127. package/dist/src/schema/rename/column-rename.d.ts +228 -0
  128. package/dist/src/schema/rename/column-rename.d.ts.map +1 -0
  129. package/dist/src/schema/rename/column-rename.js +1225 -0
  130. package/dist/src/schema/rename/column-rename.js.map +1 -0
  131. package/dist/src/schema/rename/self-qualifier-strip.d.ts +29 -0
  132. package/dist/src/schema/rename/self-qualifier-strip.d.ts.map +1 -0
  133. package/dist/src/schema/rename/self-qualifier-strip.js +267 -0
  134. package/dist/src/schema/rename/self-qualifier-strip.js.map +1 -0
  135. package/dist/src/schema/rename/shared.d.ts +108 -0
  136. package/dist/src/schema/rename/shared.d.ts.map +1 -0
  137. package/dist/src/schema/rename/shared.js +49 -0
  138. package/dist/src/schema/rename/shared.js.map +1 -0
  139. package/dist/src/schema/rename/table-rename.d.ts +263 -0
  140. package/dist/src/schema/rename/table-rename.d.ts.map +1 -0
  141. package/dist/src/schema/rename/table-rename.js +860 -0
  142. package/dist/src/schema/rename/table-rename.js.map +1 -0
  143. package/dist/src/schema/rename-rewriter.d.ts +18 -278
  144. package/dist/src/schema/rename-rewriter.d.ts.map +1 -1
  145. package/dist/src/schema/rename-rewriter.js +17 -1506
  146. package/dist/src/schema/rename-rewriter.js.map +1 -1
  147. package/dist/src/schema/schema-differ.d.ts.map +1 -1
  148. package/dist/src/schema/schema-differ.js +228 -21
  149. package/dist/src/schema/schema-differ.js.map +1 -1
  150. package/dist/src/types/builtin-types.d.ts.map +1 -1
  151. package/dist/src/types/builtin-types.js +12 -28
  152. package/dist/src/types/builtin-types.js.map +1 -1
  153. package/dist/src/types/cast-semantics.d.ts +7 -5
  154. package/dist/src/types/cast-semantics.d.ts.map +1 -1
  155. package/dist/src/types/cast-semantics.js +20 -9
  156. package/dist/src/types/cast-semantics.js.map +1 -1
  157. package/dist/src/types/index.d.ts +1 -1
  158. package/dist/src/types/index.d.ts.map +1 -1
  159. package/dist/src/types/index.js +1 -1
  160. package/dist/src/types/index.js.map +1 -1
  161. package/dist/src/types/registry.d.ts.map +1 -1
  162. package/dist/src/types/registry.js +2 -1
  163. package/dist/src/types/registry.js.map +1 -1
  164. package/dist/src/types/temporal-types.d.ts +11 -0
  165. package/dist/src/types/temporal-types.d.ts.map +1 -1
  166. package/dist/src/types/temporal-types.js +82 -0
  167. package/dist/src/types/temporal-types.js.map +1 -1
  168. package/dist/src/util/abort-signal.d.ts +25 -0
  169. package/dist/src/util/abort-signal.d.ts.map +1 -0
  170. package/dist/src/util/abort-signal.js +40 -0
  171. package/dist/src/util/abort-signal.js.map +1 -0
  172. package/dist/src/util/affinity.d.ts +2 -1
  173. package/dist/src/util/affinity.d.ts.map +1 -1
  174. package/dist/src/util/affinity.js +16 -5
  175. package/dist/src/util/affinity.js.map +1 -1
  176. package/dist/src/util/ast-spine-clone.d.ts +2 -2
  177. package/dist/src/util/ast-spine-clone.js +2 -2
  178. package/dist/src/util/value-text.d.ts +48 -0
  179. package/dist/src/util/value-text.d.ts.map +1 -0
  180. package/dist/src/util/value-text.js +35 -0
  181. package/dist/src/util/value-text.js.map +1 -0
  182. package/dist/src/vtab/concurrency.d.ts +15 -0
  183. package/dist/src/vtab/concurrency.d.ts.map +1 -1
  184. package/dist/src/vtab/concurrency.js +17 -0
  185. package/dist/src/vtab/concurrency.js.map +1 -1
  186. package/dist/src/vtab/memory/layer/base.d.ts +10 -0
  187. package/dist/src/vtab/memory/layer/base.d.ts.map +1 -1
  188. package/dist/src/vtab/memory/layer/base.js +10 -0
  189. package/dist/src/vtab/memory/layer/base.js.map +1 -1
  190. package/dist/src/vtab/memory/layer/interface.d.ts +24 -0
  191. package/dist/src/vtab/memory/layer/interface.d.ts.map +1 -1
  192. package/dist/src/vtab/memory/layer/manager.d.ts +21 -3
  193. package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
  194. package/dist/src/vtab/memory/layer/manager.js +118 -93
  195. package/dist/src/vtab/memory/layer/manager.js.map +1 -1
  196. package/dist/src/vtab/memory/layer/transaction.d.ts +11 -0
  197. package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -1
  198. package/dist/src/vtab/memory/layer/transaction.js +19 -0
  199. package/dist/src/vtab/memory/layer/transaction.js.map +1 -1
  200. package/dist/src/vtab/memory/module.d.ts +41 -0
  201. package/dist/src/vtab/memory/module.d.ts.map +1 -1
  202. package/dist/src/vtab/memory/module.js +41 -0
  203. package/dist/src/vtab/memory/module.js.map +1 -1
  204. package/dist/src/vtab/memory/table.d.ts +12 -1
  205. package/dist/src/vtab/memory/table.d.ts.map +1 -1
  206. package/dist/src/vtab/memory/table.js +12 -1
  207. package/dist/src/vtab/memory/table.js.map +1 -1
  208. package/dist/src/vtab/module.d.ts +33 -0
  209. package/dist/src/vtab/module.d.ts.map +1 -1
  210. package/dist/src/vtab/test-support/commit-stall.d.ts +53 -0
  211. package/dist/src/vtab/test-support/commit-stall.d.ts.map +1 -0
  212. package/dist/src/vtab/test-support/commit-stall.js +73 -0
  213. package/dist/src/vtab/test-support/commit-stall.js.map +1 -0
  214. package/dist/src/vtab/test-support/committed-read-conformance.d.ts +96 -0
  215. package/dist/src/vtab/test-support/committed-read-conformance.d.ts.map +1 -0
  216. package/dist/src/vtab/test-support/committed-read-conformance.js +364 -0
  217. package/dist/src/vtab/test-support/committed-read-conformance.js.map +1 -0
  218. package/package.json +3 -3
@@ -1,18 +1,41 @@
1
- import type { SchemaManager } from './manager.js';
1
+ import type { Database } from '../core/database.js';
2
2
  import type { ResolveColumnInSource } from './rename-rewriter.js';
3
3
  /**
4
4
  * The catalog-backed {@link ResolveColumnInSource} every scope-aware walk over a
5
5
  * schema-object expression consults to tell an unqualified reference that binds to an
6
6
  * inner FROM source from one that binds to the table under consideration.
7
7
  *
8
- * Three callers, one definition, so no two of them can disagree about what a name
8
+ * Four callers, one definition, so no two of them can disagree about what a name
9
9
  * resolves to: `runRenameColumn`'s pre-flight probe and its real propagation, the
10
- * DROP COLUMN guards in `runtime/emit/drop-column-guards.ts`, and the constraint
11
- * planner's self-qualifier strip (`planner/building/constraint-builder.ts`).
10
+ * DROP COLUMN guards (`runtime/emit/drop-column-guards.ts` and
11
+ * `schema/expression-dependents.ts`), and the constraint planner's self-qualifier
12
+ * strip (`planner/building/constraint-builder.ts`).
13
+ *
14
+ * A source may be a TABLE (a maintained table included — its backing columns are
15
+ * real) or a VIEW. A view exposes a column when its explicit column list names it,
16
+ * or — with no list — when its body publishes it ({@link bodyPublishesColumnNamed}:
17
+ * a result-column alias, a bare projection, or a `*` / `t.*` / `a.*` over a source
18
+ * that exposes it — a FROM alias only changes which qualifier names the source, so
19
+ * `select * from t a` publishes exactly what `select * from t` does). The view arm
20
+ * recurses through this same resolver, so a view over a
21
+ * view answers too; views cannot be recursive, so the per-question in-flight set is
22
+ * insurance against a malformed catalog, the same role the visited set plays in
23
+ * `reachableObjects`.
12
24
  *
13
25
  * Resolves against the LIVE catalog on every call, so sharing one instance across
14
26
  * passes does not by itself freeze the answer between them — see the rename
15
- * pre-flight's comment for why its two passes agree anyway.
27
+ * pre-flight's comment for why its two passes agree anyway. The view arm's
28
+ * unqualified names likewise resolve LIVE down the view's home schema path
29
+ * ({@link Database._homeSchemaPath}), matching how the view body plans.
30
+ *
31
+ * NOTE: deliberately NO cross-call memo. The rename propagation shares one
32
+ * instance across its pre-flight and its live cascade rounds, and the rounds
33
+ * rewrite view bodies in place — a memoized "does view X expose col?" answer taken
34
+ * before a round would be stale after it. The per-question in-flight set bounds the
35
+ * recursion instead. The one hot-ish caller is `constraint-builder.ts` at
36
+ * plan-build time, where the view arm only runs for a CHECK whose subquery FROMs a
37
+ * view; if that ever profiles hot, add a cross-call memo guarded by a catalog
38
+ * generation counter.
16
39
  */
17
- export declare function buildColumnSourceResolver(schemaManager: SchemaManager): ResolveColumnInSource;
40
+ export declare function buildColumnSourceResolver(db: Database): ResolveColumnInSource;
18
41
  //# sourceMappingURL=column-source-resolver.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"column-source-resolver.d.ts","sourceRoot":"","sources":["../../../src/schema/column-source-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAElE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CAAC,aAAa,EAAE,aAAa,GAAG,qBAAqB,CAM7F"}
1
+ {"version":3,"file":"column-source-resolver.d.ts","sourceRoot":"","sources":["../../../src/schema/column-source-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,qBAAqB,EAAoB,MAAM,sBAAsB,CAAC;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,QAAQ,GAAG,qBAAqB,CAyB7E"}
@@ -1,22 +1,91 @@
1
+ import { bodyPublishesColumnNamed, objectRefKey } from './rename-rewriter.js';
1
2
  /**
2
3
  * The catalog-backed {@link ResolveColumnInSource} every scope-aware walk over a
3
4
  * schema-object expression consults to tell an unqualified reference that binds to an
4
5
  * inner FROM source from one that binds to the table under consideration.
5
6
  *
6
- * Three callers, one definition, so no two of them can disagree about what a name
7
+ * Four callers, one definition, so no two of them can disagree about what a name
7
8
  * resolves to: `runRenameColumn`'s pre-flight probe and its real propagation, the
8
- * DROP COLUMN guards in `runtime/emit/drop-column-guards.ts`, and the constraint
9
- * planner's self-qualifier strip (`planner/building/constraint-builder.ts`).
9
+ * DROP COLUMN guards (`runtime/emit/drop-column-guards.ts` and
10
+ * `schema/expression-dependents.ts`), and the constraint planner's self-qualifier
11
+ * strip (`planner/building/constraint-builder.ts`).
12
+ *
13
+ * A source may be a TABLE (a maintained table included — its backing columns are
14
+ * real) or a VIEW. A view exposes a column when its explicit column list names it,
15
+ * or — with no list — when its body publishes it ({@link bodyPublishesColumnNamed}:
16
+ * a result-column alias, a bare projection, or a `*` / `t.*` / `a.*` over a source
17
+ * that exposes it — a FROM alias only changes which qualifier names the source, so
18
+ * `select * from t a` publishes exactly what `select * from t` does). The view arm
19
+ * recurses through this same resolver, so a view over a
20
+ * view answers too; views cannot be recursive, so the per-question in-flight set is
21
+ * insurance against a malformed catalog, the same role the visited set plays in
22
+ * `reachableObjects`.
10
23
  *
11
24
  * Resolves against the LIVE catalog on every call, so sharing one instance across
12
25
  * passes does not by itself freeze the answer between them — see the rename
13
- * pre-flight's comment for why its two passes agree anyway.
26
+ * pre-flight's comment for why its two passes agree anyway. The view arm's
27
+ * unqualified names likewise resolve LIVE down the view's home schema path
28
+ * ({@link Database._homeSchemaPath}), matching how the view body plans.
29
+ *
30
+ * NOTE: deliberately NO cross-call memo. The rename propagation shares one
31
+ * instance across its pre-flight and its live cascade rounds, and the rounds
32
+ * rewrite view bodies in place — a memoized "does view X expose col?" answer taken
33
+ * before a round would be stale after it. The per-question in-flight set bounds the
34
+ * recursion instead. The one hot-ish caller is `constraint-builder.ts` at
35
+ * plan-build time, where the view arm only runs for a CHECK whose subquery FROMs a
36
+ * view; if that ever profiles hot, add a cross-call memo guarded by a catalog
37
+ * generation counter.
38
+ */
39
+ export function buildColumnSourceResolver(db) {
40
+ const answer = (schemaName, sourceName, columnName, inFlight) => {
41
+ const targetSchema = db.schemaManager.getSchema(schemaName);
42
+ if (!targetSchema)
43
+ return false;
44
+ const colLower = columnName.toLowerCase();
45
+ const table = targetSchema.getTable(sourceName);
46
+ if (table)
47
+ return table.columnIndexMap.has(colLower);
48
+ const view = targetSchema.getView(sourceName);
49
+ if (!view)
50
+ return false;
51
+ if (view.columns && view.columns.length > 0) {
52
+ return view.columns.some(c => c.toLowerCase() === colLower);
53
+ }
54
+ const key = `${objectRefKey(targetSchema.name, view.name)}:${colLower}`;
55
+ if (inFlight.has(key))
56
+ return false;
57
+ inFlight.add(key);
58
+ try {
59
+ const recurse = (s, t, c) => answer(s, t, c, inFlight);
60
+ return bodyPublishesColumnNamed(view.selectAst, columnName, liveHomePathResolver(db, view.schemaName), recurse);
61
+ }
62
+ finally {
63
+ inFlight.delete(key);
64
+ }
65
+ };
66
+ return (schemaName, sourceName, columnName) => answer(schemaName, sourceName, columnName, new Set());
67
+ }
68
+ /**
69
+ * Live {@link ResolveObjectRef} for one home schema — the same resolution rule
70
+ * `snapshotObjectRefResolvers` snapshots (qualified passthrough; unqualified →
71
+ * first home-path schema holding a table or view of the name; miss → home key),
72
+ * answered against the live catalog. Live is right here: this resolver's contract
73
+ * is live answers, and the rename cascade's mid-statement body rewrites change
74
+ * published COLUMNS, never the object names this resolves.
14
75
  */
15
- export function buildColumnSourceResolver(schemaManager) {
16
- return (s, t, col) => {
17
- const targetSchema = schemaManager.getSchema(s);
18
- const targetTable = targetSchema?.getTable(t);
19
- return targetTable?.columnIndexMap.has(col.toLowerCase()) ?? false;
76
+ function liveHomePathResolver(db, homeSchemaName) {
77
+ return (schema, name) => {
78
+ if (schema !== undefined)
79
+ return objectRefKey(schema, name);
80
+ for (const pathSchemaName of db._homeSchemaPath(homeSchemaName)) {
81
+ const pathSchema = db.schemaManager.getSchema(pathSchemaName);
82
+ if (!pathSchema)
83
+ continue;
84
+ if (pathSchema.getTable(name) !== undefined || pathSchema.getView(name) !== undefined) {
85
+ return objectRefKey(pathSchemaName, name);
86
+ }
87
+ }
88
+ return objectRefKey(homeSchemaName, name);
20
89
  };
21
90
  }
22
91
  //# sourceMappingURL=column-source-resolver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"column-source-resolver.js","sourceRoot":"","sources":["../../../src/schema/column-source-resolver.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,yBAAyB,CAAC,aAA4B;IACrE,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE;QACpB,MAAM,YAAY,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAChD,MAAM,WAAW,GAAG,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC9C,OAAO,WAAW,EAAE,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,IAAI,KAAK,CAAC;IACpE,CAAC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"column-source-resolver.js","sourceRoot":"","sources":["../../../src/schema/column-source-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,160 @@
1
+ import type { Database } from '../core/database.js';
2
+ import type { TableSchema } from './table.js';
3
+ /**
4
+ * The catalog query "which stored, table-attached expressions reference this object?",
5
+ * shared by every DROP guard that has to refuse breaking one.
6
+ *
7
+ * A CHECK constraint, a column DEFAULT and a `GENERATED ALWAYS AS` body may all contain
8
+ * a subquery, so any of them can legitimately name a column or a table belonging to some
9
+ * OTHER table, in some other schema. `ALTER TABLE … RENAME` has always known this — it
10
+ * rewrites those expressions across every table in every schema — while the DROP guards
11
+ * used to scan only the altered table's own constraints and columns. The gap let
12
+ * `alter table t drop column v` and `drop table t` succeed while another table's CHECK
13
+ * still read `t.v`, leaving that table unwritable with an error naming neither the
14
+ * dropped object nor the constraint that broke.
15
+ *
16
+ * Everything here therefore walks the catalog the same way the rename propagation does —
17
+ * ONE {@link snapshotObjectRefResolvers} snapshot, a resolver per OWNING schema, the same
18
+ * scope-aware probes — so "the drop refuses exactly what a rename would have rewritten"
19
+ * holds by construction rather than by comment.
20
+ *
21
+ * **The own-table / other-table probe split is load-bearing.** It mirrors
22
+ * `rewriteTableForColumnRename`'s `isRenamedTable` branch:
23
+ *
24
+ * - On the **probed table itself**, the *seeded* probe
25
+ * ({@link columnReferencedInCheckExpression}) — an unqualified name in a CHECK /
26
+ * DEFAULT there binds the owning table implicitly.
27
+ * - On **any other table**, the *unseeded* probe ({@link columnReferencedInAst}) — no
28
+ * implicit binding, so only an explicit reference through a subquery counts. Getting
29
+ * this backwards false-refuses on every table that merely happens to have a like-named
30
+ * column.
31
+ *
32
+ * The seed answers only that binding question. What a bare `new.` / `old.` qualifier
33
+ * NAMES is a separate, explicitly-passed
34
+ * {@link import('./rename-rewriter.js').RowImageContext} — `'own'` on the seeded
35
+ * base-target probe, `'foreign'` on every other ROOT body (that table's row image is its
36
+ * own columns, not ours), `'none'` on the view / MV bodies below the root. See
37
+ * {@link columnProbe}.
38
+ *
39
+ * Partial-index predicates need no arm: the parser rejects a subquery in a partial-index
40
+ * predicate, so such a predicate can only name its own table, and `runDropColumn`'s
41
+ * existing predicate guard covers that case.
42
+ *
43
+ * Views are deliberately NOT probed as *dependents*. Dropping a table or column out from
44
+ * under a plain view stays allowed and breaks the view — the engine's stated asymmetry
45
+ * (see `runtime/emit/assertion-drop-guard.ts`): a broken view breaks queries OF that view,
46
+ * while a broken CHECK makes a whole table unwritable.
47
+ *
48
+ * Each probe runs over the REACH of the stored expression — {@link reachableObjects}, the
49
+ * same breadth-first closure over stored view / materialized-view bodies the assertion
50
+ * guards consume — not over the expression alone. Two consequences, both load-bearing:
51
+ *
52
+ * - A DIRECT reference matches exactly where a rename would have rewritten it, so the two
53
+ * definitions still cannot drift; the reach path is empty there, which is what keeps the
54
+ * guards' direct message spelling unchanged.
55
+ * - An INDIRECT reference — the expression names a view, whose body names the dropped
56
+ * object, to any depth — matches too. Without that, `check (n < (select max(v) from vv))`
57
+ * over `create view vv as select v from t` let `drop table t` /
58
+ * `alter table t drop column v` through and left the referencing table unwritable with
59
+ * an error naming neither the dropped object nor the constraint that broke.
60
+ *
61
+ * The root body is walked with `rowImageContext` and every body below it without — see
62
+ * `reachableObjects`' `rootOpts`. Rooting a CHECK / DEFAULT without it would put a table
63
+ * literally called `new` in the reach and false-refuse its own drop.
64
+ *
65
+ * NOTE: each probe walks every table in every schema, re-walking already-parsed ASTs, and
66
+ * now builds one closure PER STORED EXPRESSION rather than per table. The closure only
67
+ * expands objects a body actually names, so an expression naming no view adds no reached
68
+ * bodies at all — but it is still one extra walk per expression for the COLUMN verb, which
69
+ * pays `collectTableRefsInAst` to build the reach and then the column probe on top (the
70
+ * table verb reads its answer straight off the reach, so it is walk-for-walk with the
71
+ * one-hop probe it replaced). The COLUMN verb additionally runs one republication
72
+ * fixpoint per guard call (`schema/column-republication.ts` — a catalog sweep per round)
73
+ * and probes bodies × targets instead of bodies × 1; targets beyond the base table exist
74
+ * only when some view republishes the dropped column, so the common case pays one sweep
75
+ * and nothing else. Reasoned from the call shape, not measured. DDL is rare and
76
+ * schemas hold handfuls of tables, so this is not worth optimising now; if it ever shows as
77
+ * hot, gate each table on a cheap literal name scan of its stored SQL before paying for the
78
+ * AST walk.
79
+ */
80
+ /** A stored, table-attached expression that references a probed object. */
81
+ export interface ExpressionDependent {
82
+ /** The table carrying the expression. */
83
+ table: TableSchema;
84
+ /** True when {@link table} IS the probed table (a self-reference), false otherwise. */
85
+ ownTable: boolean;
86
+ /** What to call it in an error: `CHECK constraint 'ck1'`, `the DEFAULT of column 'w'`, … */
87
+ describe: string;
88
+ /**
89
+ * The stored bodies the expression traversed to reach the probed object, each already
90
+ * described (`view 'v'`, `materialized view 'm'`) — EMPTY when the expression names the
91
+ * object itself. Feed it to `describeReachPath` to phrase an indirect refusal.
92
+ */
93
+ path: ReadonlyArray<string>;
94
+ /**
95
+ * Present when the match is not a body NAMING the column but a view / MV the drop
96
+ * would BREAK OUTRIGHT: the object declares an explicit column list over a body
97
+ * whose `*` republishes the dropped column, so the drop changes the star's arity
98
+ * and every reference to the object breaks — not just references to one column.
99
+ * The value is the object's description (`view 'v'`), for the refusal message.
100
+ */
101
+ breaksEntirely?: string;
102
+ }
103
+ /**
104
+ * Which family of stored expressions a column probe walks. The two exist separately
105
+ * because `runDropColumn` reports them through two guards with two different messages,
106
+ * ordered by widening blast radius.
107
+ */
108
+ export type ColumnExpressionArm =
109
+ /** CHECK constraint expressions. */
110
+ 'check'
111
+ /** Column DEFAULT and `GENERATED ALWAYS AS` expressions. */
112
+ | 'columnExpression';
113
+ /**
114
+ * The FIRST table in ANY schema whose `arm` expressions name
115
+ * `<tableSchema.schemaName>.<tableSchema.name>.<columnName>`, or `undefined` when none
116
+ * does. The probed table itself is scanned first, so a self-reference is always the one
117
+ * reported and the guards' own-table messages never change spelling because an unrelated
118
+ * schema happens to sort earlier.
119
+ *
120
+ * Only the first hit is returned: every caller is a guard that throws on it, and stopping
121
+ * early keeps the walk off the remaining schemas.
122
+ *
123
+ * Two expressions are skipped on the probed table itself, both deliberately:
124
+ *
125
+ * - The dropped column's **own** DEFAULT / generated body — it goes away with the column,
126
+ * so a self-naming default (`a integer default (new.a)`) is not something the drop
127
+ * orphans.
128
+ * - **Every** own-table generated body — `runDropColumn` already refuses off
129
+ * `generatedColumnDependencies`, the resolved column-index map
130
+ * `extractGeneratedColumnDependencies` builds, and reporting it twice would only change
131
+ * which of two messages the user sees. A generated body on ANOTHER table is not covered
132
+ * by that map and IS reported here.
133
+ */
134
+ export declare function findColumnExpressionDependent(db: Database, tableSchema: TableSchema, columnName: string, arm: ColumnExpressionArm): ExpressionDependent | undefined;
135
+ /**
136
+ * The FIRST table in ANY schema whose CHECK / DEFAULT / `GENERATED ALWAYS AS` expressions
137
+ * name `<schemaName>.<objectName>`, or `undefined` when none does.
138
+ *
139
+ * The dropped object itself is skipped: its own CHECKs naming itself vanish with it, so
140
+ * refusing on them would make every self-referencing table undroppable. (The column verb
141
+ * keeps its target in the walk — a column drop leaves the rest of the table behind.)
142
+ *
143
+ * All three arms run with the walker's `rowImageContext` on the ROOT expression, exactly as
144
+ * `renameTableInCheckConstraints` / `renameTableInColumnExpressions` do: these
145
+ * expressions evaluate against a written row, so a bare `new.` / `old.` qualifier names
146
+ * that row image rather than a table literally called `new`.
147
+ *
148
+ * The match is `namerOf` over the expression's whole reach, so a CHECK that reads a view
149
+ * whose body reads the dropped object matches too, and `path` carries the shortest chain
150
+ * for the error to quote — empty exactly when the expression names the object itself.
151
+ */
152
+ export declare function findTableExpressionDependent(db: Database, schemaName: string, objectName: string): ExpressionDependent | undefined;
153
+ /**
154
+ * How an error should spell `table` when the object being dropped lives in `homeSchemaName`:
155
+ * bare when the two share a schema, schema-qualified when they do not — the same rule the
156
+ * rest of the engine's messages follow, and the only way a cross-schema refusal names a
157
+ * table the user can actually find.
158
+ */
159
+ export declare function describeDependentTable(table: TableSchema, homeSchemaName: string): string;
160
+ //# sourceMappingURL=expression-dependents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expression-dependents.d.ts","sourceRoot":"","sources":["../../../src/schema/expression-dependents.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAuB,MAAM,YAAY,CAAC;AAanE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4EG;AAEH,2EAA2E;AAC3E,MAAM,WAAW,mBAAmB;IACnC,yCAAyC;IACzC,KAAK,EAAE,WAAW,CAAC;IACnB,uFAAuF;IACvF,QAAQ,EAAE,OAAO,CAAC;IAClB,4FAA4F;IAC5F,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5B;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,MAAM,mBAAmB;AAC9B,oCAAoC;AAClC,OAAO;AACT,4DAA4D;GAC1D,kBAAkB,CAAC;AAEtB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,6BAA6B,CAC5C,EAAE,EAAE,QAAQ,EACZ,WAAW,EAAE,WAAW,EACxB,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,mBAAmB,GACtB,mBAAmB,GAAG,SAAS,CAoBjC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,4BAA4B,CAC3C,EAAE,EAAE,QAAQ,EACZ,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GAChB,mBAAmB,GAAG,SAAS,CAgBjC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAIzF"}
@@ -0,0 +1,228 @@
1
+ import { expressionToString } from '../emit/ast-stringify.js';
2
+ import { columnReferencedInAst, columnReferencedInCheckExpression, objectRefKey, } from './rename-rewriter.js';
3
+ import { buildColumnSourceResolver } from './column-source-resolver.js';
4
+ import { snapshotObjectRefResolvers } from './object-ref-resolver.js';
5
+ import { reachableObjects } from './object-dependency-closure.js';
6
+ import { collectColumnRepublication } from './column-republication.js';
7
+ /**
8
+ * The FIRST table in ANY schema whose `arm` expressions name
9
+ * `<tableSchema.schemaName>.<tableSchema.name>.<columnName>`, or `undefined` when none
10
+ * does. The probed table itself is scanned first, so a self-reference is always the one
11
+ * reported and the guards' own-table messages never change spelling because an unrelated
12
+ * schema happens to sort earlier.
13
+ *
14
+ * Only the first hit is returned: every caller is a guard that throws on it, and stopping
15
+ * early keeps the walk off the remaining schemas.
16
+ *
17
+ * Two expressions are skipped on the probed table itself, both deliberately:
18
+ *
19
+ * - The dropped column's **own** DEFAULT / generated body — it goes away with the column,
20
+ * so a self-naming default (`a integer default (new.a)`) is not something the drop
21
+ * orphans.
22
+ * - **Every** own-table generated body — `runDropColumn` already refuses off
23
+ * `generatedColumnDependencies`, the resolved column-index map
24
+ * `extractGeneratedColumnDependencies` builds, and reporting it twice would only change
25
+ * which of two messages the user sees. A generated body on ANOTHER table is not covered
26
+ * by that map and IS reported here.
27
+ */
28
+ export function findColumnExpressionDependent(db, tableSchema, columnName, arm) {
29
+ const resolvers = snapshotObjectRefResolvers(db);
30
+ const resolveColumnInSource = buildColumnSourceResolver(db);
31
+ const targetKey = objectRefKey(tableSchema.schemaName, tableSchema.name);
32
+ // One republication fixpoint per drop (seed first), shared by every probe below:
33
+ // a view republishing the column by a star (`select * from t`) is a target its
34
+ // readers reference the column THROUGH, without any body spelling the name.
35
+ const republication = collectColumnRepublication(db, { targetKey, tableName: tableSchema.name }, columnName, resolvers, resolveColumnInSource);
36
+ for (const table of tablesProbedTargetFirst(db, targetKey)) {
37
+ const ownTable = objectRefKey(table.schemaName, table.name) === targetKey;
38
+ const names = columnProbe(db, resolvers, table.schemaName, ownTable, republication, columnName, resolveColumnInSource);
39
+ const found = arm === 'check'
40
+ ? findInChecks(table, names)
41
+ : findInColumnExpressions(table, ownTable, columnName, names);
42
+ if (found)
43
+ return { table, ownTable, ...found };
44
+ }
45
+ return undefined;
46
+ }
47
+ /**
48
+ * The FIRST table in ANY schema whose CHECK / DEFAULT / `GENERATED ALWAYS AS` expressions
49
+ * name `<schemaName>.<objectName>`, or `undefined` when none does.
50
+ *
51
+ * The dropped object itself is skipped: its own CHECKs naming itself vanish with it, so
52
+ * refusing on them would make every self-referencing table undroppable. (The column verb
53
+ * keeps its target in the walk — a column drop leaves the rest of the table behind.)
54
+ *
55
+ * All three arms run with the walker's `rowImageContext` on the ROOT expression, exactly as
56
+ * `renameTableInCheckConstraints` / `renameTableInColumnExpressions` do: these
57
+ * expressions evaluate against a written row, so a bare `new.` / `old.` qualifier names
58
+ * that row image rather than a table literally called `new`.
59
+ *
60
+ * The match is `namerOf` over the expression's whole reach, so a CHECK that reads a view
61
+ * whose body reads the dropped object matches too, and `path` carries the shortest chain
62
+ * for the error to quote — empty exactly when the expression names the object itself.
63
+ */
64
+ export function findTableExpressionDependent(db, schemaName, objectName) {
65
+ const resolvers = snapshotObjectRefResolvers(db);
66
+ const targetKey = objectRefKey(schemaName, objectName);
67
+ for (const table of tablesProbedTargetFirst(db, targetKey)) {
68
+ if (objectRefKey(table.schemaName, table.name) === targetKey)
69
+ continue;
70
+ const names = expr => {
71
+ if (expr === undefined)
72
+ return undefined;
73
+ const path = reachableObjects(db, expr, table.schemaName, resolvers, { rowImageContext: true })
74
+ .namerOf(targetKey)?.path;
75
+ return path === undefined ? undefined : { path };
76
+ };
77
+ const found = findInChecks(table, names) ?? findInColumnExpressions(table, false, undefined, names);
78
+ if (found)
79
+ return { table, ownTable: false, ...found };
80
+ }
81
+ return undefined;
82
+ }
83
+ /**
84
+ * How an error should spell `table` when the object being dropped lives in `homeSchemaName`:
85
+ * bare when the two share a schema, schema-qualified when they do not — the same rule the
86
+ * rest of the engine's messages follow, and the only way a cross-schema refusal names a
87
+ * table the user can actually find.
88
+ */
89
+ export function describeDependentTable(table, homeSchemaName) {
90
+ return table.schemaName.toLowerCase() === homeSchemaName.toLowerCase()
91
+ ? `'${table.name}'`
92
+ : `'${table.schemaName}.${table.name}'`;
93
+ }
94
+ /**
95
+ * Every table in every schema, with the probed table (if it exists) first.
96
+ *
97
+ * Order is not cosmetic: the guards report the FIRST hit, and the own-table messages are
98
+ * the ones users and tests already know. Scanning the target first keeps a self-reference
99
+ * winning over an unrelated schema's.
100
+ *
101
+ * NOTE: past the probed table the order is `_getAllSchemas()` × `getAllTables()` insertion
102
+ * order, so with TWO referencing tables which one the refusal names follows catalog
103
+ * insertion rather than any user-visible rule. Harmless while the message is advisory —
104
+ * every referencing table has to be dealt with anyway. If a caller ever needs to *list*
105
+ * dependents (a `CASCADE` arm, an introspection function), give it a collect-all entry
106
+ * point with a defined order rather than calling this in a loop.
107
+ */
108
+ function* tablesProbedTargetFirst(db, targetKey) {
109
+ const rest = [];
110
+ for (const schema of db.schemaManager._getAllSchemas()) {
111
+ for (const table of schema.getAllTables()) {
112
+ if (objectRefKey(table.schemaName, table.name) === targetKey)
113
+ yield table;
114
+ else
115
+ rest.push(table);
116
+ }
117
+ }
118
+ yield* rest;
119
+ }
120
+ /**
121
+ * The column probe for one scanned table — seeded on the probed table itself, unseeded
122
+ * everywhere else. See this module's header for why that split is load-bearing.
123
+ *
124
+ * The column question is not "does the reach CONTAIN this key?" (which is all the table
125
+ * verb needs) but "does any body in the reach NAME this column?", so this loops the reach's
126
+ * bodies the way `assertNoAssertionNamesColumn` already does, each under its own resolver.
127
+ * `homeSchemaName` is the SCANNED table's schema — the root expression's own — because that
128
+ * is what its unqualified names resolve against.
129
+ *
130
+ * Each body is probed against EVERY republication target, not the base table alone: a
131
+ * reference through `create view v as select * from t` spells the column against `v`, and
132
+ * only the target sweep sees it. Targets are swept OUTER, bodies inner, base table first —
133
+ * so every match the base-table sweep finds is found at the body it always was, and the
134
+ * existing message spellings (`reaches it through view 'v'`) do not move; the widened
135
+ * targets only ever ADD refusals.
136
+ *
137
+ * After the target sweep, the broken-listed arm: a view / MV with an explicit column list
138
+ * over a `*` covering the column breaks OUTRIGHT on the drop (the star's arity changes),
139
+ * so an expression whose reach names such an object at all refuses, marked
140
+ * {@link ProbeMatch.breaksEntirely} so the guard can phrase it honestly.
141
+ */
142
+ function columnProbe(db, resolvers, homeSchemaName, ownTable, republication, columnName, resolveColumnInSource) {
143
+ return expr => {
144
+ if (!expr)
145
+ return undefined;
146
+ const reach = reachableObjects(db, expr, homeSchemaName, resolvers, { rowImageContext: true });
147
+ for (const [targetIndex, target] of republication.targets.entries()) {
148
+ for (const reached of reach.bodies) {
149
+ // Seeded ONLY on the probed table's own ROOT body, probing the BASE target: a
150
+ // CHECK / DEFAULT there is written against the row being written, so an
151
+ // unqualified name binds the owning table implicitly. A view body below it is
152
+ // a relation with no such seed, the root body of ANOTHER table's expression
153
+ // binds that table's row, not ours — and no expression ever binds a VIEW
154
+ // target implicitly, so a republication target takes the unseeded probe even
155
+ // at the root (a reference to it can only sit inside a subquery FROM).
156
+ const seeded = targetIndex === 0 && ownTable && reached.ownerKey === undefined;
157
+ // Row-image mode, the one non-constant site: a ROOT body is a table's CHECK /
158
+ // DEFAULT / generated expression and therefore always written-row context —
159
+ // `'own'` only for the seeded base-target case, `'foreign'` otherwise (another
160
+ // table's root body binds that table's image; a republication target at the
161
+ // root still binds the OWNING table's image, not the view being probed).
162
+ // Anything REACHED below the root is a view / MV body — a relation with no
163
+ // written row — so `'none'`.
164
+ const rowImage = reached.ownerKey === undefined ? (seeded ? 'own' : 'foreign') : 'none';
165
+ const hit = seeded
166
+ ? columnReferencedInCheckExpression(reached.body, target.tableName, columnName, reached.resolve, target.targetKey, rowImage, resolveColumnInSource)
167
+ : columnReferencedInAst(reached.body, target.tableName, columnName, reached.resolve, target.targetKey, rowImage, resolveColumnInSource);
168
+ if (hit)
169
+ return { path: reached.path };
170
+ }
171
+ }
172
+ for (const broken of republication.brokenListed) {
173
+ const namer = reach.namerOf(broken.key);
174
+ if (namer)
175
+ return { path: namer.path, breaksEntirely: broken.describe };
176
+ }
177
+ return undefined;
178
+ };
179
+ }
180
+ /** The first CHECK constraint of `table` the probe matches, described for an error. */
181
+ function findInChecks(table, names) {
182
+ for (const check of table.checkConstraints ?? []) {
183
+ // `!== undefined`, not truthiness: a match with an EMPTY path is a direct match.
184
+ const match = names(check.expr);
185
+ if (match !== undefined)
186
+ return { describe: describeCheck(check), ...match };
187
+ }
188
+ return undefined;
189
+ }
190
+ /**
191
+ * The first column DEFAULT / generated body of `table` the probe matches, described for
192
+ * an error. `skipColumnName` is the column being dropped, skipped only on the probed
193
+ * table itself; own-table generated bodies are skipped outright (see
194
+ * {@link findColumnExpressionDependent}).
195
+ */
196
+ function findInColumnExpressions(table, ownTable, skipColumnName, names) {
197
+ const lowerSkip = ownTable ? skipColumnName?.toLowerCase() : undefined;
198
+ for (const col of table.columns) {
199
+ if (lowerSkip !== undefined && col.name.toLowerCase() === lowerSkip)
200
+ continue;
201
+ // `!== undefined` for the same reason as in {@link findInChecks}: an empty-path
202
+ // match is a direct hit.
203
+ const defaultMatch = names(col.defaultValue ?? undefined);
204
+ if (defaultMatch !== undefined) {
205
+ return { describe: `the DEFAULT of column '${col.name}'`, ...defaultMatch };
206
+ }
207
+ if (ownTable)
208
+ continue;
209
+ const generatedMatch = names(col.generatedExpr);
210
+ if (generatedMatch !== undefined) {
211
+ return { describe: `the GENERATED expression of column '${col.name}'`, ...generatedMatch };
212
+ }
213
+ }
214
+ return undefined;
215
+ }
216
+ /**
217
+ * A table-level unnamed CHECK genuinely carries `name: undefined` — the `_check_<table>`
218
+ * spelling `manager.ts` produces is error text, not stored identity — so there is no name
219
+ * to quote and the expression stands in for one. That is also the only handle the user
220
+ * has on it: `DROP CONSTRAINT` resolves by name only, so an unnamed CHECK can only be
221
+ * removed by rebuilding its table.
222
+ */
223
+ function describeCheck(check) {
224
+ return check.name
225
+ ? `CHECK constraint '${check.name}'`
226
+ : `the CHECK constraint (${expressionToString(check.expr)})`;
227
+ }
228
+ //# sourceMappingURL=expression-dependents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expression-dependents.js","sourceRoot":"","sources":["../../../src/schema/expression-dependents.ts"],"names":[],"mappings":"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"}