joist-core 2.3.0-next.97 → 2.3.0-next.99

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 (747) hide show
  1. package/build/BaseEntity.cjs.map +1 -1
  2. package/build/BaseEntity.js.map +1 -1
  3. package/build/Entity.cjs.map +1 -1
  4. package/build/Entity.js.map +1 -1
  5. package/build/EntityManager.cjs +45 -46
  6. package/build/EntityManager.cjs.map +1 -1
  7. package/build/EntityManager.d.cts +7 -7
  8. package/build/EntityManager.d.cts.map +1 -1
  9. package/build/EntityManager.d.mts +7 -7
  10. package/build/EntityManager.d.mts.map +1 -1
  11. package/build/EntityManager.js +27 -28
  12. package/build/EntityManager.js.map +1 -1
  13. package/build/EntityMetadata.cjs +0 -2
  14. package/build/EntityMetadata.cjs.map +1 -1
  15. package/build/EntityMetadata.d.cts +3 -3
  16. package/build/EntityMetadata.d.mts +3 -3
  17. package/build/EntityMetadata.js +0 -2
  18. package/build/EntityMetadata.js.map +1 -1
  19. package/build/IndexManager.cjs +1 -1
  20. package/build/IndexManager.cjs.map +1 -1
  21. package/build/IndexManager.js +1 -1
  22. package/build/IndexManager.js.map +1 -1
  23. package/build/InstanceData.cjs.map +1 -1
  24. package/build/InstanceData.js.map +1 -1
  25. package/build/PluginManager.cjs +0 -1
  26. package/build/PluginManager.cjs.map +1 -1
  27. package/build/PluginManager.d.cts +1 -1
  28. package/build/PluginManager.d.mts +1 -1
  29. package/build/PluginManager.js +0 -1
  30. package/build/PluginManager.js.map +1 -1
  31. package/build/batchloaders/enumCollectionBatchLoader.cjs +1 -1
  32. package/build/batchloaders/enumCollectionBatchLoader.cjs.map +1 -1
  33. package/build/batchloaders/enumCollectionBatchLoader.d.cts +1 -1
  34. package/build/batchloaders/enumCollectionBatchLoader.d.mts +1 -1
  35. package/build/batchloaders/enumCollectionBatchLoader.js +1 -1
  36. package/build/batchloaders/enumCollectionBatchLoader.js.map +1 -1
  37. package/build/batchloaders/loadBatchLoader.cjs +3 -4
  38. package/build/batchloaders/loadBatchLoader.cjs.map +1 -1
  39. package/build/batchloaders/loadBatchLoader.d.cts +1 -1
  40. package/build/batchloaders/loadBatchLoader.d.mts +1 -1
  41. package/build/batchloaders/loadBatchLoader.js +2 -3
  42. package/build/batchloaders/loadBatchLoader.js.map +1 -1
  43. package/build/batchloaders/manyToManyBatchLoader.cjs +1 -1
  44. package/build/batchloaders/manyToManyBatchLoader.cjs.map +1 -1
  45. package/build/batchloaders/manyToManyBatchLoader.d.cts +1 -1
  46. package/build/batchloaders/manyToManyBatchLoader.d.mts +1 -1
  47. package/build/batchloaders/manyToManyBatchLoader.js +1 -1
  48. package/build/batchloaders/manyToManyBatchLoader.js.map +1 -1
  49. package/build/batchloaders/oneToManyBatchLoader.cjs +1 -1
  50. package/build/batchloaders/oneToManyBatchLoader.cjs.map +1 -1
  51. package/build/batchloaders/oneToManyBatchLoader.js +1 -1
  52. package/build/batchloaders/oneToManyBatchLoader.js.map +1 -1
  53. package/build/batchloaders/oneToOneBatchLoader.cjs +1 -1
  54. package/build/batchloaders/oneToOneBatchLoader.cjs.map +1 -1
  55. package/build/batchloaders/oneToOneBatchLoader.js +1 -1
  56. package/build/batchloaders/oneToOneBatchLoader.js.map +1 -1
  57. package/build/batchloaders/populateBatchLoader.cjs +11 -12
  58. package/build/batchloaders/populateBatchLoader.cjs.map +1 -1
  59. package/build/batchloaders/populateBatchLoader.d.cts +1 -1
  60. package/build/batchloaders/populateBatchLoader.d.mts +1 -1
  61. package/build/batchloaders/populateBatchLoader.js +7 -8
  62. package/build/batchloaders/populateBatchLoader.js.map +1 -1
  63. package/build/batchloaders/recursiveChildrenBatchLoader.cjs +2 -2
  64. package/build/batchloaders/recursiveChildrenBatchLoader.cjs.map +1 -1
  65. package/build/batchloaders/recursiveChildrenBatchLoader.js +2 -2
  66. package/build/batchloaders/recursiveChildrenBatchLoader.js.map +1 -1
  67. package/build/batchloaders/recursiveM2mBatchLoader.cjs +2 -2
  68. package/build/batchloaders/recursiveM2mBatchLoader.cjs.map +1 -1
  69. package/build/batchloaders/recursiveM2mBatchLoader.js +2 -2
  70. package/build/batchloaders/recursiveM2mBatchLoader.js.map +1 -1
  71. package/build/batchloaders/recursiveParentsBatchLoader.cjs +2 -2
  72. package/build/batchloaders/recursiveParentsBatchLoader.cjs.map +1 -1
  73. package/build/batchloaders/recursiveParentsBatchLoader.js +2 -2
  74. package/build/batchloaders/recursiveParentsBatchLoader.js.map +1 -1
  75. package/build/changes.cjs +2 -3
  76. package/build/changes.cjs.map +1 -1
  77. package/build/changes.js +2 -3
  78. package/build/changes.js.map +1 -1
  79. package/build/config.cjs +3 -3
  80. package/build/config.cjs.map +1 -1
  81. package/build/config.d.cts +2 -2
  82. package/build/config.d.mts +2 -2
  83. package/build/config.js +1 -1
  84. package/build/config.js.map +1 -1
  85. package/build/configure.cjs +10 -10
  86. package/build/configure.cjs.map +1 -1
  87. package/build/configure.js +5 -5
  88. package/build/configure.js.map +1 -1
  89. package/build/dataloaders/fastWhereFilterHash.cjs +8 -8
  90. package/build/dataloaders/fastWhereFilterHash.cjs.map +1 -1
  91. package/build/dataloaders/fastWhereFilterHash.d.cts.map +1 -1
  92. package/build/dataloaders/fastWhereFilterHash.d.mts.map +1 -1
  93. package/build/dataloaders/fastWhereFilterHash.js +3 -3
  94. package/build/dataloaders/fastWhereFilterHash.js.map +1 -1
  95. package/build/dataloaders/findByUniqueDataLoader.cjs.map +1 -1
  96. package/build/dataloaders/findByUniqueDataLoader.d.cts.map +1 -1
  97. package/build/dataloaders/findByUniqueDataLoader.d.mts.map +1 -1
  98. package/build/dataloaders/findByUniqueDataLoader.js.map +1 -1
  99. package/build/dataloaders/findCountDataLoader.cjs +2 -2
  100. package/build/dataloaders/findCountDataLoader.cjs.map +1 -1
  101. package/build/dataloaders/findCountDataLoader.js +1 -1
  102. package/build/dataloaders/findCountDataLoader.js.map +1 -1
  103. package/build/dataloaders/findDataLoader.cjs +6 -6
  104. package/build/dataloaders/findDataLoader.cjs.map +1 -1
  105. package/build/dataloaders/findDataLoader.d.cts +1 -1
  106. package/build/dataloaders/findDataLoader.d.mts +1 -1
  107. package/build/dataloaders/findDataLoader.js +3 -3
  108. package/build/dataloaders/findDataLoader.js.map +1 -1
  109. package/build/dataloaders/findIdsDataLoader.cjs +3 -3
  110. package/build/dataloaders/findIdsDataLoader.cjs.map +1 -1
  111. package/build/dataloaders/findIdsDataLoader.js +2 -2
  112. package/build/dataloaders/findIdsDataLoader.js.map +1 -1
  113. package/build/dataloaders/findOrCreateDataLoader.cjs +1 -1
  114. package/build/dataloaders/findOrCreateDataLoader.cjs.map +1 -1
  115. package/build/dataloaders/findOrCreateDataLoader.d.cts.map +1 -1
  116. package/build/dataloaders/findOrCreateDataLoader.d.mts.map +1 -1
  117. package/build/dataloaders/findOrCreateDataLoader.js +1 -1
  118. package/build/dataloaders/findOrCreateDataLoader.js.map +1 -1
  119. package/build/dataloaders/findPaginatedDataLoader.cjs +6 -6
  120. package/build/dataloaders/findPaginatedDataLoader.cjs.map +1 -1
  121. package/build/dataloaders/findPaginatedDataLoader.d.cts +1 -1
  122. package/build/dataloaders/findPaginatedDataLoader.d.mts +1 -1
  123. package/build/dataloaders/findPaginatedDataLoader.js +3 -3
  124. package/build/dataloaders/findPaginatedDataLoader.js.map +1 -1
  125. package/build/dataloaders/lensDataLoader.cjs +3 -3
  126. package/build/dataloaders/lensDataLoader.cjs.map +1 -1
  127. package/build/dataloaders/lensDataLoader.d.cts.map +1 -1
  128. package/build/dataloaders/lensDataLoader.d.mts.map +1 -1
  129. package/build/dataloaders/lensDataLoader.js +2 -2
  130. package/build/dataloaders/lensDataLoader.js.map +1 -1
  131. package/build/dataloaders/manyToManyFindDataLoader.cjs +1 -1
  132. package/build/dataloaders/manyToManyFindDataLoader.cjs.map +1 -1
  133. package/build/dataloaders/manyToManyFindDataLoader.d.cts.map +1 -1
  134. package/build/dataloaders/manyToManyFindDataLoader.d.mts.map +1 -1
  135. package/build/dataloaders/manyToManyFindDataLoader.js +1 -1
  136. package/build/dataloaders/manyToManyFindDataLoader.js.map +1 -1
  137. package/build/dataloaders/oneToManyFindDataLoader.cjs +1 -1
  138. package/build/dataloaders/oneToManyFindDataLoader.cjs.map +1 -1
  139. package/build/dataloaders/oneToManyFindDataLoader.d.cts.map +1 -1
  140. package/build/dataloaders/oneToManyFindDataLoader.d.mts.map +1 -1
  141. package/build/dataloaders/oneToManyFindDataLoader.js +1 -1
  142. package/build/dataloaders/oneToManyFindDataLoader.js.map +1 -1
  143. package/build/defaults.cjs +5 -5
  144. package/build/defaults.cjs.map +1 -1
  145. package/build/defaults.d.cts +1 -1
  146. package/build/defaults.d.cts.map +1 -1
  147. package/build/defaults.d.mts +1 -1
  148. package/build/defaults.d.mts.map +1 -1
  149. package/build/defaults.js +4 -4
  150. package/build/defaults.js.map +1 -1
  151. package/build/drivers/Driver.cjs +0 -1
  152. package/build/drivers/Driver.d.cts +1 -1
  153. package/build/drivers/Driver.d.mts +1 -1
  154. package/build/drivers/Driver.js +0 -1
  155. package/build/drivers/EntityWriter.cjs +6 -7
  156. package/build/drivers/EntityWriter.cjs.map +1 -1
  157. package/build/drivers/EntityWriter.d.cts +1 -1
  158. package/build/drivers/EntityWriter.d.mts +1 -1
  159. package/build/drivers/EntityWriter.js +2 -3
  160. package/build/drivers/EntityWriter.js.map +1 -1
  161. package/build/drivers/IdAssigner.cjs +0 -1
  162. package/build/drivers/IdAssigner.cjs.map +1 -1
  163. package/build/drivers/IdAssigner.d.cts +1 -1
  164. package/build/drivers/IdAssigner.d.mts +1 -1
  165. package/build/drivers/IdAssigner.js +0 -1
  166. package/build/drivers/IdAssigner.js.map +1 -1
  167. package/build/drivers/driverApi.cjs +19 -0
  168. package/build/drivers/driverApi.cjs.map +1 -0
  169. package/build/drivers/driverApi.d.cts +22 -0
  170. package/build/drivers/driverApi.d.cts.map +1 -0
  171. package/build/drivers/driverApi.d.mts +22 -0
  172. package/build/drivers/driverApi.d.mts.map +1 -0
  173. package/build/drivers/driverApi.js +18 -0
  174. package/build/drivers/driverApi.js.map +1 -0
  175. package/build/fields.cjs +3 -3
  176. package/build/fields.cjs.map +1 -1
  177. package/build/fields.js +2 -2
  178. package/build/fields.js.map +1 -1
  179. package/build/{FlushLock.cjs → flush/FlushLock.cjs} +1 -1
  180. package/build/flush/FlushLock.cjs.map +1 -0
  181. package/build/{FlushLock.d.cts → flush/FlushLock.d.cts} +1 -1
  182. package/build/flush/FlushLock.d.cts.map +1 -0
  183. package/build/{FlushLock.d.mts → flush/FlushLock.d.mts} +1 -1
  184. package/build/flush/FlushLock.d.mts.map +1 -0
  185. package/build/{FlushLock.js → flush/FlushLock.js} +1 -1
  186. package/build/flush/FlushLock.js.map +1 -0
  187. package/build/{JoinRows.cjs → flush/JoinRows.cjs} +5 -8
  188. package/build/flush/JoinRows.cjs.map +1 -0
  189. package/build/{JoinRows.d.cts → flush/JoinRows.d.cts} +5 -5
  190. package/build/flush/JoinRows.d.cts.map +1 -0
  191. package/build/{JoinRows.d.mts → flush/JoinRows.d.mts} +5 -5
  192. package/build/flush/JoinRows.d.mts.map +1 -0
  193. package/build/{JoinRows.js → flush/JoinRows.js} +5 -8
  194. package/build/flush/JoinRows.js.map +1 -0
  195. package/build/{PendingChanges.cjs → flush/PendingChanges.cjs} +0 -1
  196. package/build/{PendingChanges.d.cts → flush/PendingChanges.d.cts} +2 -2
  197. package/build/flush/PendingChanges.d.cts.map +1 -0
  198. package/build/{PendingChanges.d.mts → flush/PendingChanges.d.mts} +2 -2
  199. package/build/flush/PendingChanges.d.mts.map +1 -0
  200. package/build/flush/PendingChanges.js +1 -0
  201. package/build/{Todo.cjs → flush/Todo.cjs} +4 -6
  202. package/build/flush/Todo.cjs.map +1 -0
  203. package/build/{Todo.d.cts → flush/Todo.d.cts} +3 -3
  204. package/build/flush/Todo.d.cts.map +1 -0
  205. package/build/{Todo.d.mts → flush/Todo.d.mts} +3 -3
  206. package/build/flush/Todo.d.mts.map +1 -0
  207. package/build/{Todo.js → flush/Todo.js} +4 -6
  208. package/build/flush/Todo.js.map +1 -0
  209. package/build/getProperties.cjs.map +1 -1
  210. package/build/getProperties.js.map +1 -1
  211. package/build/index.cjs +100 -100
  212. package/build/index.cjs.map +1 -1
  213. package/build/index.d.cts +15 -15
  214. package/build/index.d.mts +15 -15
  215. package/build/index.js +42 -42
  216. package/build/index.js.map +1 -1
  217. package/build/json.cjs +4 -4
  218. package/build/json.cjs.map +1 -1
  219. package/build/json.js +3 -3
  220. package/build/json.js.map +1 -1
  221. package/build/keys.cjs +1 -1
  222. package/build/keys.cjs.map +1 -1
  223. package/build/keys.js +1 -1
  224. package/build/keys.js.map +1 -1
  225. package/build/{HintTree.cjs → loading/HintTree.cjs} +2 -5
  226. package/build/loading/HintTree.cjs.map +1 -0
  227. package/build/{HintTree.d.cts → loading/HintTree.d.cts} +3 -3
  228. package/build/loading/HintTree.d.cts.map +1 -0
  229. package/build/{HintTree.d.mts → loading/HintTree.d.mts} +3 -3
  230. package/build/loading/HintTree.d.mts.map +1 -0
  231. package/build/{HintTree.js → loading/HintTree.js} +2 -5
  232. package/build/loading/HintTree.js.map +1 -0
  233. package/build/{IsLoadedCache.cjs → loading/IsLoadedCache.cjs} +2 -3
  234. package/build/loading/IsLoadedCache.cjs.map +1 -0
  235. package/build/{IsLoadedCache.d.cts → loading/IsLoadedCache.d.cts} +2 -2
  236. package/build/loading/IsLoadedCache.d.cts.map +1 -0
  237. package/build/{IsLoadedCache.d.mts → loading/IsLoadedCache.d.mts} +2 -2
  238. package/build/loading/IsLoadedCache.d.mts.map +1 -0
  239. package/build/{IsLoadedCache.js → loading/IsLoadedCache.js} +2 -3
  240. package/build/{IsLoadedCache.cjs.map → loading/IsLoadedCache.js.map} +1 -1
  241. package/build/{loadHints.cjs → loading/loadHints.cjs} +6 -11
  242. package/build/loading/loadHints.cjs.map +1 -0
  243. package/build/{loadHints.d.cts → loading/loadHints.d.cts} +14 -14
  244. package/build/loading/loadHints.d.cts.map +1 -0
  245. package/build/{loadHints.d.mts → loading/loadHints.d.mts} +14 -14
  246. package/build/loading/loadHints.d.mts.map +1 -0
  247. package/build/{loadHints.js → loading/loadHints.js} +3 -8
  248. package/build/loading/loadHints.js.map +1 -0
  249. package/build/{loadLens.cjs → loading/loadLens.cjs} +8 -9
  250. package/build/loading/loadLens.cjs.map +1 -0
  251. package/build/{loadLens.d.cts → loading/loadLens.d.cts} +3 -3
  252. package/build/loading/loadLens.d.cts.map +1 -0
  253. package/build/{loadLens.d.mts → loading/loadLens.d.mts} +3 -3
  254. package/build/loading/loadLens.d.mts.map +1 -0
  255. package/build/{loadLens.js → loading/loadLens.js} +8 -9
  256. package/build/loading/loadLens.js.map +1 -0
  257. package/build/{withLoaded.cjs → loading/withLoaded.cjs} +12 -13
  258. package/build/loading/withLoaded.cjs.map +1 -0
  259. package/build/{withLoaded.d.cts → loading/withLoaded.d.cts} +9 -9
  260. package/build/loading/withLoaded.d.cts.map +1 -0
  261. package/build/{withLoaded.d.mts → loading/withLoaded.d.mts} +9 -9
  262. package/build/loading/withLoaded.d.mts.map +1 -0
  263. package/build/{withLoaded.js → loading/withLoaded.js} +10 -11
  264. package/build/loading/withLoaded.js.map +1 -0
  265. package/build/logging/FactoryLogger.cjs.map +1 -1
  266. package/build/logging/FactoryLogger.d.cts.map +1 -1
  267. package/build/logging/FactoryLogger.d.mts.map +1 -1
  268. package/build/logging/FactoryLogger.js.map +1 -1
  269. package/build/logging/FieldLogger.cjs.map +1 -1
  270. package/build/logging/FieldLogger.d.cts.map +1 -1
  271. package/build/logging/FieldLogger.d.mts.map +1 -1
  272. package/build/logging/FieldLogger.js.map +1 -1
  273. package/build/logging/ReactionLogger.cjs +0 -2
  274. package/build/logging/ReactionLogger.cjs.map +1 -1
  275. package/build/logging/ReactionLogger.d.cts +2 -2
  276. package/build/logging/ReactionLogger.d.cts.map +1 -1
  277. package/build/logging/ReactionLogger.d.mts +2 -2
  278. package/build/logging/ReactionLogger.d.mts.map +1 -1
  279. package/build/logging/ReactionLogger.js +0 -2
  280. package/build/logging/ReactionLogger.js.map +1 -1
  281. package/build/newEntity.cjs.map +1 -1
  282. package/build/newEntity.js.map +1 -1
  283. package/build/newTestInstance.cjs +3 -3
  284. package/build/newTestInstance.cjs.map +1 -1
  285. package/build/newTestInstance.d.cts +1 -1
  286. package/build/newTestInstance.d.cts.map +1 -1
  287. package/build/newTestInstance.d.mts +1 -1
  288. package/build/newTestInstance.d.mts.map +1 -1
  289. package/build/newTestInstance.js +2 -2
  290. package/build/newTestInstance.js.map +1 -1
  291. package/build/normalizeHints.cjs +0 -2
  292. package/build/normalizeHints.cjs.map +1 -1
  293. package/build/normalizeHints.d.cts +2 -2
  294. package/build/normalizeHints.d.mts +2 -2
  295. package/build/normalizeHints.js +0 -2
  296. package/build/normalizeHints.js.map +1 -1
  297. package/build/nowUTC.cjs +2 -2
  298. package/build/nowUTC.cjs.map +1 -1
  299. package/build/nowUTC.d.cts +1 -1
  300. package/build/nowUTC.d.mts +1 -1
  301. package/build/nowUTC.js +1 -1
  302. package/build/nowUTC.js.map +1 -1
  303. package/build/plugins/ImmutableEntitiesPlugin.cjs.map +1 -1
  304. package/build/plugins/ImmutableEntitiesPlugin.js.map +1 -1
  305. package/build/plugins/PreloadPlugin.cjs +0 -2
  306. package/build/plugins/PreloadPlugin.d.cts +2 -2
  307. package/build/plugins/PreloadPlugin.d.mts +2 -2
  308. package/build/plugins/PreloadPlugin.js +0 -2
  309. package/build/preloading/JsonAggregatePreloader.cjs +1 -4
  310. package/build/preloading/JsonAggregatePreloader.cjs.map +1 -1
  311. package/build/preloading/JsonAggregatePreloader.d.cts +2 -2
  312. package/build/preloading/JsonAggregatePreloader.d.cts.map +1 -1
  313. package/build/preloading/JsonAggregatePreloader.d.mts +2 -2
  314. package/build/preloading/JsonAggregatePreloader.d.mts.map +1 -1
  315. package/build/preloading/JsonAggregatePreloader.js +1 -4
  316. package/build/preloading/JsonAggregatePreloader.js.map +1 -1
  317. package/build/preloading/canPreload.cjs.map +1 -1
  318. package/build/preloading/canPreload.js.map +1 -1
  319. package/build/preloading/partitionHint.cjs +2 -3
  320. package/build/preloading/partitionHint.cjs.map +1 -1
  321. package/build/preloading/partitionHint.d.cts +1 -1
  322. package/build/preloading/partitionHint.d.mts +1 -1
  323. package/build/preloading/partitionHint.js +2 -3
  324. package/build/preloading/partitionHint.js.map +1 -1
  325. package/build/queries/ConditionBuilder.cjs.map +1 -1
  326. package/build/queries/ConditionBuilder.d.cts +1 -1
  327. package/build/queries/ConditionBuilder.d.mts +1 -1
  328. package/build/queries/ConditionBuilder.js.map +1 -1
  329. package/build/queries/conditions.cjs.map +1 -1
  330. package/build/queries/conditions.js.map +1 -1
  331. package/build/queries/entityQueryUtils.cjs.map +1 -1
  332. package/build/queries/entityQueryUtils.js.map +1 -1
  333. package/build/queries/find/Aliases.cjs +1 -1
  334. package/build/queries/find/Aliases.cjs.map +1 -1
  335. package/build/queries/find/Aliases.d.cts.map +1 -1
  336. package/build/queries/find/Aliases.d.mts.map +1 -1
  337. package/build/queries/find/Aliases.js +1 -1
  338. package/build/queries/find/Aliases.js.map +1 -1
  339. package/build/queries/find/DeferredAlias.cjs.map +1 -1
  340. package/build/queries/find/DeferredAlias.js.map +1 -1
  341. package/build/queries/find/EntityFilter.cjs.map +1 -1
  342. package/build/queries/find/EntityFilter.js.map +1 -1
  343. package/build/queries/find/EntityGraphQLFilter.cjs.map +1 -1
  344. package/build/queries/find/EntityGraphQLFilter.js.map +1 -1
  345. package/build/queries/find/QueryParser.cjs +2 -2
  346. package/build/queries/find/QueryParser.cjs.map +1 -1
  347. package/build/queries/find/QueryParser.collectionJoins.cjs.map +1 -1
  348. package/build/queries/find/QueryParser.collectionJoins.js.map +1 -1
  349. package/build/queries/find/QueryParser.d.cts.map +1 -1
  350. package/build/queries/find/QueryParser.d.mts.map +1 -1
  351. package/build/queries/find/QueryParser.js +2 -2
  352. package/build/queries/find/QueryParser.js.map +1 -1
  353. package/build/queries/find/QueryParser.pruning.cjs.map +1 -1
  354. package/build/queries/find/QueryParser.pruning.js.map +1 -1
  355. package/build/queries/find/QueryVisitor.cjs.map +1 -1
  356. package/build/queries/find/QueryVisitor.js.map +1 -1
  357. package/build/queries/find/buildFindQuery.cjs.map +1 -1
  358. package/build/queries/find/buildFindQuery.js.map +1 -1
  359. package/build/queries/find/scopes.cjs.map +1 -1
  360. package/build/queries/find/scopes.d.cts +1 -1
  361. package/build/queries/find/scopes.d.mts +1 -1
  362. package/build/queries/find/scopes.js.map +1 -1
  363. package/build/queries/parsedConditions.cjs.map +1 -1
  364. package/build/queries/parsedConditions.js.map +1 -1
  365. package/build/queries/renderConditions.cjs.map +1 -1
  366. package/build/queries/renderConditions.js.map +1 -1
  367. package/build/queries/skipCondition.cjs.map +1 -1
  368. package/build/queries/skipCondition.js.map +1 -1
  369. package/build/queries/sql/AliasAssigner.cjs.map +1 -1
  370. package/build/queries/sql/AliasAssigner.js.map +1 -1
  371. package/build/queries/sql/Expr.cjs +2 -2
  372. package/build/queries/sql/Expr.cjs.map +1 -1
  373. package/build/queries/sql/Expr.d.cts +1 -1
  374. package/build/queries/sql/Expr.d.mts +1 -1
  375. package/build/queries/sql/Expr.js +1 -1
  376. package/build/queries/sql/Expr.js.map +1 -1
  377. package/build/queries/sql/Tables.cjs +1 -1
  378. package/build/queries/sql/Tables.cjs.map +1 -1
  379. package/build/queries/sql/Tables.d.cts.map +1 -1
  380. package/build/queries/sql/Tables.d.mts.map +1 -1
  381. package/build/queries/sql/Tables.js +1 -1
  382. package/build/queries/sql/Tables.js.map +1 -1
  383. package/build/queries/sql/execute.cjs +1 -1
  384. package/build/queries/sql/execute.cjs.map +1 -1
  385. package/build/queries/sql/execute.js +1 -1
  386. package/build/queries/sql/execute.js.map +1 -1
  387. package/build/queries/sql/expressions/arrayAgg.cjs.map +1 -1
  388. package/build/queries/sql/expressions/arrayAgg.js.map +1 -1
  389. package/build/queries/sql/expressions/case.cjs.map +1 -1
  390. package/build/queries/sql/expressions/case.js.map +1 -1
  391. package/build/queries/sql/expressions/coalesce.cjs.map +1 -1
  392. package/build/queries/sql/expressions/coalesce.js.map +1 -1
  393. package/build/queries/sql/expressions/codecs.cjs +2 -2
  394. package/build/queries/sql/expressions/codecs.cjs.map +1 -1
  395. package/build/queries/sql/expressions/codecs.js +1 -1
  396. package/build/queries/sql/expressions/codecs.js.map +1 -1
  397. package/build/queries/sql/expressions/expression.cjs.map +1 -1
  398. package/build/queries/sql/expressions/expression.d.cts.map +1 -1
  399. package/build/queries/sql/expressions/expression.d.mts.map +1 -1
  400. package/build/queries/sql/expressions/expression.js.map +1 -1
  401. package/build/queries/sql/expressions/greatest.cjs.map +1 -1
  402. package/build/queries/sql/expressions/greatest.js.map +1 -1
  403. package/build/queries/sql/expressions/least.cjs.map +1 -1
  404. package/build/queries/sql/expressions/least.js.map +1 -1
  405. package/build/queries/sql/expressions/nullIf.cjs.map +1 -1
  406. package/build/queries/sql/expressions/nullIf.js.map +1 -1
  407. package/build/queries/sql/expressions/parseExpression.cjs.map +1 -1
  408. package/build/queries/sql/expressions/parseExpression.js.map +1 -1
  409. package/build/queries/sql/expressions/types.d.cts.map +1 -1
  410. package/build/queries/sql/expressions/types.d.mts.map +1 -1
  411. package/build/queries/sql/query.cjs +1 -1
  412. package/build/queries/sql/query.cjs.map +1 -1
  413. package/build/queries/sql/query.d.cts +1 -1
  414. package/build/queries/sql/query.d.mts +1 -1
  415. package/build/queries/sql/query.js +1 -1
  416. package/build/queries/sql/query.js.map +1 -1
  417. package/build/{unnest.cjs → queries/unnest.cjs} +1 -2
  418. package/build/queries/unnest.cjs.map +1 -0
  419. package/build/{unnest.d.cts → queries/unnest.d.cts} +3 -3
  420. package/build/queries/unnest.d.cts.map +1 -0
  421. package/build/{unnest.d.mts → queries/unnest.d.mts} +3 -3
  422. package/build/queries/unnest.d.mts.map +1 -0
  423. package/build/{unnest.js → queries/unnest.js} +1 -2
  424. package/build/queries/unnest.js.map +1 -0
  425. package/build/queries/valueFilters.cjs.map +1 -1
  426. package/build/queries/valueFilters.d.cts +1 -1
  427. package/build/queries/valueFilters.d.cts.map +1 -1
  428. package/build/queries/valueFilters.d.mts +1 -1
  429. package/build/queries/valueFilters.d.mts.map +1 -1
  430. package/build/queries/valueFilters.js.map +1 -1
  431. package/build/{ReactionsManager.cjs → reactivity/ReactionsManager.cjs} +8 -10
  432. package/build/reactivity/ReactionsManager.cjs.map +1 -0
  433. package/build/{ReactionsManager.d.cts → reactivity/ReactionsManager.d.cts} +5 -6
  434. package/build/reactivity/ReactionsManager.d.cts.map +1 -0
  435. package/build/{ReactionsManager.d.mts → reactivity/ReactionsManager.d.mts} +5 -6
  436. package/build/reactivity/ReactionsManager.d.mts.map +1 -0
  437. package/build/{ReactionsManager.js → reactivity/ReactionsManager.js} +6 -8
  438. package/build/reactivity/ReactionsManager.js.map +1 -0
  439. package/build/{reactiveHints.cjs → reactivity/reactiveHints.cjs} +12 -16
  440. package/build/reactivity/reactiveHints.cjs.map +1 -0
  441. package/build/{reactiveHints.d.cts → reactivity/reactiveHints.d.cts} +17 -17
  442. package/build/reactivity/reactiveHints.d.cts.map +1 -0
  443. package/build/{reactiveHints.d.mts → reactivity/reactiveHints.d.mts} +17 -17
  444. package/build/reactivity/reactiveHints.d.mts.map +1 -0
  445. package/build/{reactiveHints.js → reactivity/reactiveHints.js} +12 -16
  446. package/build/reactivity/reactiveHints.js.map +1 -0
  447. package/build/relations/AbstractRelationImpl.cjs.map +1 -1
  448. package/build/relations/AbstractRelationImpl.js.map +1 -1
  449. package/build/relations/AsyncProperty.cjs.map +1 -1
  450. package/build/relations/AsyncProperty.js.map +1 -1
  451. package/build/relations/AsyncReactiveField.cjs +6 -6
  452. package/build/relations/AsyncReactiveField.cjs.map +1 -1
  453. package/build/relations/AsyncReactiveField.d.cts +1 -1
  454. package/build/relations/AsyncReactiveField.d.mts +1 -1
  455. package/build/relations/AsyncReactiveField.js +4 -4
  456. package/build/relations/AsyncReactiveField.js.map +1 -1
  457. package/build/relations/Collection.cjs +1 -1
  458. package/build/relations/Collection.cjs.map +1 -1
  459. package/build/relations/Collection.js +1 -1
  460. package/build/relations/Collection.js.map +1 -1
  461. package/build/relations/CustomCollection.cjs.map +1 -1
  462. package/build/relations/CustomCollection.d.cts +1 -1
  463. package/build/relations/CustomCollection.d.mts +1 -1
  464. package/build/relations/CustomCollection.js.map +1 -1
  465. package/build/relations/CustomReference.cjs +1 -1
  466. package/build/relations/CustomReference.cjs.map +1 -1
  467. package/build/relations/CustomReference.d.cts +1 -1
  468. package/build/relations/CustomReference.d.mts +1 -1
  469. package/build/relations/CustomReference.js +1 -1
  470. package/build/relations/CustomReference.js.map +1 -1
  471. package/build/relations/EnumCollection.cjs.map +1 -1
  472. package/build/relations/EnumCollection.d.cts +1 -1
  473. package/build/relations/EnumCollection.d.mts +1 -1
  474. package/build/relations/EnumCollection.js.map +1 -1
  475. package/build/relations/LazyField.cjs +4 -4
  476. package/build/relations/LazyField.cjs.map +1 -1
  477. package/build/relations/LazyField.js +4 -4
  478. package/build/relations/LazyField.js.map +1 -1
  479. package/build/relations/ManyToManyCollection.cjs +3 -3
  480. package/build/relations/ManyToManyCollection.cjs.map +1 -1
  481. package/build/relations/ManyToManyCollection.js +3 -3
  482. package/build/relations/ManyToManyCollection.js.map +1 -1
  483. package/build/relations/ManyToManyLargeCollection.cjs +3 -3
  484. package/build/relations/ManyToManyLargeCollection.cjs.map +1 -1
  485. package/build/relations/ManyToManyLargeCollection.js +3 -3
  486. package/build/relations/ManyToManyLargeCollection.js.map +1 -1
  487. package/build/relations/ManyToOneReference.cjs +4 -4
  488. package/build/relations/ManyToOneReference.cjs.map +1 -1
  489. package/build/relations/ManyToOneReference.js +4 -4
  490. package/build/relations/ManyToOneReference.js.map +1 -1
  491. package/build/relations/OneToManyCollection.cjs +1 -2
  492. package/build/relations/OneToManyCollection.cjs.map +1 -1
  493. package/build/relations/OneToManyCollection.d.cts +1 -1
  494. package/build/relations/OneToManyCollection.d.mts +1 -1
  495. package/build/relations/OneToManyCollection.js +1 -2
  496. package/build/relations/OneToManyCollection.js.map +1 -1
  497. package/build/relations/OneToManyLargeCollection.cjs +1 -1
  498. package/build/relations/OneToManyLargeCollection.cjs.map +1 -1
  499. package/build/relations/OneToManyLargeCollection.js +1 -1
  500. package/build/relations/OneToManyLargeCollection.js.map +1 -1
  501. package/build/relations/OneToOneReference.cjs +5 -5
  502. package/build/relations/OneToOneReference.cjs.map +1 -1
  503. package/build/relations/OneToOneReference.js +5 -5
  504. package/build/relations/OneToOneReference.js.map +1 -1
  505. package/build/relations/PolymorphicReference.cjs +3 -3
  506. package/build/relations/PolymorphicReference.cjs.map +1 -1
  507. package/build/relations/PolymorphicReference.js +3 -3
  508. package/build/relations/PolymorphicReference.js.map +1 -1
  509. package/build/relations/ReactiveField.cjs +5 -6
  510. package/build/relations/ReactiveField.cjs.map +1 -1
  511. package/build/relations/ReactiveField.d.cts +2 -2
  512. package/build/relations/ReactiveField.d.mts +2 -2
  513. package/build/relations/ReactiveField.js +3 -4
  514. package/build/relations/ReactiveField.js.map +1 -1
  515. package/build/relations/ReactiveGetter.cjs +0 -1
  516. package/build/relations/ReactiveGetter.cjs.map +1 -1
  517. package/build/relations/ReactiveGetter.d.cts +1 -1
  518. package/build/relations/ReactiveGetter.d.mts +1 -1
  519. package/build/relations/ReactiveGetter.js +0 -1
  520. package/build/relations/ReactiveGetter.js.map +1 -1
  521. package/build/relations/ReactiveManyToMany.cjs +5 -6
  522. package/build/relations/ReactiveManyToMany.cjs.map +1 -1
  523. package/build/relations/ReactiveManyToMany.d.cts +2 -2
  524. package/build/relations/ReactiveManyToMany.d.cts.map +1 -1
  525. package/build/relations/ReactiveManyToMany.d.mts +2 -2
  526. package/build/relations/ReactiveManyToMany.d.mts.map +1 -1
  527. package/build/relations/ReactiveManyToMany.js +3 -4
  528. package/build/relations/ReactiveManyToMany.js.map +1 -1
  529. package/build/relations/ReactiveManyToManyOtherSide.cjs +1 -3
  530. package/build/relations/ReactiveManyToManyOtherSide.cjs.map +1 -1
  531. package/build/relations/ReactiveManyToManyOtherSide.d.cts +2 -2
  532. package/build/relations/ReactiveManyToManyOtherSide.d.mts +2 -2
  533. package/build/relations/ReactiveManyToManyOtherSide.js +1 -3
  534. package/build/relations/ReactiveManyToManyOtherSide.js.map +1 -1
  535. package/build/relations/ReactiveReference.cjs +8 -9
  536. package/build/relations/ReactiveReference.cjs.map +1 -1
  537. package/build/relations/ReactiveReference.d.cts +2 -2
  538. package/build/relations/ReactiveReference.d.cts.map +1 -1
  539. package/build/relations/ReactiveReference.d.mts +2 -2
  540. package/build/relations/ReactiveReference.d.mts.map +1 -1
  541. package/build/relations/ReactiveReference.js +6 -7
  542. package/build/relations/ReactiveReference.js.map +1 -1
  543. package/build/relations/ReadOnlyCollection.cjs.map +1 -1
  544. package/build/relations/ReadOnlyCollection.js.map +1 -1
  545. package/build/relations/RecursiveCollection.cjs +3 -4
  546. package/build/relations/RecursiveCollection.cjs.map +1 -1
  547. package/build/relations/RecursiveCollection.d.cts +1 -1
  548. package/build/relations/RecursiveCollection.d.mts +1 -1
  549. package/build/relations/RecursiveCollection.js +3 -4
  550. package/build/relations/RecursiveCollection.js.map +1 -1
  551. package/build/relations/RecursiveCycleError.cjs.map +1 -1
  552. package/build/relations/RecursiveCycleError.js.map +1 -1
  553. package/build/relations/Reference.cjs +1 -1
  554. package/build/relations/Reference.cjs.map +1 -1
  555. package/build/relations/Reference.js +1 -1
  556. package/build/relations/Reference.js.map +1 -1
  557. package/build/relations/Relation.cjs.map +1 -1
  558. package/build/relations/Relation.js.map +1 -1
  559. package/build/relations/hasAsyncMethod.cjs +2 -2
  560. package/build/relations/hasAsyncMethod.cjs.map +1 -1
  561. package/build/relations/hasAsyncMethod.d.cts +1 -1
  562. package/build/relations/hasAsyncMethod.d.mts +1 -1
  563. package/build/relations/hasAsyncMethod.js +1 -1
  564. package/build/relations/hasAsyncMethod.js.map +1 -1
  565. package/build/relations/hasManyDerived.cjs +3 -3
  566. package/build/relations/hasManyDerived.cjs.map +1 -1
  567. package/build/relations/hasManyDerived.d.cts +1 -1
  568. package/build/relations/hasManyDerived.d.mts +1 -1
  569. package/build/relations/hasManyDerived.js +2 -2
  570. package/build/relations/hasManyDerived.js.map +1 -1
  571. package/build/relations/hasManyThrough.cjs +6 -6
  572. package/build/relations/hasManyThrough.cjs.map +1 -1
  573. package/build/relations/hasManyThrough.d.cts +1 -1
  574. package/build/relations/hasManyThrough.d.mts +1 -1
  575. package/build/relations/hasManyThrough.js +2 -2
  576. package/build/relations/hasManyThrough.js.map +1 -1
  577. package/build/relations/hasOneDerived.cjs +3 -3
  578. package/build/relations/hasOneDerived.cjs.map +1 -1
  579. package/build/relations/hasOneDerived.d.cts +1 -1
  580. package/build/relations/hasOneDerived.d.mts +1 -1
  581. package/build/relations/hasOneDerived.js +2 -2
  582. package/build/relations/hasOneDerived.js.map +1 -1
  583. package/build/relations/hasOneThrough.cjs +7 -7
  584. package/build/relations/hasOneThrough.cjs.map +1 -1
  585. package/build/relations/hasOneThrough.d.cts +1 -1
  586. package/build/relations/hasOneThrough.d.mts +1 -1
  587. package/build/relations/hasOneThrough.js +2 -2
  588. package/build/relations/hasOneThrough.js.map +1 -1
  589. package/build/relations/hasProperty.cjs +4 -4
  590. package/build/relations/hasProperty.cjs.map +1 -1
  591. package/build/relations/hasProperty.d.cts +2 -2
  592. package/build/relations/hasProperty.d.mts +2 -2
  593. package/build/relations/hasProperty.js +2 -2
  594. package/build/relations/hasProperty.js.map +1 -1
  595. package/build/relations/index.cjs +10 -10
  596. package/build/relations/index.js +10 -10
  597. package/build/relations/isCascadeDelete.cjs.map +1 -1
  598. package/build/relations/isCascadeDelete.js.map +1 -1
  599. package/build/resurrection.cjs.map +1 -1
  600. package/build/resurrection.js.map +1 -1
  601. package/build/rules.cjs +3 -4
  602. package/build/rules.cjs.map +1 -1
  603. package/build/rules.d.cts +1 -1
  604. package/build/rules.d.mts +1 -1
  605. package/build/rules.js +3 -4
  606. package/build/rules.js.map +1 -1
  607. package/build/runtimeConfig.cjs.map +1 -1
  608. package/build/runtimeConfig.js.map +1 -1
  609. package/build/{TypeInfo.cjs → serde/TypeInfo.cjs} +1 -1
  610. package/build/serde/TypeInfo.cjs.map +1 -0
  611. package/build/{TypeInfo.d.cts → serde/TypeInfo.d.cts} +2 -2
  612. package/build/serde/TypeInfo.d.cts.map +1 -0
  613. package/build/{TypeInfo.d.mts → serde/TypeInfo.d.mts} +2 -2
  614. package/build/serde/TypeInfo.d.mts.map +1 -0
  615. package/build/{TypeInfo.js → serde/TypeInfo.js} +1 -1
  616. package/build/serde/TypeInfo.js.map +1 -0
  617. package/build/{columns.cjs → serde/columns.cjs} +1 -1
  618. package/build/serde/columns.cjs.map +1 -0
  619. package/build/{columns.d.cts → serde/columns.d.cts} +2 -2
  620. package/build/serde/columns.d.cts.map +1 -0
  621. package/build/{columns.d.mts → serde/columns.d.mts} +2 -2
  622. package/build/serde/columns.d.mts.map +1 -0
  623. package/build/{columns.js → serde/columns.js} +1 -1
  624. package/build/serde/columns.js.map +1 -0
  625. package/build/{fieldSerde.cjs → serde/fieldSerde.cjs} +6 -6
  626. package/build/serde/fieldSerde.cjs.map +1 -0
  627. package/build/{fieldSerde.d.cts → serde/fieldSerde.d.cts} +5 -5
  628. package/build/serde/fieldSerde.d.cts.map +1 -0
  629. package/build/{fieldSerde.d.mts → serde/fieldSerde.d.mts} +5 -5
  630. package/build/serde/fieldSerde.d.mts.map +1 -0
  631. package/build/{fieldSerde.js → serde/fieldSerde.js} +6 -6
  632. package/build/serde/fieldSerde.js.map +1 -0
  633. package/build/{serde.cjs → serde/serde.cjs} +25 -26
  634. package/build/serde/serde.cjs.map +1 -0
  635. package/build/{serde.d.cts → serde/serde.d.cts} +1 -1
  636. package/build/serde/serde.d.cts.map +1 -0
  637. package/build/{serde.d.mts → serde/serde.d.mts} +1 -1
  638. package/build/serde/serde.d.mts.map +1 -0
  639. package/build/{serde.js → serde/serde.js} +4 -5
  640. package/build/serde/serde.js.map +1 -0
  641. package/build/{temporal.cjs → serde/temporal.cjs} +1 -1
  642. package/build/serde/temporal.cjs.map +1 -0
  643. package/build/{temporal.d.cts → serde/temporal.d.cts} +1 -1
  644. package/build/serde/temporal.d.cts.map +1 -0
  645. package/build/{temporal.d.mts → serde/temporal.d.mts} +1 -1
  646. package/build/serde/temporal.d.mts.map +1 -0
  647. package/build/{temporal.js → serde/temporal.js} +1 -1
  648. package/build/serde/temporal.js.map +1 -0
  649. package/build/{temporalMappers.cjs → serde/temporalMappers.cjs} +4 -5
  650. package/build/serde/temporalMappers.cjs.map +1 -0
  651. package/build/{temporalMappers.d.cts → serde/temporalMappers.d.cts} +1 -1
  652. package/build/serde/temporalMappers.d.cts.map +1 -0
  653. package/build/{temporalMappers.d.mts → serde/temporalMappers.d.mts} +1 -1
  654. package/build/serde/temporalMappers.d.mts.map +1 -0
  655. package/build/{temporalMappers.js → serde/temporalMappers.js} +2 -3
  656. package/build/serde/temporalMappers.js.map +1 -0
  657. package/build/upsert.cjs +1 -1
  658. package/build/upsert.cjs.map +1 -1
  659. package/build/upsert.d.cts.map +1 -1
  660. package/build/upsert.d.mts.map +1 -1
  661. package/build/upsert.js +1 -1
  662. package/build/upsert.js.map +1 -1
  663. package/build/utils.cjs +0 -1
  664. package/build/utils.cjs.map +1 -1
  665. package/build/utils.d.cts +1 -1
  666. package/build/utils.d.mts +1 -1
  667. package/build/utils.js +0 -1
  668. package/build/utils.js.map +1 -1
  669. package/package.json +2 -2
  670. package/build/FlushLock.cjs.map +0 -1
  671. package/build/FlushLock.d.cts.map +0 -1
  672. package/build/FlushLock.d.mts.map +0 -1
  673. package/build/FlushLock.js.map +0 -1
  674. package/build/HintTree.cjs.map +0 -1
  675. package/build/HintTree.d.cts.map +0 -1
  676. package/build/HintTree.d.mts.map +0 -1
  677. package/build/HintTree.js.map +0 -1
  678. package/build/IsLoadedCache.d.cts.map +0 -1
  679. package/build/IsLoadedCache.d.mts.map +0 -1
  680. package/build/IsLoadedCache.js.map +0 -1
  681. package/build/JoinRows.cjs.map +0 -1
  682. package/build/JoinRows.d.cts.map +0 -1
  683. package/build/JoinRows.d.mts.map +0 -1
  684. package/build/JoinRows.js.map +0 -1
  685. package/build/PendingChanges.d.cts.map +0 -1
  686. package/build/PendingChanges.d.mts.map +0 -1
  687. package/build/PendingChanges.js +0 -2
  688. package/build/ReactionsManager.cjs.map +0 -1
  689. package/build/ReactionsManager.d.cts.map +0 -1
  690. package/build/ReactionsManager.d.mts.map +0 -1
  691. package/build/ReactionsManager.js.map +0 -1
  692. package/build/Todo.cjs.map +0 -1
  693. package/build/Todo.d.cts.map +0 -1
  694. package/build/Todo.d.mts.map +0 -1
  695. package/build/Todo.js.map +0 -1
  696. package/build/TypeInfo.cjs.map +0 -1
  697. package/build/TypeInfo.d.cts.map +0 -1
  698. package/build/TypeInfo.d.mts.map +0 -1
  699. package/build/TypeInfo.js.map +0 -1
  700. package/build/columns.cjs.map +0 -1
  701. package/build/columns.d.cts.map +0 -1
  702. package/build/columns.d.mts.map +0 -1
  703. package/build/columns.js.map +0 -1
  704. package/build/driverApi.cjs +0 -18
  705. package/build/driverApi.cjs.map +0 -1
  706. package/build/driverApi.d.cts +0 -22
  707. package/build/driverApi.d.cts.map +0 -1
  708. package/build/driverApi.d.mts +0 -22
  709. package/build/driverApi.d.mts.map +0 -1
  710. package/build/driverApi.js +0 -18
  711. package/build/driverApi.js.map +0 -1
  712. package/build/fieldSerde.cjs.map +0 -1
  713. package/build/fieldSerde.d.cts.map +0 -1
  714. package/build/fieldSerde.d.mts.map +0 -1
  715. package/build/fieldSerde.js.map +0 -1
  716. package/build/loadHints.cjs.map +0 -1
  717. package/build/loadHints.d.cts.map +0 -1
  718. package/build/loadHints.d.mts.map +0 -1
  719. package/build/loadHints.js.map +0 -1
  720. package/build/loadLens.cjs.map +0 -1
  721. package/build/loadLens.d.cts.map +0 -1
  722. package/build/loadLens.d.mts.map +0 -1
  723. package/build/loadLens.js.map +0 -1
  724. package/build/reactiveHints.cjs.map +0 -1
  725. package/build/reactiveHints.d.cts.map +0 -1
  726. package/build/reactiveHints.d.mts.map +0 -1
  727. package/build/reactiveHints.js.map +0 -1
  728. package/build/serde.cjs.map +0 -1
  729. package/build/serde.d.cts.map +0 -1
  730. package/build/serde.d.mts.map +0 -1
  731. package/build/serde.js.map +0 -1
  732. package/build/temporal.cjs.map +0 -1
  733. package/build/temporal.d.cts.map +0 -1
  734. package/build/temporal.d.mts.map +0 -1
  735. package/build/temporal.js.map +0 -1
  736. package/build/temporalMappers.cjs.map +0 -1
  737. package/build/temporalMappers.d.cts.map +0 -1
  738. package/build/temporalMappers.d.mts.map +0 -1
  739. package/build/temporalMappers.js.map +0 -1
  740. package/build/unnest.cjs.map +0 -1
  741. package/build/unnest.d.cts.map +0 -1
  742. package/build/unnest.d.mts.map +0 -1
  743. package/build/unnest.js.map +0 -1
  744. package/build/withLoaded.cjs.map +0 -1
  745. package/build/withLoaded.d.cts.map +0 -1
  746. package/build/withLoaded.d.mts.map +0 -1
  747. package/build/withLoaded.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"QueryParser.d.cts","names":[],"sources":["../../../src/queries/find/QueryParser.ts"],"mappings":";;;;UA8BiB;EACf;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;;;;;;;;;;;;;;;;;;;;;;EAsBA;;IAEE;;IAEA;;IAEA;;;;;;;;;;;;;;;;;;;;;UAsBa;EACf;;EAEA;;EAEA;;;;;;;;;;;;;UAce;;EAEf;;EAEA;IAAY;IAAoB;;;EAEhC;IAAS;IAAa;IAAa;;IAA+B;IAAa,OAAO;;;EAEtF;;;;;UAMe;EACf;EACA;;EAEA;;EAEA;;EAEA,OAAO;;EAEP;IAAa;IAAgB;;;KAGnB,cAAc,eAAe,YAAY,iBAAiB;UAErD;EACf;EACA;EACA,OAAO;;KAGG;EAAkB;EAAe;;EAAqB;;KAEtD,wBAAwB;KAC/B;EAA6B;EAAa;EAAiB;;;UAG/C;EACf,SAAS;;EAET,QAAQ;;EAER,YAAY;;EAEZ,WAAW;;EAEX,UAAU;;EAEV,OAAO;;;;;;;;iBASO,eACd,MAAM,gBACN,aACA;EACE,aAAa;EACb;EACA;EACA;EACA;EACA;EACA;IAED;;;;;;;;;;;;iBAwhBa,mBAAmB,OAAO;;iBAgC1B,WAAW;;iBAKX,gBAAgB,MAAM,gBAAgB,eAAe;EAAU;;;iBAU/D,gBAAgB,OAAO,iBAAiB,MAAM,gBAAgB;iBAiB9D,iCACd,OAAO,iBACP,MAAM,gBACN,eACA;iBA8Fc,UAAU,OAAO,mBAAmB,cAAc,aAAa,oBAAoB"}
1
+ {"version":3,"file":"QueryParser.d.cts","names":[],"sources":["../../../src/queries/find/QueryParser.ts"],"mappings":";;;;UAmCiB;EACf;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;;;;;;;;;;;;;;;;;;;;;;EAsBA;;IAEE;;IAEA;;IAEA;;;;;;;;;;;;;;;;;;;;;UAsBa;EACf;;EAEA;;EAEA;;;;;;;;;;;;;UAce;;EAEf;;EAEA;IAAY;IAAoB;;;EAEhC;IAAS;IAAa;IAAa;;IAA+B;IAAa,OAAO;;;EAEtF;;;;;UAMe;EACf;EACA;;EAEA;;EAEA;;EAEA,OAAO;;EAEP;IAAa;IAAgB;;;KAGnB,cAAc,eAAe,YAAY,iBAAiB;UAErD;EACf;EACA;EACA,OAAO;;KAGG;EAAkB;EAAe;;EAAqB;;KAEtD,wBAAwB;KAC/B;EAA6B;EAAa;EAAiB;;;UAG/C;EACf,SAAS;;EAET,QAAQ;;EAER,YAAY;;EAEZ,WAAW;;EAEX,UAAU;;EAEV,OAAO;;;;;;;;iBASO,eACd,MAAM,gBACN,aACA;EACE,aAAa;EACb;EACA;EACA;EACA;EACA;EACA;IAED;;;;;;;;;;;;iBAwhBa,mBAAmB,OAAO;;iBAgC1B,WAAW;;iBAKX,gBAAgB,MAAM,gBAAgB,eAAe;EAAU;;;iBAU/D,gBAAgB,OAAO,iBAAiB,MAAM,gBAAgB;iBAiB9D,iCACd,OAAO,iBACP,MAAM,gBACN,eACA;iBA8Fc,UAAU,OAAO,mBAAmB,cAAc,aAAa,oBAAoB"}
@@ -1 +1 @@
1
- {"version":3,"file":"QueryParser.d.mts","names":[],"sources":["../../../src/queries/find/QueryParser.ts"],"mappings":";;;;UA8BiB;EACf;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;;;;;;;;;;;;;;;;;;;;;;EAsBA;;IAEE;;IAEA;;IAEA;;;;;;;;;;;;;;;;;;;;;UAsBa;EACf;;EAEA;;EAEA;;;;;;;;;;;;;UAce;;EAEf;;EAEA;IAAY;IAAoB;;;EAEhC;IAAS;IAAa;IAAa;;IAA+B;IAAa,OAAO;;;EAEtF;;;;;UAMe;EACf;EACA;;EAEA;;EAEA;;EAEA,OAAO;;EAEP;IAAa;IAAgB;;;KAGnB,cAAc,eAAe,YAAY,iBAAiB;UAErD;EACf;EACA;EACA,OAAO;;KAGG;EAAkB;EAAe;;EAAqB;;KAEtD,wBAAwB;KAC/B;EAA6B;EAAa;EAAiB;;;UAG/C;EACf,SAAS;;EAET,QAAQ;;EAER,YAAY;;EAEZ,WAAW;;EAEX,UAAU;;EAEV,OAAO;;;;;;;;iBASO,eACd,MAAM,gBACN,aACA;EACE,aAAa;EACb;EACA;EACA;EACA;EACA;EACA;IAED;;;;;;;;;;;;iBAwhBa,mBAAmB,OAAO;;iBAgC1B,WAAW;;iBAKX,gBAAgB,MAAM,gBAAgB,eAAe;EAAU;;;iBAU/D,gBAAgB,OAAO,iBAAiB,MAAM,gBAAgB;iBAiB9D,iCACd,OAAO,iBACP,MAAM,gBACN,eACA;iBA8Fc,UAAU,OAAO,mBAAmB,cAAc,aAAa,oBAAoB"}
1
+ {"version":3,"file":"QueryParser.d.mts","names":[],"sources":["../../../src/queries/find/QueryParser.ts"],"mappings":";;;;UAmCiB;EACf;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;;;;;;;;;;;;;;;;;;;;;;EAsBA;;IAEE;;IAEA;;IAEA;;;;;;;;;;;;;;;;;;;;;UAsBa;EACf;;EAEA;;EAEA;;;;;;;;;;;;;UAce;;EAEf;;EAEA;IAAY;IAAoB;;;EAEhC;IAAS;IAAa;IAAa;;IAA+B;IAAa,OAAO;;;EAEtF;;;;;UAMe;EACf;EACA;;EAEA;;EAEA;;EAEA,OAAO;;EAEP;IAAa;IAAgB;;;KAGnB,cAAc,eAAe,YAAY,iBAAiB;UAErD;EACf;EACA;EACA,OAAO;;KAGG;EAAkB;EAAe;;EAAqB;;KAEtD,wBAAwB;KAC/B;EAA6B;EAAa;EAAiB;;;UAG/C;EACf,SAAS;;EAET,QAAQ;;EAER,YAAY;;EAEZ,WAAW;;EAEX,UAAU;;EAEV,OAAO;;;;;;;;iBASO,eACd,MAAM,gBACN,aACA;EACE,aAAa;EACb;EACA;EACA;EACA;EACA;EACA;IAED;;;;;;;;;;;;iBAwhBa,mBAAmB,OAAO;;iBAgC1B,WAAW;;iBAKX,gBAAgB,MAAM,gBAAgB,eAAe;EAAU;;;iBAU/D,gBAAgB,OAAO,iBAAiB,MAAM,gBAAgB;iBAiB9D,iCACd,OAAO,iBACP,MAAM,gBACN,eACA;iBA8Fc,UAAU,OAAO,mBAAmB,cAAc,aAAa,oBAAoB"}
@@ -1,3 +1,4 @@
1
+ import { keyToNumber, maybeResolveReferenceToId } from "../../keys.js";
1
2
  import { kq, kqDot } from "../sql/keywords.js";
2
3
  import { predicateBrand } from "../conditions.js";
3
4
  import { deferredAliasSym, isDeferredAliasCondition } from "./DeferredAlias.js";
@@ -6,11 +7,10 @@ import { isScope, isScopeJoinFilter, resolveScope } from "./scopes.js";
6
7
  import { isNilIdValue, mapToDb, parseEntityFilter, parseValueFilter } from "../valueFilters.js";
7
8
  import { ConditionBuilder } from "../ConditionBuilder.js";
8
9
  import { filterSoftDeletes, lazyExcludedSelects, stiSubtypeFilter } from "../entityQueryUtils.js";
9
- import { isDeferredCondition } from "../sql/Expr.js";
10
10
  import { pruneUnusedJoins } from "./QueryParser.pruning.js";
11
11
  import { visitConditions } from "./QueryVisitor.js";
12
+ import { isDeferredCondition } from "../sql/Expr.js";
12
13
  import { abbreviation, fail } from "../../utils.js";
13
- import { keyToNumber, maybeResolveReferenceToId } from "../../keys.js";
14
14
  import { getConstructorFromTaggedId, getMetadataForTable } from "../../configure.js";
15
15
  import { getBaseMeta } from "../../EntityMetadata.js";
16
16
  import { groupBy } from "joist-utils";
@@ -1 +1 @@
1
- {"version":3,"file":"QueryParser.js","names":["newAlias","alias"],"sources":["../../../src/queries/find/QueryParser.ts"],"sourcesContent":["import { groupBy } from \"joist-utils\";\n\nimport { getConstructorFromTaggedId, getMetadataForTable } from \"../../configure.ts\";\nimport type { Entity } from \"../../Entity.ts\";\nimport { type EntityMetadata, type Field, getBaseMeta } from \"../../EntityMetadata.ts\";\nimport { keyToNumber, maybeResolveReferenceToId } from \"../../keys.ts\";\nimport { abbreviation, fail } from \"../../utils.ts\";\nimport { ConditionBuilder } from \"../ConditionBuilder.ts\";\nimport { type ConditionInput, predicateBrand } from \"../conditions.ts\";\nimport { filterSoftDeletes, lazyExcludedSelects, stiSubtypeFilter } from \"../entityQueryUtils.ts\";\nimport type { ColumnCondition, ParsedExpressionFilter, RawCondition } from \"../parsedConditions.ts\";\nimport { isDeferredCondition } from \"../sql/Expr.ts\";\nimport { kq, kqDot } from \"../sql/keywords.ts\";\nimport {\n type ParsedEntityFilter,\n isNilIdValue,\n mapToDb,\n parseEntityFilter,\n parseValueFilter,\n} from \"../valueFilters.ts\";\nimport { type AliasMgmt, getAliasMgmt, getMaybeCtiAlias, isAlias, alias as newAlias } from \"./Aliases.ts\";\nimport { deferredAliasSym, isDeferredAliasCondition } from \"./DeferredAlias.ts\";\nimport type { ExpressionFilter, OrderBy } from \"./EntityFilter.ts\";\nimport { pruneUnusedJoins } from \"./QueryParser.pruning.ts\";\nimport { visitConditions } from \"./QueryVisitor.ts\";\nimport { type Scope, isScope, isScopeJoinFilter, resolveScope } from \"./scopes.ts\";\n\n// `skipCondition` lives in its own leaf module, shared by domain aliases and SQL expressions\n// without a load-order cycle; `index.ts` re-exports it directly.\n\nexport interface PrimaryTable {\n join: \"primary\";\n alias: string;\n table: string;\n}\n\nexport interface JoinTable {\n join: \"inner\" | \"outer\";\n alias: string;\n table: string;\n col1: string;\n col2: string;\n distinct?: boolean;\n /**\n * Metadata used by `optimizeCollectionJoins` to rewrite collection joins into EXISTS.\n *\n * I.e. for `Author.books.reviews`:\n * ```sql\n * authors a\n * LEFT JOIN books b ON a.id = b.author_id\n * LEFT JOIN book_reviews br ON b.id = br.book_id\n * ```\n * `books b` has `parentAlias: \"a\"` and `rootAlias: \"b\"`, while `book_reviews br` has\n * `parentAlias: \"b\"` and `rootAlias: \"br\"`.\n *\n * I.e. for `Author.tags`, the m2m join table is the collection root:\n * ```sql\n * authors a\n * LEFT JOIN authors_to_tags att ON a.id = att.author_id\n * LEFT JOIN tags t ON att.tag_id = t.id\n * ```\n * `authors_to_tags att` has `alias: \"att\"` and `rootAlias: \"att\"`, while `tags t` has `alias: \"t\"`\n * but still has `rootAlias: \"att\"` because it belongs to the m2m subtree rooted at the join table.\n */\n collection?: {\n /** The collection relation type, i.e. `o2m` for `Author.books`, or `m2m` for `Author.tags`. */\n kind: \"o2m\" | \"m2m\";\n /** The alias that owns this collection path, i.e. `a` for `Author.books`, or `att` for `Author.tags -> tags`. */\n parentAlias: string;\n /** The top-level alias in this collection subtree, i.e. `b` for `Author.books.reviews`, or `att` for `Author.tags`. */\n rootAlias: string;\n };\n}\n\n/**\n * Creates a `CROSS JOIN`, currently used for our `em.find` batching.\n *\n * I.e. queries like:\n *\n * ```sql\n * WITH _find (tag, arg1, arg2) AS (VALUES\n * (0::int, 'a'::varchar, 'a'::varchar),\n * (1, 'b', 'b'),\n * (2, 'c', 'c')\n * )\n * SELECT a.*, array_agg(_find.tag) AS _tags\n * FROM authors a\n * CROSS JOIN _find AS _find\n * WHERE a.first_name = _find.arg0 OR a.last_name = _find.arg1\n * GROUP BY a.id\n * ```\n */\nexport interface CrossJoinTable {\n join: \"cross\";\n /** The new alias for the joined table. */\n alias: string;\n /** The table name to join into the query. */\n table: string;\n}\n\n/**\n * Adds `WITH` CTE clauses to the query.\n *\n * I.e. queries like:\n *\n * ```sql\n * WITH _find (tag, arg0, arg1) AS (\n * VALUES ($1::int, $2::character varying, $3::character varying), ($4, $5, $6)\n * )\n * ```\n */\nexport interface ParsedCteClause {\n /** The new alias for the CTE, i.e. `_find` in the above query. */\n alias: string;\n /** The columns, i.e. `tag, arg0, arg1` in the above query. */\n columns?: { columnName: string; dbType: string }[];\n /** The subquery for the AS of the CTE clause. */\n query: { kind: \"raw\"; sql: string; bindings: readonly any[] } | { kind: \"ast\"; query: ParsedFindQuery };\n /** Whether to include a `RECURSIVE` keyword after the `WITH`. */\n recursive?: boolean;\n}\n\n/**\n * Creates `LATERAL JOIN`s, currently used by `findCount` and JSON preloading.\n */\nexport interface LateralJoinTable {\n join: \"lateral\";\n alias: string;\n /** Used for join dependency tracking. */\n fromAlias: string;\n /** Used more for bookkeeping/consistency with other join tables than the query itself. */\n table: string;\n /** The subquery that will look for/roll-up N children. */\n query: ParsedFindQuery;\n /** Optional settings for the subquery, i.e. per-parent pagination. */\n settings?: { limit?: number; offset?: number };\n}\n\nexport type ParsedTable = PrimaryTable | JoinTable | CrossJoinTable | LateralJoinTable;\n\nexport interface ParsedOrderBy {\n alias: string;\n column: string;\n order: OrderBy;\n}\n\nexport type ParsedGroupBy = { alias: string; column: string } | { expression: string };\n\nexport type ParsedSelect = string | ParsedSelectWithBindings;\ntype ParsedSelectWithBindings = { sql: string; bindings: any[]; aliases: string[] };\n\n/** The result of parsing an `em.find` filter. */\nexport interface ParsedFindQuery {\n selects: ParsedSelect[];\n /** The primary table plus any joins. */\n tables: ParsedTable[];\n /** The query's conditions. */\n condition?: ParsedExpressionFilter;\n /** Extremely optional group bys; we generally don't support adhoc/aggregate queries, but the auto-batching infra uses these. */\n groupBys?: ParsedGroupBy[];\n /** Any optional orders to add before the default 'order by id'. */\n orderBys: ParsedOrderBy[];\n /** Optional CTE to prefix to the query, i.e. for recursive relations. */\n ctes?: ParsedCteClause[];\n}\n\n/**\n * Parses an `em.find` filter into a logical `ParsedFindQuery` AST, leaving optimization/pruning to callers.\n *\n * The main execution flow is:\n * parseFindQuery -> beforeFind plugins -> optimizeCollectionJoins -> pruneUnusedJoins -> execute SQL.\n */\nexport function parseFindQuery(\n meta: EntityMetadata,\n filter: any,\n opts: {\n conditions?: ExpressionFilter;\n orderBy?: any;\n pruneJoins?: boolean;\n keepAliases?: string[];\n softDeletes?: \"include\" | \"exclude\";\n allowMultipleLeftJoins?: boolean;\n optimizeJoinsToExists?: boolean;\n } = {},\n): ParsedFindQuery {\n const selects: string[] = [];\n const tables: ParsedTable[] = [];\n const orderBys: ParsedOrderBy[] = [];\n const query: ParsedFindQuery = { selects, tables, orderBys };\n const { orderBy, conditions: optsExpression, softDeletes = \"exclude\", pruneJoins = false, keepAliases = [] } = opts;\n const cb = new ConditionBuilder();\n // Where each user-created `alias(...)` is bound in this parse's join literal; alias-built conditions\n // (`a.firstName.eq(...)`) are resolved against it once the whole tree is walked\n const aliasBindings = new Map<AliasMgmt, { meta: EntityMetadata; alias: string }>();\n\n const aliases: Record<string, number> = {};\n function getAlias(tableName: string): string {\n const abbrev = abbreviation(tableName);\n const i = aliases[abbrev] || 0;\n aliases[abbrev] = i + 1;\n return i === 0 ? abbrev : `${abbrev}${i}`;\n }\n\n /** Adds a `deleted_at IS NULL` condition for `alias`, i.e. for the primary table or a collection join. */\n function addSoftDeleteCondition(meta: EntityMetadata, alias: string, targetCb: ConditionBuilder): void {\n if (filterSoftDeletes(meta, softDeletes)) {\n const column = meta.allFields[getBaseMeta(meta).timestampFields!.deletedAt!].serde?.columns[0]!;\n targetCb.addSimpleCondition({\n kind: \"column\",\n alias,\n column: column.columnName,\n dbType: column.dbType,\n cond: { kind: \"is-null\" },\n pruneable: true,\n });\n }\n }\n\n function addTable(\n meta: EntityMetadata,\n alias: string,\n join: ParsedTable[\"join\"],\n col1: string,\n col2: string,\n filter: any,\n fieldName?: string,\n targetCb: ConditionBuilder = cb,\n /** Whether this table is the \"other side\" of a collection, i.e. `books` in `em.find(Author, { books: ... })`. */\n isCollection: boolean = false,\n ): void {\n // look at filter, is it `{ book: \"b2\" }` or `{ book: { ... } }`\n const scopeFilter = isScope(filter);\n const ef = scopeFilter ? undefined : parseEntityFilter(meta, filter);\n if (!scopeFilter && !ef && join !== \"primary\" && !isAlias(filter)) {\n return;\n }\n\n if (join === \"primary\") {\n tables.push({ alias, table: meta.tableName, join });\n addTablePerClassJoinsAndClassTag({ selects, tables, orderBys }, meta, alias, true);\n } else if (meta.inheritanceType === \"cti\" && fieldName && !(fieldName in meta.fields)) {\n // For cti, our meta might be a subtype while the FK is actually on the base table. This should only be the case\n // when the fk is on another table (e.g. o2o/o2m). In these cases, we'll be passed a field name and can verify if\n // its directly in our meta, if not we should assume it's in the base type and join that in first.\n meta.baseTypes.forEach((bt, i) => {\n tables.push({\n alias: `${alias}_b${i}`,\n table: bt.tableName,\n join: \"outer\",\n col1,\n col2: `${kq(`${alias}_b${i}`)}.${col2.split(\".\")[1]}`,\n distinct: false,\n });\n // and we still need to join in our subtype as well in case its own fields are queried against\n tables.push({\n alias: `${alias}`,\n table: meta.tableName,\n join: \"outer\",\n col1: kqDot(alias, \"id\"),\n col2: kqDot(`${alias}_b${i}`, \"id\"),\n distinct: false,\n });\n });\n } else if (join === \"lateral\" || join === \"cross\") {\n fail(\"Unexpected lateral join\");\n } else {\n tables.push({ alias, table: meta.tableName, join, col1, col2 });\n // Maybe only do this if we're the primary, or have a field that needs it?\n addTablePerClassJoinsAndClassTag({ selects, tables, orderBys }, meta, alias, false);\n }\n\n if (needsStiDiscriminator(meta)) {\n addStiSubtypeFilter(targetCb, meta, alias);\n }\n\n // Only the primary table & collection joins filter soft-deletes, to match the in-memory relation\n // semantics of \"o2m/m2m collections filter out soft-deletes, but m2o/o2o references still return\n // them\". I.e. `book.author.get` returns a soft-deleted author, so `em.find(Book, { author: ... })`\n // should still match the book, as long as the book itself is not soft-deleted.\n if (join === \"primary\" || isCollection) {\n addSoftDeleteCondition(meta, alias, targetCb);\n }\n\n // The user's locally declared aliases, i.e. `const [a, b] = aliases(Author, Book)`,\n // aren't guaranteed to line up with the aliases we've assigned internally, like `a`\n // might actually be `a1` if there are two `authors` tables in the query, so push the\n // canonical alias value for the current clause into the Alias.\n if (filter && typeof filter === \"object\" && \"as\" in filter && isAlias(filter.as)) {\n aliasBindings.set(getAliasMgmt(filter.as), { meta, alias });\n } else if (isAlias(filter)) {\n aliasBindings.set(getAliasMgmt(filter), { meta, alias });\n }\n\n addFilterAt(meta, alias, filter, targetCb, ef, join);\n }\n\n function addFilterAt(\n meta: EntityMetadata,\n tableAlias: string,\n filter: any,\n targetCb: ConditionBuilder,\n parsed: ParsedEntityFilter | undefined = parseEntityFilter(meta, filter),\n parentJoin: ParsedTable[\"join\"] = \"primary\",\n ): void {\n if (isScope(filter)) {\n addScopeFilterAt(meta, tableAlias, filter, targetCb, parentJoin);\n } else if (parsed && parsed.kind === \"join\") {\n addSubFilter(meta, tableAlias, parsed.subFilter, targetCb, parentJoin);\n } else if (parsed) {\n const column = meta.fields[\"id\"].serde!.columns[0];\n targetCb.addValueFilter(tableAlias, column, parsed);\n }\n }\n\n function addScopeFilterAt<T extends Entity>(\n meta: EntityMetadata<T>,\n tableAlias: string,\n scope: Scope<T>,\n targetCb: ConditionBuilder,\n parentJoin: ParsedTable[\"join\"],\n ): void {\n for (const fragment of resolveScope(scope).fragments) {\n if (fragment.kind === \"filter\") {\n addFilterAt(meta, tableAlias, fragment.filter, targetCb, undefined, parentJoin);\n } else {\n const a = newAlias(meta.cstr);\n const result = fragment.fn(a);\n aliasBindings.set(getAliasMgmt(a), { meta, alias: tableAlias });\n if (isScopeJoinFilter(result)) {\n // Parse the join tree first so its `as:` bindings re-root the aliases that\n // `conditions` reference, then add the conditions against the now-bound aliases.\n addFilterAt(meta, tableAlias, result.where, targetCb, undefined, parentJoin);\n checkDomainCondition(result.conditions);\n targetCb.maybeAddExpression(result.conditions);\n } else {\n const conditions = Array.isArray(result) ? result : [result];\n for (const condition of conditions) checkDomainCondition(condition);\n if (conditions.length > 0) targetCb.maybeAddExpression({ and: conditions });\n }\n }\n }\n }\n\n function addSubFilter(\n meta: EntityMetadata,\n tableAlias: string,\n subFilter: object,\n targetCb: ConditionBuilder,\n parentJoin: ParsedTable[\"join\"],\n ): void {\n // subFilter really means we're matching against the entity columns/further joins\n Object.keys(subFilter).forEach((key) => {\n // Skip the `{ as: ... }` alias binding\n if (key === \"as\") return;\n if (key === \"and\" || key === \"or\") {\n addLogicalFilter(meta, tableAlias, key, (subFilter as any)[key], targetCb, parentJoin);\n return;\n }\n const field = findFilterField(meta, key) ?? fail(`Field '${key}' not found on ${meta.tableName}`);\n const fa = `${tableAlias}${field.aliasSuffix}`;\n if (field.kind === \"primitive\" || field.kind === \"primaryKey\" || field.kind === \"enum\") {\n const column = field.serde.columns[0];\n parseValueFilter((subFilter as any)[key]).forEach((filter) => {\n targetCb.addValueFilter(fa, column, filter);\n });\n } else if (field.kind === \"m2o\") {\n const column = field.serde.columns[0];\n const sub = (subFilter as any)[key];\n const joinKind = field.required && parentJoin !== \"outer\" ? \"inner\" : \"outer\";\n if (isAlias(sub)) {\n const a = getAlias(field.otherMetadata().tableName);\n addTable(\n field.otherMetadata(),\n a,\n joinKind,\n kqDot(fa, column.columnName),\n kqDot(a, \"id\"),\n sub,\n undefined,\n targetCb,\n );\n }\n const f = parseEntityFilter(field.otherMetadata(), sub);\n // Probe the filter and see if it's just an id, if so we can avoid the join; m2os don't need\n // a join for soft-delete filtering because references don't filter out soft-deletes.\n if (!f) {\n // skip\n } else if (f.kind === \"join\") {\n const a = getAlias(field.otherMetadata().tableName);\n addTable(\n field.otherMetadata(),\n a,\n joinKind,\n kqDot(fa, column.columnName),\n kqDot(a, \"id\"),\n sub,\n undefined,\n targetCb,\n );\n } else {\n targetCb.addValueFilter(fa, column, f);\n }\n } else if (field.kind === \"poly\") {\n const f = parseEntityFilter(meta, (subFilter as any)[key]);\n if (!f) {\n // skip\n } else if (f.kind === \"join\") {\n throw new Error(\"Joins through polys are not supported\");\n } else {\n // We're left with basically a ValueFilter against the ids\n // For now only support eq/ne/in/is-null\n if (f.kind === \"eq\" || f.kind === \"ne\") {\n if (isNilIdValue(f.value)) return;\n const comp = field.components.find((p) => {\n const otherMeta = p.otherMetadata();\n const cstr = getConstructorFromTaggedId(f.value as string);\n // tagged ids from subclasses always map to the base class, so we should compare to the base class if we don't directly match\n return otherMeta.cstr === cstr || otherMeta.baseType === cstr.name;\n });\n if (!comp) fail(`Invalid tagged id passed to ${meta.type}.${key}: ${f.value}`);\n const column = field.serde.columns.find((c) => c.columnName === comp.columnName)!;\n targetCb.addValueFilter(fa, column, f);\n } else if (f.kind === \"is-null\") {\n // Add a condition for every component--these can be AND-d with the rest of the simple/inline conditions\n field.components.forEach((comp) => {\n const column = field.serde.columns.find((c) => c.columnName === comp.columnName)!;\n targetCb.addSimpleCondition({\n kind: \"column\",\n alias: fa,\n column: comp.columnName,\n dbType: column.dbType,\n cond: f,\n });\n });\n } else if (f.kind === \"not-null\") {\n const conditions = field.components.map((comp) => {\n const column = field.serde.columns.find((c) => c.columnName === comp.columnName)!;\n return {\n kind: \"column\",\n alias: fa,\n column: comp.columnName,\n dbType: column.dbType,\n cond: { kind: \"not-null\" },\n };\n }) satisfies ColumnCondition[];\n targetCb.addParsedExpression({ kind: \"exp\", op: \"or\", conditions });\n } else if (f.kind === \"in\") {\n // An empty `in` matches nothing, so emit a single always-false condition (consistent\n // with a non-poly m2o `{ relation: [] }`); otherwise grouping by constructor would yield\n // zero conditions and prune the filter entirely, incorrectly matching every row.\n if (f.value.length === 0) {\n targetCb.addValueFilter(fa, field.serde.columns[0], { kind: \"in\", value: [] });\n return;\n }\n // Split up the ids by constructor\n const idsByConstructor = groupBy(f.value, (id) => getConstructorFromTaggedId(id as string).name);\n // Or together `parent_book_id in (1,2,3) OR parent_author_id IN (4,5,6)`\n // ...if there is a `parent IN [b:1, b:2, a:1, null]` we'd need to pull the `null` out and do an `OR (all columns are null)`...\n const conditions = Object.entries(idsByConstructor).map(([cstrName, ids]) => {\n const column =\n field.serde.columns.find(\n // tagged ids from subclasses always map to the base class, so we should compare to the base class if we don't directly match\n (c) => c.otherMetadata().cstr.name === cstrName || c.otherMetadata().baseType === cstrName,\n ) ?? fail(`Invalid tagged ids passed to ${meta.type}.${key}: ${ids}`);\n return {\n kind: \"column\",\n alias: fa,\n column: column.columnName,\n dbType: column.dbType,\n cond: mapToDb(column, { kind: \"in\", value: ids }),\n } satisfies ColumnCondition;\n });\n targetCb.addParsedExpression({ kind: \"exp\", op: \"or\", conditions });\n } else {\n throw new Error(`Filters on polys for ${f.kind} are not supported`);\n }\n }\n } else if (field.kind === \"o2o\") {\n // We have to always join into o2os, i.e. we can't probe the filter like we do for m2os\n const otherMeta = field.otherMetadata();\n const a = getAlias(otherMeta.tableName);\n const otherField = otherMeta.allFields[field.otherFieldName];\n const otherColumn =\n // if our other is a poly, we need to find a matching column rather than just picking the first\n otherField.kind === \"poly\"\n ? otherField.components.find((c) => c.otherMetadata() === meta || c.otherMetadata() === getBaseMeta(meta))!\n .columnName\n : otherField.serde!.columns[0].columnName;\n addTable(\n field.otherMetadata(),\n a,\n \"outer\",\n kqDot(tableAlias, \"id\"),\n kqDot(a, otherColumn),\n (subFilter as any)[key],\n field.otherFieldName,\n targetCb,\n );\n } else if (field.kind === \"o2m\") {\n const otherMeta = field.otherMetadata();\n const otherField = otherMeta.allFields[field.otherFieldName];\n let otherColumn = otherField.serde!.columns[0].columnName;\n if (otherField.kind === \"poly\") {\n const otherComponent =\n otherField.components.find((c) => c.otherMetadata() === meta) ??\n fail(`No poly component found for ${otherField.fieldName}`);\n otherColumn = otherComponent.columnName;\n }\n const isCtiBaseFk =\n otherMeta.inheritanceType === \"cti\" && field.otherFieldName && !(field.otherFieldName in otherMeta.fields);\n const a = getAlias(otherMeta.tableName);\n addTable(\n otherMeta,\n a,\n \"outer\",\n kqDot(tableAlias, \"id\"),\n kqDot(a, otherColumn),\n (subFilter as any)[key],\n field.otherFieldName,\n targetCb,\n true,\n );\n if (!isCtiBaseFk) {\n const table = tables.find((t) => t.alias === a);\n if (table && (table.join === \"inner\" || table.join === \"outer\")) {\n table.collection = { parentAlias: tableAlias, rootAlias: a, kind: \"o2m\" };\n }\n }\n } else if (field.kind === \"m2m\") {\n const sub = (subFilter as any)[key];\n const f = parseEntityFilter(field.otherMetadata(), sub);\n if (!f && !isAlias(sub)) return;\n\n const ja = getAlias(field.joinTableName);\n tables.push({\n join: \"outer\",\n alias: ja,\n table: field.joinTableName,\n col1: kqDot(tableAlias, \"id\"),\n col2: kqDot(ja, field.columnNames[0]),\n collection: { parentAlias: tableAlias, rootAlias: ja, kind: \"m2m\" },\n });\n\n if (isAlias(sub) || f?.kind === \"join\" || filterSoftDeletes(field.otherMetadata(), softDeletes)) {\n const a = getAlias(field.otherMetadata().tableName);\n addTable(\n field.otherMetadata(),\n a,\n \"outer\",\n kqDot(ja, field.columnNames[1]),\n kqDot(a, \"id\"),\n sub,\n undefined,\n targetCb,\n true,\n );\n const table = tables.find((t) => t.alias === a);\n if (table && (table.join === \"inner\" || table.join === \"outer\")) {\n table.collection = { parentAlias: ja, rootAlias: ja, kind: \"m2m\" };\n }\n } else if (f) {\n const otherMeta = field.otherMetadata();\n const column: any = {\n columnName: field.columnNames[1],\n dbType: otherMeta.idDbType,\n mapToDb(value: any) {\n return value === null || isNilIdValue(value)\n ? value\n : keyToNumber(otherMeta, maybeResolveReferenceToId(value));\n },\n };\n targetCb.addSimpleCondition({\n kind: \"column\",\n alias: ja,\n column: field.columnNames[1],\n dbType: otherMeta.idDbType,\n cond: mapToDb(column, f),\n });\n }\n } else if (field.kind === \"m2mEnum\") {\n // Membership filter, e.g. `{ logoColors: Color.Red }` / `{ logoColors: [Red, Green] }`: join the\n // join table and filter its enum-id column, mapping enum codes -> their numeric ids.\n const ja = getAlias(field.joinTableName);\n tables.push({\n join: \"outer\",\n alias: ja,\n table: field.joinTableName,\n col1: kqDot(tableAlias, \"id\"),\n col2: kqDot(ja, field.columnNames[0]),\n collection: { parentAlias: tableAlias, rootAlias: ja, kind: \"m2m\" },\n });\n const column: any = {\n columnName: field.columnNames[1],\n dbType: \"int\",\n mapToDb(value: any) {\n return value === null || value === undefined ? value : field.enumDetailType.getByCode(value).id;\n },\n };\n parseValueFilter((subFilter as any)[key]).forEach((filter) => {\n targetCb.addValueFilter(ja, column, filter);\n });\n } else {\n throw new Error(`Unsupported field ${key}`);\n }\n });\n }\n\n function addLogicalFilter(\n meta: EntityMetadata,\n tableAlias: string,\n op: \"and\" | \"or\",\n value: unknown,\n targetCb: ConditionBuilder,\n parentJoin: ParsedTable[\"join\"],\n ): void {\n const filters = Array.isArray(value) ? value : [value];\n const conditions = filters.flatMap((filter) => {\n const branchCb = new ConditionBuilder();\n addFilterAt(meta, tableAlias, filter, branchCb, undefined, parentJoin);\n const condition = branchCb.toExpressionFilter();\n return condition ? [condition] : [];\n });\n if (conditions.length > 0) targetCb.addParsedExpression({ kind: \"exp\", op, conditions });\n }\n\n function addOrderBy(meta: EntityMetadata, alias: string, orderBy: Record<string, any>): void {\n const entries = Object.entries(orderBy);\n if (entries.length === 0) return;\n for (const [key, value] of entries) {\n if (!value) continue; // prune undefined\n const field = meta.allFields[key] ?? fail(`${key} not found on ${meta.tableName}`);\n if (field.kind === \"primitive\" || field.kind === \"primaryKey\" || field.kind === \"enum\") {\n const column = field.serde.columns[0];\n orderBys.push({\n alias: `${alias}${field.aliasSuffix ?? \"\"}`,\n column: column.columnName,\n order: value as OrderBy,\n });\n } else if (field.kind === \"m2o\") {\n // Do we already this table joined in?\n let table = tables.find((t) => t.table === field.otherMetadata().tableName);\n if (table) {\n addTablePerClassJoinsAndClassTag(query, field.otherMetadata(), table.alias, false);\n addOrderBy(field.otherMetadata(), table.alias, value);\n } else {\n const table = field.otherMetadata().tableName;\n const a = getAlias(table);\n const column = field.serde.columns[0].columnName;\n const fa = getMaybeCtiAlias(meta, field, meta, alias);\n // If we don't have a join, don't force this to be an inner join\n tables.push({\n alias: a,\n table,\n join: \"outer\",\n col1: kqDot(fa, column),\n col2: kqDot(a, \"id\"),\n distinct: false,\n });\n addTablePerClassJoinsAndClassTag(query, field.otherMetadata(), a, false);\n addOrderBy(field.otherMetadata(), a, value);\n }\n } else {\n throw new Error(`Unsupported field ${key}`);\n }\n }\n }\n\n // always add the main table\n const alias = getAlias(meta.tableName);\n if (meta.hasLazyColumns) {\n selects.push(...lazyExcludedSelects(meta, alias));\n } else {\n selects.push(`${kq(alias)}.*`);\n }\n addTable(meta, alias, \"primary\", \"n/a\", \"n/a\", filter);\n\n // If they passed extra `conditions: ...`, parse that\n if (optsExpression) {\n checkDomainCondition(optsExpression);\n cb.maybeAddExpression(optsExpression);\n }\n\n Object.assign(query, {\n condition: cb.toExpressionFilter(),\n });\n\n // Resolve alias-built conditions against this parse's bindings, before anything reads their\n // aliases (the id-not-null injection just below, and join pruning)\n resolveAliasConditions(query, aliasBindings);\n\n if (query.tables.some((t) => t.join === \"outer\")) {\n maybeAddIdNotNulls(query);\n }\n\n if (orderBy) {\n if (Array.isArray(orderBy)) {\n for (const ob of orderBy) addOrderBy(meta, alias, ob);\n } else {\n addOrderBy(meta, alias, orderBy);\n }\n }\n maybeAddOrderBy(query, meta, alias);\n\n if (pruneJoins) {\n pruneUnusedJoins(query, keepAliases);\n }\n return query;\n}\n\n/**\n * Look for conditions doing `some_column IS NULL` in an outer join that\n * need an `id IS NOT NULL` to make sure they don't match inadvertently on\n * the child row simply not existing.\n *\n * Note: Instead of injecting an extra `id IS NOT NULL` condition, I had tried\n * using all INNER JOINs and flipping joins to OUTER only if the user explicit\n * had `id IS NULL` in their filter, but that didn't work for queries that wanted\n * to do an `OR` across two different children (which queries both children being\n * OUTER JOINs, and detecting that case seemed complicated).\n */\nexport function maybeAddIdNotNulls(query: ParsedFindQuery): void {\n visitConditions(query, {\n visitCond(c: ColumnCondition) {\n // Check `c.prunable` to make sure we don't catch our injected `deleted_at is null` conditions\n if (c.cond.kind !== \"is-null\" || c.column === \"id\" || c.pruneable) {\n return c;\n }\n // This is an `some_column IS NULL`, is it in an outer join?\n const table = query.tables.find((t) => t.alias === c.alias);\n if (table && table.join === \"outer\") {\n const meta = getMetadataForTable(table.table);\n return {\n kind: \"exp\",\n op: \"and\",\n conditions: [\n c,\n {\n kind: \"column\",\n alias: c.alias,\n column: \"id\",\n dbType: meta.idDbType,\n cond: { kind: \"not-null\" },\n },\n ],\n } satisfies ParsedExpressionFilter;\n }\n return c;\n },\n });\n}\n\n/** Returns the `a` from `\"a\".*`. */\nexport function parseAlias(alias: string): string {\n return alias.split(\".\")[0].replaceAll(`\"`, \"\");\n}\n\n/** Finds a filter field by fieldName or generated fieldIdName. */\nexport function findFilterField(meta: EntityMetadata, key: string): (Field & { aliasSuffix: string }) | undefined {\n return (\n meta.allFields[key] ??\n meta.polyComponentFields?.[key] ??\n Object.values(meta.allFields).find((field) => field.fieldIdName === key) ??\n Object.values(meta.polyComponentFields ?? {}).find((field) => field.fieldIdName === key)\n );\n}\n\n/** Adds any user-configured default order, plus an \"always order by id\" for determinism. */\nexport function maybeAddOrderBy(query: ParsedFindQuery, meta: EntityMetadata, alias: string): void {\n const { orderBys } = query;\n if (meta.orderBy) {\n const field = meta.allFields[meta.orderBy] ?? fail(`${meta.orderBy} not found on ${meta.tableName}`);\n const column = field.serde!.columns[0].columnName;\n const hasAlready = orderBys.find((o) => o.alias === alias && o.column === column);\n if (!hasAlready) {\n orderBys.push({ alias, column, order: \"ASC\" });\n }\n }\n // Even if they already added orders, add id as the last one to get deterministic output\n const hasIdOrder = orderBys.find((o) => o.alias === alias && o.column === \"id\");\n if (!hasIdOrder) {\n orderBys.push({ alias, column: \"id\", order: \"ASC\" });\n }\n}\n\nexport function addTablePerClassJoinsAndClassTag(\n query: ParsedFindQuery,\n meta: EntityMetadata,\n alias: string,\n isPrimary: boolean,\n): void {\n if (!needsClassPerTableJoins(meta)) return;\n const { selects, tables } = query;\n // When `.load(SmallPublisher)` is called, join in base tables like `Publisher`\n meta.baseTypes.forEach((bt, i) => {\n if (isPrimary) {\n selects.push(`${alias}_b${i}.*`);\n }\n tables.push({\n alias: `${alias}_b${i}`,\n table: bt.tableName,\n join: \"outer\",\n col1: kqDot(alias, \"id\"),\n col2: `${alias}_b${i}.id`,\n distinct: false,\n });\n });\n\n // We always join in the base table in case a query happens to use\n // it as a filter, but we only need to do the subtype joins + selects\n // if this is the primary table\n if (isPrimary) {\n // Watch for subTypes that share column names. It'd be great to do\n // this statically at codegen time, like a meta.sharedSubtypeColumns.\n const stColumns: { stAlias: string; columnName: string }[] = [];\n\n // When `.load(Publisher)` is called, join in sub tables like `SmallPublisher` and `LargePublisher`\n meta.subTypes.forEach((st, i) => {\n const stAlias = `${alias}_s${i}`;\n selects.push(`${stAlias}.*`);\n tables.push({\n alias: stAlias,\n table: st.tableName,\n join: \"outer\",\n col1: kqDot(alias, \"id\"),\n col2: `${alias}_s${i}.id`,\n distinct: false,\n });\n for (const field of Object.values(st.fields)) {\n if (field.fieldName !== \"id\" && field.serde) {\n for (const c of field.serde?.columns) {\n stColumns.push({ stAlias, columnName: c.columnName });\n }\n }\n }\n });\n\n // Nominate a specific `id` column to avoid ambiguity\n selects.push(`${kq(alias)}.id as id`);\n\n // Add an explicit coalesce for shared columns\n Object.values(groupBy(stColumns, (c) => c.columnName))\n .filter((columns) => columns.length > 1)\n .forEach((columns) => {\n const { columnName } = columns[0];\n selects.push(`COALESCE(${columns.map((c) => `${c.stAlias}.${columnName}`).join(\", \")}) as ${columnName}`);\n });\n\n // If our meta has no subtypes, we're a left type and don't need a __class\n const cases = meta.subTypes.map((st, i) => `WHEN ${alias}_s${i}.id IS NOT NULL THEN '${st.type}'`);\n if (cases.length > 0) {\n selects.push(`CASE ${cases.join(\" \")} ELSE '_' END as __class`);\n }\n }\n}\n\n/** Rejects SQL predicates throughout a domain condition tree before optional-filter pruning. */\nfunction checkDomainCondition(condition: ConditionInput | undefined): void {\n if (!condition) return;\n if (isDeferredCondition(condition) || (predicateBrand in condition && condition[predicateBrand] === \"sql\")) {\n fail(\"SQL predicates are only supported by em.query/em.execute; use alias(...) predicates in em.find and scopes.\");\n }\n if (\"and\" in condition && condition.and) {\n for (const child of condition.and) checkDomainCondition(child);\n } else if (\"or\" in condition && condition.or) {\n for (const child of condition.or) checkDomainCondition(child);\n }\n}\n\n/** Resolves every `DeferredAliasCondition` in `query` against the parse's alias bindings. */\nfunction resolveAliasConditions(\n query: ParsedFindQuery,\n bindings: Map<AliasMgmt, { meta: EntityMetadata; alias: string }>,\n): void {\n function resolve(handle: AliasMgmt): { meta: EntityMetadata; alias: string } {\n return bindings.get(handle) ?? fail(`Alias for ${handle.tableName} is not bound to this query's join literal`);\n }\n function maybeResolve<C extends ColumnCondition | RawCondition>(c: C): C | undefined {\n return isDeferredAliasCondition(c) ? c[deferredAliasSym](resolve) : undefined;\n }\n visitConditions(query, { visitCond: maybeResolve, visitRaw: maybeResolve });\n}\n\nexport function getTables(query: ParsedFindQuery): [PrimaryTable, JoinTable[], LateralJoinTable[], CrossJoinTable[]] {\n let primary: PrimaryTable;\n const joins: JoinTable[] = [];\n const laterals: LateralJoinTable[] = [];\n const crosses: CrossJoinTable[] = [];\n for (const table of query.tables) {\n if (table.join === \"primary\") {\n primary = table;\n } else if (table.join === \"lateral\") {\n laterals.push(table);\n } else if (table.join === \"cross\") {\n crosses.push(table);\n } else {\n joins.push(table);\n }\n }\n return [primary!, joins, laterals, crosses];\n}\n\nfunction needsClassPerTableJoins(meta: EntityMetadata): boolean {\n return meta.inheritanceType === \"cti\" && (meta.subTypes.length > 0 || meta.baseTypes.length > 0);\n}\n\nfunction needsStiDiscriminator(meta: EntityMetadata): boolean {\n return meta.inheritanceType === \"sti\" && !meta.stiDiscriminatorField;\n}\n\nfunction addStiSubtypeFilter(cb: ConditionBuilder, subtypeMeta: EntityMetadata, alias: string): void {\n const cond = stiSubtypeFilter(subtypeMeta, alias);\n if (cond) cb.addSimpleCondition(cond);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"QueryParser.js","names":["newAlias","alias"],"sources":["../../../src/queries/find/QueryParser.ts"],"sourcesContent":["import { groupBy } from \"joist-utils\";\nimport { getConstructorFromTaggedId, getMetadataForTable } from \"src/configure.ts\";\nimport type { Entity } from \"src/Entity.ts\";\nimport { type EntityMetadata, type Field, getBaseMeta } from \"src/EntityMetadata.ts\";\nimport { keyToNumber, maybeResolveReferenceToId } from \"src/keys.ts\";\nimport { ConditionBuilder } from \"src/queries/ConditionBuilder.ts\";\nimport { type ConditionInput, predicateBrand } from \"src/queries/conditions.ts\";\nimport { filterSoftDeletes, lazyExcludedSelects, stiSubtypeFilter } from \"src/queries/entityQueryUtils.ts\";\nimport {\n type AliasMgmt,\n getAliasMgmt,\n getMaybeCtiAlias,\n isAlias,\n alias as newAlias,\n} from \"src/queries/find/Aliases.ts\";\nimport { deferredAliasSym, isDeferredAliasCondition } from \"src/queries/find/DeferredAlias.ts\";\nimport type { ExpressionFilter, OrderBy } from \"src/queries/find/EntityFilter.ts\";\nimport { pruneUnusedJoins } from \"src/queries/find/QueryParser.pruning.ts\";\nimport { visitConditions } from \"src/queries/find/QueryVisitor.ts\";\nimport { type Scope, isScope, isScopeJoinFilter, resolveScope } from \"src/queries/find/scopes.ts\";\nimport type { ColumnCondition, ParsedExpressionFilter, RawCondition } from \"src/queries/parsedConditions.ts\";\nimport { isDeferredCondition } from \"src/queries/sql/Expr.ts\";\nimport { kq, kqDot } from \"src/queries/sql/keywords.ts\";\nimport {\n type ParsedEntityFilter,\n isNilIdValue,\n mapToDb,\n parseEntityFilter,\n parseValueFilter,\n} from \"src/queries/valueFilters.ts\";\nimport { abbreviation, fail } from \"src/utils.ts\";\n\n// `skipCondition` lives in its own leaf module, shared by domain aliases and SQL expressions\n// without a load-order cycle; `index.ts` re-exports it directly.\n\nexport interface PrimaryTable {\n join: \"primary\";\n alias: string;\n table: string;\n}\n\nexport interface JoinTable {\n join: \"inner\" | \"outer\";\n alias: string;\n table: string;\n col1: string;\n col2: string;\n distinct?: boolean;\n /**\n * Metadata used by `optimizeCollectionJoins` to rewrite collection joins into EXISTS.\n *\n * I.e. for `Author.books.reviews`:\n * ```sql\n * authors a\n * LEFT JOIN books b ON a.id = b.author_id\n * LEFT JOIN book_reviews br ON b.id = br.book_id\n * ```\n * `books b` has `parentAlias: \"a\"` and `rootAlias: \"b\"`, while `book_reviews br` has\n * `parentAlias: \"b\"` and `rootAlias: \"br\"`.\n *\n * I.e. for `Author.tags`, the m2m join table is the collection root:\n * ```sql\n * authors a\n * LEFT JOIN authors_to_tags att ON a.id = att.author_id\n * LEFT JOIN tags t ON att.tag_id = t.id\n * ```\n * `authors_to_tags att` has `alias: \"att\"` and `rootAlias: \"att\"`, while `tags t` has `alias: \"t\"`\n * but still has `rootAlias: \"att\"` because it belongs to the m2m subtree rooted at the join table.\n */\n collection?: {\n /** The collection relation type, i.e. `o2m` for `Author.books`, or `m2m` for `Author.tags`. */\n kind: \"o2m\" | \"m2m\";\n /** The alias that owns this collection path, i.e. `a` for `Author.books`, or `att` for `Author.tags -> tags`. */\n parentAlias: string;\n /** The top-level alias in this collection subtree, i.e. `b` for `Author.books.reviews`, or `att` for `Author.tags`. */\n rootAlias: string;\n };\n}\n\n/**\n * Creates a `CROSS JOIN`, currently used for our `em.find` batching.\n *\n * I.e. queries like:\n *\n * ```sql\n * WITH _find (tag, arg1, arg2) AS (VALUES\n * (0::int, 'a'::varchar, 'a'::varchar),\n * (1, 'b', 'b'),\n * (2, 'c', 'c')\n * )\n * SELECT a.*, array_agg(_find.tag) AS _tags\n * FROM authors a\n * CROSS JOIN _find AS _find\n * WHERE a.first_name = _find.arg0 OR a.last_name = _find.arg1\n * GROUP BY a.id\n * ```\n */\nexport interface CrossJoinTable {\n join: \"cross\";\n /** The new alias for the joined table. */\n alias: string;\n /** The table name to join into the query. */\n table: string;\n}\n\n/**\n * Adds `WITH` CTE clauses to the query.\n *\n * I.e. queries like:\n *\n * ```sql\n * WITH _find (tag, arg0, arg1) AS (\n * VALUES ($1::int, $2::character varying, $3::character varying), ($4, $5, $6)\n * )\n * ```\n */\nexport interface ParsedCteClause {\n /** The new alias for the CTE, i.e. `_find` in the above query. */\n alias: string;\n /** The columns, i.e. `tag, arg0, arg1` in the above query. */\n columns?: { columnName: string; dbType: string }[];\n /** The subquery for the AS of the CTE clause. */\n query: { kind: \"raw\"; sql: string; bindings: readonly any[] } | { kind: \"ast\"; query: ParsedFindQuery };\n /** Whether to include a `RECURSIVE` keyword after the `WITH`. */\n recursive?: boolean;\n}\n\n/**\n * Creates `LATERAL JOIN`s, currently used by `findCount` and JSON preloading.\n */\nexport interface LateralJoinTable {\n join: \"lateral\";\n alias: string;\n /** Used for join dependency tracking. */\n fromAlias: string;\n /** Used more for bookkeeping/consistency with other join tables than the query itself. */\n table: string;\n /** The subquery that will look for/roll-up N children. */\n query: ParsedFindQuery;\n /** Optional settings for the subquery, i.e. per-parent pagination. */\n settings?: { limit?: number; offset?: number };\n}\n\nexport type ParsedTable = PrimaryTable | JoinTable | CrossJoinTable | LateralJoinTable;\n\nexport interface ParsedOrderBy {\n alias: string;\n column: string;\n order: OrderBy;\n}\n\nexport type ParsedGroupBy = { alias: string; column: string } | { expression: string };\n\nexport type ParsedSelect = string | ParsedSelectWithBindings;\ntype ParsedSelectWithBindings = { sql: string; bindings: any[]; aliases: string[] };\n\n/** The result of parsing an `em.find` filter. */\nexport interface ParsedFindQuery {\n selects: ParsedSelect[];\n /** The primary table plus any joins. */\n tables: ParsedTable[];\n /** The query's conditions. */\n condition?: ParsedExpressionFilter;\n /** Extremely optional group bys; we generally don't support adhoc/aggregate queries, but the auto-batching infra uses these. */\n groupBys?: ParsedGroupBy[];\n /** Any optional orders to add before the default 'order by id'. */\n orderBys: ParsedOrderBy[];\n /** Optional CTE to prefix to the query, i.e. for recursive relations. */\n ctes?: ParsedCteClause[];\n}\n\n/**\n * Parses an `em.find` filter into a logical `ParsedFindQuery` AST, leaving optimization/pruning to callers.\n *\n * The main execution flow is:\n * parseFindQuery -> beforeFind plugins -> optimizeCollectionJoins -> pruneUnusedJoins -> execute SQL.\n */\nexport function parseFindQuery(\n meta: EntityMetadata,\n filter: any,\n opts: {\n conditions?: ExpressionFilter;\n orderBy?: any;\n pruneJoins?: boolean;\n keepAliases?: string[];\n softDeletes?: \"include\" | \"exclude\";\n allowMultipleLeftJoins?: boolean;\n optimizeJoinsToExists?: boolean;\n } = {},\n): ParsedFindQuery {\n const selects: string[] = [];\n const tables: ParsedTable[] = [];\n const orderBys: ParsedOrderBy[] = [];\n const query: ParsedFindQuery = { selects, tables, orderBys };\n const { orderBy, conditions: optsExpression, softDeletes = \"exclude\", pruneJoins = false, keepAliases = [] } = opts;\n const cb = new ConditionBuilder();\n // Where each user-created `alias(...)` is bound in this parse's join literal; alias-built conditions\n // (`a.firstName.eq(...)`) are resolved against it once the whole tree is walked\n const aliasBindings = new Map<AliasMgmt, { meta: EntityMetadata; alias: string }>();\n\n const aliases: Record<string, number> = {};\n function getAlias(tableName: string): string {\n const abbrev = abbreviation(tableName);\n const i = aliases[abbrev] || 0;\n aliases[abbrev] = i + 1;\n return i === 0 ? abbrev : `${abbrev}${i}`;\n }\n\n /** Adds a `deleted_at IS NULL` condition for `alias`, i.e. for the primary table or a collection join. */\n function addSoftDeleteCondition(meta: EntityMetadata, alias: string, targetCb: ConditionBuilder): void {\n if (filterSoftDeletes(meta, softDeletes)) {\n const column = meta.allFields[getBaseMeta(meta).timestampFields!.deletedAt!].serde?.columns[0]!;\n targetCb.addSimpleCondition({\n kind: \"column\",\n alias,\n column: column.columnName,\n dbType: column.dbType,\n cond: { kind: \"is-null\" },\n pruneable: true,\n });\n }\n }\n\n function addTable(\n meta: EntityMetadata,\n alias: string,\n join: ParsedTable[\"join\"],\n col1: string,\n col2: string,\n filter: any,\n fieldName?: string,\n targetCb: ConditionBuilder = cb,\n /** Whether this table is the \"other side\" of a collection, i.e. `books` in `em.find(Author, { books: ... })`. */\n isCollection: boolean = false,\n ): void {\n // look at filter, is it `{ book: \"b2\" }` or `{ book: { ... } }`\n const scopeFilter = isScope(filter);\n const ef = scopeFilter ? undefined : parseEntityFilter(meta, filter);\n if (!scopeFilter && !ef && join !== \"primary\" && !isAlias(filter)) {\n return;\n }\n\n if (join === \"primary\") {\n tables.push({ alias, table: meta.tableName, join });\n addTablePerClassJoinsAndClassTag({ selects, tables, orderBys }, meta, alias, true);\n } else if (meta.inheritanceType === \"cti\" && fieldName && !(fieldName in meta.fields)) {\n // For cti, our meta might be a subtype while the FK is actually on the base table. This should only be the case\n // when the fk is on another table (e.g. o2o/o2m). In these cases, we'll be passed a field name and can verify if\n // its directly in our meta, if not we should assume it's in the base type and join that in first.\n meta.baseTypes.forEach((bt, i) => {\n tables.push({\n alias: `${alias}_b${i}`,\n table: bt.tableName,\n join: \"outer\",\n col1,\n col2: `${kq(`${alias}_b${i}`)}.${col2.split(\".\")[1]}`,\n distinct: false,\n });\n // and we still need to join in our subtype as well in case its own fields are queried against\n tables.push({\n alias: `${alias}`,\n table: meta.tableName,\n join: \"outer\",\n col1: kqDot(alias, \"id\"),\n col2: kqDot(`${alias}_b${i}`, \"id\"),\n distinct: false,\n });\n });\n } else if (join === \"lateral\" || join === \"cross\") {\n fail(\"Unexpected lateral join\");\n } else {\n tables.push({ alias, table: meta.tableName, join, col1, col2 });\n // Maybe only do this if we're the primary, or have a field that needs it?\n addTablePerClassJoinsAndClassTag({ selects, tables, orderBys }, meta, alias, false);\n }\n\n if (needsStiDiscriminator(meta)) {\n addStiSubtypeFilter(targetCb, meta, alias);\n }\n\n // Only the primary table & collection joins filter soft-deletes, to match the in-memory relation\n // semantics of \"o2m/m2m collections filter out soft-deletes, but m2o/o2o references still return\n // them\". I.e. `book.author.get` returns a soft-deleted author, so `em.find(Book, { author: ... })`\n // should still match the book, as long as the book itself is not soft-deleted.\n if (join === \"primary\" || isCollection) {\n addSoftDeleteCondition(meta, alias, targetCb);\n }\n\n // The user's locally declared aliases, i.e. `const [a, b] = aliases(Author, Book)`,\n // aren't guaranteed to line up with the aliases we've assigned internally, like `a`\n // might actually be `a1` if there are two `authors` tables in the query, so push the\n // canonical alias value for the current clause into the Alias.\n if (filter && typeof filter === \"object\" && \"as\" in filter && isAlias(filter.as)) {\n aliasBindings.set(getAliasMgmt(filter.as), { meta, alias });\n } else if (isAlias(filter)) {\n aliasBindings.set(getAliasMgmt(filter), { meta, alias });\n }\n\n addFilterAt(meta, alias, filter, targetCb, ef, join);\n }\n\n function addFilterAt(\n meta: EntityMetadata,\n tableAlias: string,\n filter: any,\n targetCb: ConditionBuilder,\n parsed: ParsedEntityFilter | undefined = parseEntityFilter(meta, filter),\n parentJoin: ParsedTable[\"join\"] = \"primary\",\n ): void {\n if (isScope(filter)) {\n addScopeFilterAt(meta, tableAlias, filter, targetCb, parentJoin);\n } else if (parsed && parsed.kind === \"join\") {\n addSubFilter(meta, tableAlias, parsed.subFilter, targetCb, parentJoin);\n } else if (parsed) {\n const column = meta.fields[\"id\"].serde!.columns[0];\n targetCb.addValueFilter(tableAlias, column, parsed);\n }\n }\n\n function addScopeFilterAt<T extends Entity>(\n meta: EntityMetadata<T>,\n tableAlias: string,\n scope: Scope<T>,\n targetCb: ConditionBuilder,\n parentJoin: ParsedTable[\"join\"],\n ): void {\n for (const fragment of resolveScope(scope).fragments) {\n if (fragment.kind === \"filter\") {\n addFilterAt(meta, tableAlias, fragment.filter, targetCb, undefined, parentJoin);\n } else {\n const a = newAlias(meta.cstr);\n const result = fragment.fn(a);\n aliasBindings.set(getAliasMgmt(a), { meta, alias: tableAlias });\n if (isScopeJoinFilter(result)) {\n // Parse the join tree first so its `as:` bindings re-root the aliases that\n // `conditions` reference, then add the conditions against the now-bound aliases.\n addFilterAt(meta, tableAlias, result.where, targetCb, undefined, parentJoin);\n checkDomainCondition(result.conditions);\n targetCb.maybeAddExpression(result.conditions);\n } else {\n const conditions = Array.isArray(result) ? result : [result];\n for (const condition of conditions) checkDomainCondition(condition);\n if (conditions.length > 0) targetCb.maybeAddExpression({ and: conditions });\n }\n }\n }\n }\n\n function addSubFilter(\n meta: EntityMetadata,\n tableAlias: string,\n subFilter: object,\n targetCb: ConditionBuilder,\n parentJoin: ParsedTable[\"join\"],\n ): void {\n // subFilter really means we're matching against the entity columns/further joins\n Object.keys(subFilter).forEach((key) => {\n // Skip the `{ as: ... }` alias binding\n if (key === \"as\") return;\n if (key === \"and\" || key === \"or\") {\n addLogicalFilter(meta, tableAlias, key, (subFilter as any)[key], targetCb, parentJoin);\n return;\n }\n const field = findFilterField(meta, key) ?? fail(`Field '${key}' not found on ${meta.tableName}`);\n const fa = `${tableAlias}${field.aliasSuffix}`;\n if (field.kind === \"primitive\" || field.kind === \"primaryKey\" || field.kind === \"enum\") {\n const column = field.serde.columns[0];\n parseValueFilter((subFilter as any)[key]).forEach((filter) => {\n targetCb.addValueFilter(fa, column, filter);\n });\n } else if (field.kind === \"m2o\") {\n const column = field.serde.columns[0];\n const sub = (subFilter as any)[key];\n const joinKind = field.required && parentJoin !== \"outer\" ? \"inner\" : \"outer\";\n if (isAlias(sub)) {\n const a = getAlias(field.otherMetadata().tableName);\n addTable(\n field.otherMetadata(),\n a,\n joinKind,\n kqDot(fa, column.columnName),\n kqDot(a, \"id\"),\n sub,\n undefined,\n targetCb,\n );\n }\n const f = parseEntityFilter(field.otherMetadata(), sub);\n // Probe the filter and see if it's just an id, if so we can avoid the join; m2os don't need\n // a join for soft-delete filtering because references don't filter out soft-deletes.\n if (!f) {\n // skip\n } else if (f.kind === \"join\") {\n const a = getAlias(field.otherMetadata().tableName);\n addTable(\n field.otherMetadata(),\n a,\n joinKind,\n kqDot(fa, column.columnName),\n kqDot(a, \"id\"),\n sub,\n undefined,\n targetCb,\n );\n } else {\n targetCb.addValueFilter(fa, column, f);\n }\n } else if (field.kind === \"poly\") {\n const f = parseEntityFilter(meta, (subFilter as any)[key]);\n if (!f) {\n // skip\n } else if (f.kind === \"join\") {\n throw new Error(\"Joins through polys are not supported\");\n } else {\n // We're left with basically a ValueFilter against the ids\n // For now only support eq/ne/in/is-null\n if (f.kind === \"eq\" || f.kind === \"ne\") {\n if (isNilIdValue(f.value)) return;\n const comp = field.components.find((p) => {\n const otherMeta = p.otherMetadata();\n const cstr = getConstructorFromTaggedId(f.value as string);\n // tagged ids from subclasses always map to the base class, so we should compare to the base class if we don't directly match\n return otherMeta.cstr === cstr || otherMeta.baseType === cstr.name;\n });\n if (!comp) fail(`Invalid tagged id passed to ${meta.type}.${key}: ${f.value}`);\n const column = field.serde.columns.find((c) => c.columnName === comp.columnName)!;\n targetCb.addValueFilter(fa, column, f);\n } else if (f.kind === \"is-null\") {\n // Add a condition for every component--these can be AND-d with the rest of the simple/inline conditions\n field.components.forEach((comp) => {\n const column = field.serde.columns.find((c) => c.columnName === comp.columnName)!;\n targetCb.addSimpleCondition({\n kind: \"column\",\n alias: fa,\n column: comp.columnName,\n dbType: column.dbType,\n cond: f,\n });\n });\n } else if (f.kind === \"not-null\") {\n const conditions = field.components.map((comp) => {\n const column = field.serde.columns.find((c) => c.columnName === comp.columnName)!;\n return {\n kind: \"column\",\n alias: fa,\n column: comp.columnName,\n dbType: column.dbType,\n cond: { kind: \"not-null\" },\n };\n }) satisfies ColumnCondition[];\n targetCb.addParsedExpression({ kind: \"exp\", op: \"or\", conditions });\n } else if (f.kind === \"in\") {\n // An empty `in` matches nothing, so emit a single always-false condition (consistent\n // with a non-poly m2o `{ relation: [] }`); otherwise grouping by constructor would yield\n // zero conditions and prune the filter entirely, incorrectly matching every row.\n if (f.value.length === 0) {\n targetCb.addValueFilter(fa, field.serde.columns[0], { kind: \"in\", value: [] });\n return;\n }\n // Split up the ids by constructor\n const idsByConstructor = groupBy(f.value, (id) => getConstructorFromTaggedId(id as string).name);\n // Or together `parent_book_id in (1,2,3) OR parent_author_id IN (4,5,6)`\n // ...if there is a `parent IN [b:1, b:2, a:1, null]` we'd need to pull the `null` out and do an `OR (all columns are null)`...\n const conditions = Object.entries(idsByConstructor).map(([cstrName, ids]) => {\n const column =\n field.serde.columns.find(\n // tagged ids from subclasses always map to the base class, so we should compare to the base class if we don't directly match\n (c) => c.otherMetadata().cstr.name === cstrName || c.otherMetadata().baseType === cstrName,\n ) ?? fail(`Invalid tagged ids passed to ${meta.type}.${key}: ${ids}`);\n return {\n kind: \"column\",\n alias: fa,\n column: column.columnName,\n dbType: column.dbType,\n cond: mapToDb(column, { kind: \"in\", value: ids }),\n } satisfies ColumnCondition;\n });\n targetCb.addParsedExpression({ kind: \"exp\", op: \"or\", conditions });\n } else {\n throw new Error(`Filters on polys for ${f.kind} are not supported`);\n }\n }\n } else if (field.kind === \"o2o\") {\n // We have to always join into o2os, i.e. we can't probe the filter like we do for m2os\n const otherMeta = field.otherMetadata();\n const a = getAlias(otherMeta.tableName);\n const otherField = otherMeta.allFields[field.otherFieldName];\n const otherColumn =\n // if our other is a poly, we need to find a matching column rather than just picking the first\n otherField.kind === \"poly\"\n ? otherField.components.find((c) => c.otherMetadata() === meta || c.otherMetadata() === getBaseMeta(meta))!\n .columnName\n : otherField.serde!.columns[0].columnName;\n addTable(\n field.otherMetadata(),\n a,\n \"outer\",\n kqDot(tableAlias, \"id\"),\n kqDot(a, otherColumn),\n (subFilter as any)[key],\n field.otherFieldName,\n targetCb,\n );\n } else if (field.kind === \"o2m\") {\n const otherMeta = field.otherMetadata();\n const otherField = otherMeta.allFields[field.otherFieldName];\n let otherColumn = otherField.serde!.columns[0].columnName;\n if (otherField.kind === \"poly\") {\n const otherComponent =\n otherField.components.find((c) => c.otherMetadata() === meta) ??\n fail(`No poly component found for ${otherField.fieldName}`);\n otherColumn = otherComponent.columnName;\n }\n const isCtiBaseFk =\n otherMeta.inheritanceType === \"cti\" && field.otherFieldName && !(field.otherFieldName in otherMeta.fields);\n const a = getAlias(otherMeta.tableName);\n addTable(\n otherMeta,\n a,\n \"outer\",\n kqDot(tableAlias, \"id\"),\n kqDot(a, otherColumn),\n (subFilter as any)[key],\n field.otherFieldName,\n targetCb,\n true,\n );\n if (!isCtiBaseFk) {\n const table = tables.find((t) => t.alias === a);\n if (table && (table.join === \"inner\" || table.join === \"outer\")) {\n table.collection = { parentAlias: tableAlias, rootAlias: a, kind: \"o2m\" };\n }\n }\n } else if (field.kind === \"m2m\") {\n const sub = (subFilter as any)[key];\n const f = parseEntityFilter(field.otherMetadata(), sub);\n if (!f && !isAlias(sub)) return;\n\n const ja = getAlias(field.joinTableName);\n tables.push({\n join: \"outer\",\n alias: ja,\n table: field.joinTableName,\n col1: kqDot(tableAlias, \"id\"),\n col2: kqDot(ja, field.columnNames[0]),\n collection: { parentAlias: tableAlias, rootAlias: ja, kind: \"m2m\" },\n });\n\n if (isAlias(sub) || f?.kind === \"join\" || filterSoftDeletes(field.otherMetadata(), softDeletes)) {\n const a = getAlias(field.otherMetadata().tableName);\n addTable(\n field.otherMetadata(),\n a,\n \"outer\",\n kqDot(ja, field.columnNames[1]),\n kqDot(a, \"id\"),\n sub,\n undefined,\n targetCb,\n true,\n );\n const table = tables.find((t) => t.alias === a);\n if (table && (table.join === \"inner\" || table.join === \"outer\")) {\n table.collection = { parentAlias: ja, rootAlias: ja, kind: \"m2m\" };\n }\n } else if (f) {\n const otherMeta = field.otherMetadata();\n const column: any = {\n columnName: field.columnNames[1],\n dbType: otherMeta.idDbType,\n mapToDb(value: any) {\n return value === null || isNilIdValue(value)\n ? value\n : keyToNumber(otherMeta, maybeResolveReferenceToId(value));\n },\n };\n targetCb.addSimpleCondition({\n kind: \"column\",\n alias: ja,\n column: field.columnNames[1],\n dbType: otherMeta.idDbType,\n cond: mapToDb(column, f),\n });\n }\n } else if (field.kind === \"m2mEnum\") {\n // Membership filter, e.g. `{ logoColors: Color.Red }` / `{ logoColors: [Red, Green] }`: join the\n // join table and filter its enum-id column, mapping enum codes -> their numeric ids.\n const ja = getAlias(field.joinTableName);\n tables.push({\n join: \"outer\",\n alias: ja,\n table: field.joinTableName,\n col1: kqDot(tableAlias, \"id\"),\n col2: kqDot(ja, field.columnNames[0]),\n collection: { parentAlias: tableAlias, rootAlias: ja, kind: \"m2m\" },\n });\n const column: any = {\n columnName: field.columnNames[1],\n dbType: \"int\",\n mapToDb(value: any) {\n return value === null || value === undefined ? value : field.enumDetailType.getByCode(value).id;\n },\n };\n parseValueFilter((subFilter as any)[key]).forEach((filter) => {\n targetCb.addValueFilter(ja, column, filter);\n });\n } else {\n throw new Error(`Unsupported field ${key}`);\n }\n });\n }\n\n function addLogicalFilter(\n meta: EntityMetadata,\n tableAlias: string,\n op: \"and\" | \"or\",\n value: unknown,\n targetCb: ConditionBuilder,\n parentJoin: ParsedTable[\"join\"],\n ): void {\n const filters = Array.isArray(value) ? value : [value];\n const conditions = filters.flatMap((filter) => {\n const branchCb = new ConditionBuilder();\n addFilterAt(meta, tableAlias, filter, branchCb, undefined, parentJoin);\n const condition = branchCb.toExpressionFilter();\n return condition ? [condition] : [];\n });\n if (conditions.length > 0) targetCb.addParsedExpression({ kind: \"exp\", op, conditions });\n }\n\n function addOrderBy(meta: EntityMetadata, alias: string, orderBy: Record<string, any>): void {\n const entries = Object.entries(orderBy);\n if (entries.length === 0) return;\n for (const [key, value] of entries) {\n if (!value) continue; // prune undefined\n const field = meta.allFields[key] ?? fail(`${key} not found on ${meta.tableName}`);\n if (field.kind === \"primitive\" || field.kind === \"primaryKey\" || field.kind === \"enum\") {\n const column = field.serde.columns[0];\n orderBys.push({\n alias: `${alias}${field.aliasSuffix ?? \"\"}`,\n column: column.columnName,\n order: value as OrderBy,\n });\n } else if (field.kind === \"m2o\") {\n // Do we already this table joined in?\n let table = tables.find((t) => t.table === field.otherMetadata().tableName);\n if (table) {\n addTablePerClassJoinsAndClassTag(query, field.otherMetadata(), table.alias, false);\n addOrderBy(field.otherMetadata(), table.alias, value);\n } else {\n const table = field.otherMetadata().tableName;\n const a = getAlias(table);\n const column = field.serde.columns[0].columnName;\n const fa = getMaybeCtiAlias(meta, field, meta, alias);\n // If we don't have a join, don't force this to be an inner join\n tables.push({\n alias: a,\n table,\n join: \"outer\",\n col1: kqDot(fa, column),\n col2: kqDot(a, \"id\"),\n distinct: false,\n });\n addTablePerClassJoinsAndClassTag(query, field.otherMetadata(), a, false);\n addOrderBy(field.otherMetadata(), a, value);\n }\n } else {\n throw new Error(`Unsupported field ${key}`);\n }\n }\n }\n\n // always add the main table\n const alias = getAlias(meta.tableName);\n if (meta.hasLazyColumns) {\n selects.push(...lazyExcludedSelects(meta, alias));\n } else {\n selects.push(`${kq(alias)}.*`);\n }\n addTable(meta, alias, \"primary\", \"n/a\", \"n/a\", filter);\n\n // If they passed extra `conditions: ...`, parse that\n if (optsExpression) {\n checkDomainCondition(optsExpression);\n cb.maybeAddExpression(optsExpression);\n }\n\n Object.assign(query, {\n condition: cb.toExpressionFilter(),\n });\n\n // Resolve alias-built conditions against this parse's bindings, before anything reads their\n // aliases (the id-not-null injection just below, and join pruning)\n resolveAliasConditions(query, aliasBindings);\n\n if (query.tables.some((t) => t.join === \"outer\")) {\n maybeAddIdNotNulls(query);\n }\n\n if (orderBy) {\n if (Array.isArray(orderBy)) {\n for (const ob of orderBy) addOrderBy(meta, alias, ob);\n } else {\n addOrderBy(meta, alias, orderBy);\n }\n }\n maybeAddOrderBy(query, meta, alias);\n\n if (pruneJoins) {\n pruneUnusedJoins(query, keepAliases);\n }\n return query;\n}\n\n/**\n * Look for conditions doing `some_column IS NULL` in an outer join that\n * need an `id IS NOT NULL` to make sure they don't match inadvertently on\n * the child row simply not existing.\n *\n * Note: Instead of injecting an extra `id IS NOT NULL` condition, I had tried\n * using all INNER JOINs and flipping joins to OUTER only if the user explicit\n * had `id IS NULL` in their filter, but that didn't work for queries that wanted\n * to do an `OR` across two different children (which queries both children being\n * OUTER JOINs, and detecting that case seemed complicated).\n */\nexport function maybeAddIdNotNulls(query: ParsedFindQuery): void {\n visitConditions(query, {\n visitCond(c: ColumnCondition) {\n // Check `c.prunable` to make sure we don't catch our injected `deleted_at is null` conditions\n if (c.cond.kind !== \"is-null\" || c.column === \"id\" || c.pruneable) {\n return c;\n }\n // This is an `some_column IS NULL`, is it in an outer join?\n const table = query.tables.find((t) => t.alias === c.alias);\n if (table && table.join === \"outer\") {\n const meta = getMetadataForTable(table.table);\n return {\n kind: \"exp\",\n op: \"and\",\n conditions: [\n c,\n {\n kind: \"column\",\n alias: c.alias,\n column: \"id\",\n dbType: meta.idDbType,\n cond: { kind: \"not-null\" },\n },\n ],\n } satisfies ParsedExpressionFilter;\n }\n return c;\n },\n });\n}\n\n/** Returns the `a` from `\"a\".*`. */\nexport function parseAlias(alias: string): string {\n return alias.split(\".\")[0].replaceAll(`\"`, \"\");\n}\n\n/** Finds a filter field by fieldName or generated fieldIdName. */\nexport function findFilterField(meta: EntityMetadata, key: string): (Field & { aliasSuffix: string }) | undefined {\n return (\n meta.allFields[key] ??\n meta.polyComponentFields?.[key] ??\n Object.values(meta.allFields).find((field) => field.fieldIdName === key) ??\n Object.values(meta.polyComponentFields ?? {}).find((field) => field.fieldIdName === key)\n );\n}\n\n/** Adds any user-configured default order, plus an \"always order by id\" for determinism. */\nexport function maybeAddOrderBy(query: ParsedFindQuery, meta: EntityMetadata, alias: string): void {\n const { orderBys } = query;\n if (meta.orderBy) {\n const field = meta.allFields[meta.orderBy] ?? fail(`${meta.orderBy} not found on ${meta.tableName}`);\n const column = field.serde!.columns[0].columnName;\n const hasAlready = orderBys.find((o) => o.alias === alias && o.column === column);\n if (!hasAlready) {\n orderBys.push({ alias, column, order: \"ASC\" });\n }\n }\n // Even if they already added orders, add id as the last one to get deterministic output\n const hasIdOrder = orderBys.find((o) => o.alias === alias && o.column === \"id\");\n if (!hasIdOrder) {\n orderBys.push({ alias, column: \"id\", order: \"ASC\" });\n }\n}\n\nexport function addTablePerClassJoinsAndClassTag(\n query: ParsedFindQuery,\n meta: EntityMetadata,\n alias: string,\n isPrimary: boolean,\n): void {\n if (!needsClassPerTableJoins(meta)) return;\n const { selects, tables } = query;\n // When `.load(SmallPublisher)` is called, join in base tables like `Publisher`\n meta.baseTypes.forEach((bt, i) => {\n if (isPrimary) {\n selects.push(`${alias}_b${i}.*`);\n }\n tables.push({\n alias: `${alias}_b${i}`,\n table: bt.tableName,\n join: \"outer\",\n col1: kqDot(alias, \"id\"),\n col2: `${alias}_b${i}.id`,\n distinct: false,\n });\n });\n\n // We always join in the base table in case a query happens to use\n // it as a filter, but we only need to do the subtype joins + selects\n // if this is the primary table\n if (isPrimary) {\n // Watch for subTypes that share column names. It'd be great to do\n // this statically at codegen time, like a meta.sharedSubtypeColumns.\n const stColumns: { stAlias: string; columnName: string }[] = [];\n\n // When `.load(Publisher)` is called, join in sub tables like `SmallPublisher` and `LargePublisher`\n meta.subTypes.forEach((st, i) => {\n const stAlias = `${alias}_s${i}`;\n selects.push(`${stAlias}.*`);\n tables.push({\n alias: stAlias,\n table: st.tableName,\n join: \"outer\",\n col1: kqDot(alias, \"id\"),\n col2: `${alias}_s${i}.id`,\n distinct: false,\n });\n for (const field of Object.values(st.fields)) {\n if (field.fieldName !== \"id\" && field.serde) {\n for (const c of field.serde?.columns) {\n stColumns.push({ stAlias, columnName: c.columnName });\n }\n }\n }\n });\n\n // Nominate a specific `id` column to avoid ambiguity\n selects.push(`${kq(alias)}.id as id`);\n\n // Add an explicit coalesce for shared columns\n Object.values(groupBy(stColumns, (c) => c.columnName))\n .filter((columns) => columns.length > 1)\n .forEach((columns) => {\n const { columnName } = columns[0];\n selects.push(`COALESCE(${columns.map((c) => `${c.stAlias}.${columnName}`).join(\", \")}) as ${columnName}`);\n });\n\n // If our meta has no subtypes, we're a left type and don't need a __class\n const cases = meta.subTypes.map((st, i) => `WHEN ${alias}_s${i}.id IS NOT NULL THEN '${st.type}'`);\n if (cases.length > 0) {\n selects.push(`CASE ${cases.join(\" \")} ELSE '_' END as __class`);\n }\n }\n}\n\n/** Rejects SQL predicates throughout a domain condition tree before optional-filter pruning. */\nfunction checkDomainCondition(condition: ConditionInput | undefined): void {\n if (!condition) return;\n if (isDeferredCondition(condition) || (predicateBrand in condition && condition[predicateBrand] === \"sql\")) {\n fail(\"SQL predicates are only supported by em.query/em.execute; use alias(...) predicates in em.find and scopes.\");\n }\n if (\"and\" in condition && condition.and) {\n for (const child of condition.and) checkDomainCondition(child);\n } else if (\"or\" in condition && condition.or) {\n for (const child of condition.or) checkDomainCondition(child);\n }\n}\n\n/** Resolves every `DeferredAliasCondition` in `query` against the parse's alias bindings. */\nfunction resolveAliasConditions(\n query: ParsedFindQuery,\n bindings: Map<AliasMgmt, { meta: EntityMetadata; alias: string }>,\n): void {\n function resolve(handle: AliasMgmt): { meta: EntityMetadata; alias: string } {\n return bindings.get(handle) ?? fail(`Alias for ${handle.tableName} is not bound to this query's join literal`);\n }\n function maybeResolve<C extends ColumnCondition | RawCondition>(c: C): C | undefined {\n return isDeferredAliasCondition(c) ? c[deferredAliasSym](resolve) : undefined;\n }\n visitConditions(query, { visitCond: maybeResolve, visitRaw: maybeResolve });\n}\n\nexport function getTables(query: ParsedFindQuery): [PrimaryTable, JoinTable[], LateralJoinTable[], CrossJoinTable[]] {\n let primary: PrimaryTable;\n const joins: JoinTable[] = [];\n const laterals: LateralJoinTable[] = [];\n const crosses: CrossJoinTable[] = [];\n for (const table of query.tables) {\n if (table.join === \"primary\") {\n primary = table;\n } else if (table.join === \"lateral\") {\n laterals.push(table);\n } else if (table.join === \"cross\") {\n crosses.push(table);\n } else {\n joins.push(table);\n }\n }\n return [primary!, joins, laterals, crosses];\n}\n\nfunction needsClassPerTableJoins(meta: EntityMetadata): boolean {\n return meta.inheritanceType === \"cti\" && (meta.subTypes.length > 0 || meta.baseTypes.length > 0);\n}\n\nfunction needsStiDiscriminator(meta: EntityMetadata): boolean {\n return meta.inheritanceType === \"sti\" && !meta.stiDiscriminatorField;\n}\n\nfunction addStiSubtypeFilter(cb: ConditionBuilder, subtypeMeta: EntityMetadata, alias: string): void {\n const cond = stiSubtypeFilter(subtypeMeta, alias);\n if (cond) cb.addSimpleCondition(cond);\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"QueryParser.pruning.cjs","names":["parseAlias"],"sources":["../../../src/queries/find/QueryParser.pruning.ts"],"sourcesContent":["import { assertNever } from \"../../utils.ts\";\nimport { deepFindConditions } from \"../parsedConditions.ts\";\nimport { type JoinTable, type ParsedFindQuery, parseAlias } from \"./QueryParser.ts\";\n\n// Remove any joins that are not used in the select or conditions\nexport function pruneUnusedJoins(parsed: ParsedFindQuery, keepAliases: string[]): void {\n const dt = new DependencyTracker();\n\n // First setup the alias -> alias dependencies...\n const todo = [...parsed.tables];\n while (todo.length > 0) {\n const t = todo.pop()!;\n if (t.join === \"lateral\") {\n dt.addAlias(t.alias, [t.fromAlias]);\n // Recurse into lateral joins...\n todo.push(...t.query.tables);\n } else if (t.join === \"cross\") {\n dt.markRequired(t.alias);\n } else if (t.join === \"primary\") {\n dt.markRequired(t.alias);\n } else if (parsed.ctes?.some((cte) => cte.alias === t.table)) {\n dt.addAlias(t.alias, joinDependencies(t));\n dt.markRequired(t.alias);\n } else {\n dt.addAlias(t.alias, joinDependencies(t));\n }\n }\n\n // Mark all terminal usages\n parsed.selects.forEach((s) => {\n if (typeof s === \"string\") {\n markSelectAliases(dt, parsed, s);\n } else if (\"aliases\" in s) {\n for (const a of s.aliases) dt.markRequired(a);\n markSelectAliases(dt, parsed, s.sql);\n }\n });\n parsed.orderBys.forEach((o) => dt.markRequired(o.alias));\n parsed.groupBys?.forEach((g) => {\n if (\"expression\" in g) {\n markSelectAliases(dt, parsed, g.expression);\n } else {\n dt.markRequired(g.alias);\n }\n });\n keepAliases.forEach((a) => dt.markRequired(a));\n // Look recursively into CTE & lateral join conditions\n const todo2 = [{ query: parsed, filterPruneable: true }];\n while (todo2.length > 0) {\n const { query, filterPruneable } = todo2.pop()!;\n deepFindConditions(query.condition, filterPruneable).forEach((c) => {\n if (c.kind === \"column\") {\n dt.markRequired(c.alias);\n } else if (c.kind === \"raw\") {\n for (const alias of c.aliases) dt.markRequired(alias);\n } else if (c.kind === \"exists\") {\n for (const alias of c.outerAliases) dt.markRequired(alias);\n } else {\n assertNever(c);\n }\n });\n todo2.push(\n ...query.tables.filter((t) => t.join === \"lateral\").map((t) => ({ query: t.query, filterPruneable: false })),\n );\n }\n\n // Now remove any unused joins\n parsed.tables = parsed.tables.filter((t) => dt.required.has(t.alias));\n\n // And then remove any inline soft-delete conditions we don't need anymore\n if (parsed.condition && parsed.condition.op === \"and\") {\n parsed.condition.conditions = parsed.condition.conditions.filter((c) => {\n if (c.kind === \"column\") {\n const prune = c.pruneable && !dt.required.has(c.alias);\n // if (prune) console.log(`DROPPING`, c);\n return !prune;\n } else {\n return c;\n }\n });\n }\n\n // Remove any `{ and: [...] }`s that are empty; we should probably do this deeply?\n if (parsed.condition && parsed.condition.conditions.length === 0) {\n parsed.condition = undefined;\n }\n}\n\n/** Returns the aliases needed to evaluate a join's ON clause, excluding the joined alias itself. */\nfunction joinDependencies(t: JoinTable): string[] {\n return [parseAlias(t.col1), parseAlias(t.col2)].filter((alias) => alias !== t.alias);\n}\n\n/** Marks aliases used by select strings, including generated CTI expressions like `COALESCE(st0.col, st1.col)`. */\nfunction markSelectAliases(dt: DependencyTracker, parsed: ParsedFindQuery, select: string): void {\n for (const table of parsed.tables) {\n if (selectReferencesAlias(select, table.alias)) {\n dt.markRequired(table.alias);\n }\n }\n}\n\n/** Returns true if a raw select expression references `alias.column` or the whole-row `alias`. */\nexport function selectReferencesAlias(select: string, alias: string): boolean {\n // Most selects are simple `a.*`, but CTI adds expressions like\n // `COALESCE(p_s0.shared_column, p_s1.shared_column) as shared_column`.\n // Those expressions must keep the subtype joins, but `parseAlias` only sees\n // the leading function name. Instead of parsing SQL, scan for the only alias\n // forms Joist generates in selects: `alias.column`, `\"alias\".column`, and whole-row aliases.\n return (\n selectReferencesCandidate(select, `${alias}.`) ||\n selectReferencesCandidate(select, `\"${alias}\".`) ||\n selectReferencesCandidate(select, alias) ||\n selectReferencesCandidate(select, `\"${alias}\"`)\n );\n}\n\n/**\n * Returns true when `candidate` is present at a SQL identifier boundary.\n *\n * Scans the select string for literal candidate matches, then verifies the characters before/after the match are not\n * part of a larger identifier or dotted path. I.e. `row_to_json(\"ap\")` matches, but `foo_\"ap\"` and `foo.ap` do not.\n */\nfunction selectReferencesCandidate(select: string, candidate: string): boolean {\n let index = select.indexOf(candidate);\n const quoted = candidate.startsWith('\"');\n while (index !== -1) {\n // Each loop inspects one literal occurrence of `candidate`, then either accepts it as a real alias reference or\n // advances to the next occurrence if the surrounding characters show it is part of a larger token.\n // Avoid treating `foo.a.id` as a reference to `a`; Joist-generated aliases\n // appear at the start of an expression or after punctuation/whitespace.\n const previous = select[index - 1];\n const next = select[index + candidate.length];\n if (\n (index === 0 || (previous !== \".\" && !isSqlIdentifierChar(previous))) &&\n !isSqlIdentifierChar(next) &&\n (quoted || (previous !== '\"' && next !== '\"'))\n ) {\n return true;\n }\n // Continue scanning after the current occurrence; `indexOf` returns -1 once there are no more candidates.\n index = select.indexOf(candidate, index + candidate.length);\n }\n return false;\n}\n\n/** Returns true for characters that can be part of an unquoted SQL identifier. */\nfunction isSqlIdentifierChar(char: string | undefined): boolean {\n return char !== undefined && /[A-Za-z0-9_]/.test(char);\n}\n\n/** Track join dependencies for `pruneUnusedJoins`. */\nclass DependencyTracker {\n private nodes: Map<string, string[]> = new Map();\n required: Set<string> = new Set();\n\n addAlias(alias: string, dependencies: string[] = []): void {\n this.nodes.set(alias, dependencies);\n }\n\n markRequired(alias: string): void {\n const marked = new Set<string>();\n const todo = [alias];\n while (todo.length > 0) {\n const alias = todo.pop()!;\n if (!marked.has(alias)) {\n marked.add(alias);\n todo.push(...(this.nodes.get(alias) || []));\n }\n }\n this.required = new Set([...this.required, ...marked]);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"QueryParser.pruning.cjs","names":["parseAlias"],"sources":["../../../src/queries/find/QueryParser.pruning.ts"],"sourcesContent":["import { type JoinTable, type ParsedFindQuery, parseAlias } from \"src/queries/find/QueryParser.ts\";\nimport { deepFindConditions } from \"src/queries/parsedConditions.ts\";\nimport { assertNever } from \"src/utils.ts\";\n\n// Remove any joins that are not used in the select or conditions\nexport function pruneUnusedJoins(parsed: ParsedFindQuery, keepAliases: string[]): void {\n const dt = new DependencyTracker();\n\n // First setup the alias -> alias dependencies...\n const todo = [...parsed.tables];\n while (todo.length > 0) {\n const t = todo.pop()!;\n if (t.join === \"lateral\") {\n dt.addAlias(t.alias, [t.fromAlias]);\n // Recurse into lateral joins...\n todo.push(...t.query.tables);\n } else if (t.join === \"cross\") {\n dt.markRequired(t.alias);\n } else if (t.join === \"primary\") {\n dt.markRequired(t.alias);\n } else if (parsed.ctes?.some((cte) => cte.alias === t.table)) {\n dt.addAlias(t.alias, joinDependencies(t));\n dt.markRequired(t.alias);\n } else {\n dt.addAlias(t.alias, joinDependencies(t));\n }\n }\n\n // Mark all terminal usages\n parsed.selects.forEach((s) => {\n if (typeof s === \"string\") {\n markSelectAliases(dt, parsed, s);\n } else if (\"aliases\" in s) {\n for (const a of s.aliases) dt.markRequired(a);\n markSelectAliases(dt, parsed, s.sql);\n }\n });\n parsed.orderBys.forEach((o) => dt.markRequired(o.alias));\n parsed.groupBys?.forEach((g) => {\n if (\"expression\" in g) {\n markSelectAliases(dt, parsed, g.expression);\n } else {\n dt.markRequired(g.alias);\n }\n });\n keepAliases.forEach((a) => dt.markRequired(a));\n // Look recursively into CTE & lateral join conditions\n const todo2 = [{ query: parsed, filterPruneable: true }];\n while (todo2.length > 0) {\n const { query, filterPruneable } = todo2.pop()!;\n deepFindConditions(query.condition, filterPruneable).forEach((c) => {\n if (c.kind === \"column\") {\n dt.markRequired(c.alias);\n } else if (c.kind === \"raw\") {\n for (const alias of c.aliases) dt.markRequired(alias);\n } else if (c.kind === \"exists\") {\n for (const alias of c.outerAliases) dt.markRequired(alias);\n } else {\n assertNever(c);\n }\n });\n todo2.push(\n ...query.tables.filter((t) => t.join === \"lateral\").map((t) => ({ query: t.query, filterPruneable: false })),\n );\n }\n\n // Now remove any unused joins\n parsed.tables = parsed.tables.filter((t) => dt.required.has(t.alias));\n\n // And then remove any inline soft-delete conditions we don't need anymore\n if (parsed.condition && parsed.condition.op === \"and\") {\n parsed.condition.conditions = parsed.condition.conditions.filter((c) => {\n if (c.kind === \"column\") {\n const prune = c.pruneable && !dt.required.has(c.alias);\n // if (prune) console.log(`DROPPING`, c);\n return !prune;\n } else {\n return c;\n }\n });\n }\n\n // Remove any `{ and: [...] }`s that are empty; we should probably do this deeply?\n if (parsed.condition && parsed.condition.conditions.length === 0) {\n parsed.condition = undefined;\n }\n}\n\n/** Returns the aliases needed to evaluate a join's ON clause, excluding the joined alias itself. */\nfunction joinDependencies(t: JoinTable): string[] {\n return [parseAlias(t.col1), parseAlias(t.col2)].filter((alias) => alias !== t.alias);\n}\n\n/** Marks aliases used by select strings, including generated CTI expressions like `COALESCE(st0.col, st1.col)`. */\nfunction markSelectAliases(dt: DependencyTracker, parsed: ParsedFindQuery, select: string): void {\n for (const table of parsed.tables) {\n if (selectReferencesAlias(select, table.alias)) {\n dt.markRequired(table.alias);\n }\n }\n}\n\n/** Returns true if a raw select expression references `alias.column` or the whole-row `alias`. */\nexport function selectReferencesAlias(select: string, alias: string): boolean {\n // Most selects are simple `a.*`, but CTI adds expressions like\n // `COALESCE(p_s0.shared_column, p_s1.shared_column) as shared_column`.\n // Those expressions must keep the subtype joins, but `parseAlias` only sees\n // the leading function name. Instead of parsing SQL, scan for the only alias\n // forms Joist generates in selects: `alias.column`, `\"alias\".column`, and whole-row aliases.\n return (\n selectReferencesCandidate(select, `${alias}.`) ||\n selectReferencesCandidate(select, `\"${alias}\".`) ||\n selectReferencesCandidate(select, alias) ||\n selectReferencesCandidate(select, `\"${alias}\"`)\n );\n}\n\n/**\n * Returns true when `candidate` is present at a SQL identifier boundary.\n *\n * Scans the select string for literal candidate matches, then verifies the characters before/after the match are not\n * part of a larger identifier or dotted path. I.e. `row_to_json(\"ap\")` matches, but `foo_\"ap\"` and `foo.ap` do not.\n */\nfunction selectReferencesCandidate(select: string, candidate: string): boolean {\n let index = select.indexOf(candidate);\n const quoted = candidate.startsWith('\"');\n while (index !== -1) {\n // Each loop inspects one literal occurrence of `candidate`, then either accepts it as a real alias reference or\n // advances to the next occurrence if the surrounding characters show it is part of a larger token.\n // Avoid treating `foo.a.id` as a reference to `a`; Joist-generated aliases\n // appear at the start of an expression or after punctuation/whitespace.\n const previous = select[index - 1];\n const next = select[index + candidate.length];\n if (\n (index === 0 || (previous !== \".\" && !isSqlIdentifierChar(previous))) &&\n !isSqlIdentifierChar(next) &&\n (quoted || (previous !== '\"' && next !== '\"'))\n ) {\n return true;\n }\n // Continue scanning after the current occurrence; `indexOf` returns -1 once there are no more candidates.\n index = select.indexOf(candidate, index + candidate.length);\n }\n return false;\n}\n\n/** Returns true for characters that can be part of an unquoted SQL identifier. */\nfunction isSqlIdentifierChar(char: string | undefined): boolean {\n return char !== undefined && /[A-Za-z0-9_]/.test(char);\n}\n\n/** Track join dependencies for `pruneUnusedJoins`. */\nclass DependencyTracker {\n private nodes: Map<string, string[]> = new Map();\n required: Set<string> = new Set();\n\n addAlias(alias: string, dependencies: string[] = []): void {\n this.nodes.set(alias, dependencies);\n }\n\n markRequired(alias: string): void {\n const marked = new Set<string>();\n const todo = [alias];\n while (todo.length > 0) {\n const alias = todo.pop()!;\n if (!marked.has(alias)) {\n marked.add(alias);\n todo.push(...(this.nodes.get(alias) || []));\n }\n }\n this.required = new Set([...this.required, ...marked]);\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"QueryParser.pruning.js","names":[],"sources":["../../../src/queries/find/QueryParser.pruning.ts"],"sourcesContent":["import { assertNever } from \"../../utils.ts\";\nimport { deepFindConditions } from \"../parsedConditions.ts\";\nimport { type JoinTable, type ParsedFindQuery, parseAlias } from \"./QueryParser.ts\";\n\n// Remove any joins that are not used in the select or conditions\nexport function pruneUnusedJoins(parsed: ParsedFindQuery, keepAliases: string[]): void {\n const dt = new DependencyTracker();\n\n // First setup the alias -> alias dependencies...\n const todo = [...parsed.tables];\n while (todo.length > 0) {\n const t = todo.pop()!;\n if (t.join === \"lateral\") {\n dt.addAlias(t.alias, [t.fromAlias]);\n // Recurse into lateral joins...\n todo.push(...t.query.tables);\n } else if (t.join === \"cross\") {\n dt.markRequired(t.alias);\n } else if (t.join === \"primary\") {\n dt.markRequired(t.alias);\n } else if (parsed.ctes?.some((cte) => cte.alias === t.table)) {\n dt.addAlias(t.alias, joinDependencies(t));\n dt.markRequired(t.alias);\n } else {\n dt.addAlias(t.alias, joinDependencies(t));\n }\n }\n\n // Mark all terminal usages\n parsed.selects.forEach((s) => {\n if (typeof s === \"string\") {\n markSelectAliases(dt, parsed, s);\n } else if (\"aliases\" in s) {\n for (const a of s.aliases) dt.markRequired(a);\n markSelectAliases(dt, parsed, s.sql);\n }\n });\n parsed.orderBys.forEach((o) => dt.markRequired(o.alias));\n parsed.groupBys?.forEach((g) => {\n if (\"expression\" in g) {\n markSelectAliases(dt, parsed, g.expression);\n } else {\n dt.markRequired(g.alias);\n }\n });\n keepAliases.forEach((a) => dt.markRequired(a));\n // Look recursively into CTE & lateral join conditions\n const todo2 = [{ query: parsed, filterPruneable: true }];\n while (todo2.length > 0) {\n const { query, filterPruneable } = todo2.pop()!;\n deepFindConditions(query.condition, filterPruneable).forEach((c) => {\n if (c.kind === \"column\") {\n dt.markRequired(c.alias);\n } else if (c.kind === \"raw\") {\n for (const alias of c.aliases) dt.markRequired(alias);\n } else if (c.kind === \"exists\") {\n for (const alias of c.outerAliases) dt.markRequired(alias);\n } else {\n assertNever(c);\n }\n });\n todo2.push(\n ...query.tables.filter((t) => t.join === \"lateral\").map((t) => ({ query: t.query, filterPruneable: false })),\n );\n }\n\n // Now remove any unused joins\n parsed.tables = parsed.tables.filter((t) => dt.required.has(t.alias));\n\n // And then remove any inline soft-delete conditions we don't need anymore\n if (parsed.condition && parsed.condition.op === \"and\") {\n parsed.condition.conditions = parsed.condition.conditions.filter((c) => {\n if (c.kind === \"column\") {\n const prune = c.pruneable && !dt.required.has(c.alias);\n // if (prune) console.log(`DROPPING`, c);\n return !prune;\n } else {\n return c;\n }\n });\n }\n\n // Remove any `{ and: [...] }`s that are empty; we should probably do this deeply?\n if (parsed.condition && parsed.condition.conditions.length === 0) {\n parsed.condition = undefined;\n }\n}\n\n/** Returns the aliases needed to evaluate a join's ON clause, excluding the joined alias itself. */\nfunction joinDependencies(t: JoinTable): string[] {\n return [parseAlias(t.col1), parseAlias(t.col2)].filter((alias) => alias !== t.alias);\n}\n\n/** Marks aliases used by select strings, including generated CTI expressions like `COALESCE(st0.col, st1.col)`. */\nfunction markSelectAliases(dt: DependencyTracker, parsed: ParsedFindQuery, select: string): void {\n for (const table of parsed.tables) {\n if (selectReferencesAlias(select, table.alias)) {\n dt.markRequired(table.alias);\n }\n }\n}\n\n/** Returns true if a raw select expression references `alias.column` or the whole-row `alias`. */\nexport function selectReferencesAlias(select: string, alias: string): boolean {\n // Most selects are simple `a.*`, but CTI adds expressions like\n // `COALESCE(p_s0.shared_column, p_s1.shared_column) as shared_column`.\n // Those expressions must keep the subtype joins, but `parseAlias` only sees\n // the leading function name. Instead of parsing SQL, scan for the only alias\n // forms Joist generates in selects: `alias.column`, `\"alias\".column`, and whole-row aliases.\n return (\n selectReferencesCandidate(select, `${alias}.`) ||\n selectReferencesCandidate(select, `\"${alias}\".`) ||\n selectReferencesCandidate(select, alias) ||\n selectReferencesCandidate(select, `\"${alias}\"`)\n );\n}\n\n/**\n * Returns true when `candidate` is present at a SQL identifier boundary.\n *\n * Scans the select string for literal candidate matches, then verifies the characters before/after the match are not\n * part of a larger identifier or dotted path. I.e. `row_to_json(\"ap\")` matches, but `foo_\"ap\"` and `foo.ap` do not.\n */\nfunction selectReferencesCandidate(select: string, candidate: string): boolean {\n let index = select.indexOf(candidate);\n const quoted = candidate.startsWith('\"');\n while (index !== -1) {\n // Each loop inspects one literal occurrence of `candidate`, then either accepts it as a real alias reference or\n // advances to the next occurrence if the surrounding characters show it is part of a larger token.\n // Avoid treating `foo.a.id` as a reference to `a`; Joist-generated aliases\n // appear at the start of an expression or after punctuation/whitespace.\n const previous = select[index - 1];\n const next = select[index + candidate.length];\n if (\n (index === 0 || (previous !== \".\" && !isSqlIdentifierChar(previous))) &&\n !isSqlIdentifierChar(next) &&\n (quoted || (previous !== '\"' && next !== '\"'))\n ) {\n return true;\n }\n // Continue scanning after the current occurrence; `indexOf` returns -1 once there are no more candidates.\n index = select.indexOf(candidate, index + candidate.length);\n }\n return false;\n}\n\n/** Returns true for characters that can be part of an unquoted SQL identifier. */\nfunction isSqlIdentifierChar(char: string | undefined): boolean {\n return char !== undefined && /[A-Za-z0-9_]/.test(char);\n}\n\n/** Track join dependencies for `pruneUnusedJoins`. */\nclass DependencyTracker {\n private nodes: Map<string, string[]> = new Map();\n required: Set<string> = new Set();\n\n addAlias(alias: string, dependencies: string[] = []): void {\n this.nodes.set(alias, dependencies);\n }\n\n markRequired(alias: string): void {\n const marked = new Set<string>();\n const todo = [alias];\n while (todo.length > 0) {\n const alias = todo.pop()!;\n if (!marked.has(alias)) {\n marked.add(alias);\n todo.push(...(this.nodes.get(alias) || []));\n }\n }\n this.required = new Set([...this.required, ...marked]);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"QueryParser.pruning.js","names":[],"sources":["../../../src/queries/find/QueryParser.pruning.ts"],"sourcesContent":["import { type JoinTable, type ParsedFindQuery, parseAlias } from \"src/queries/find/QueryParser.ts\";\nimport { deepFindConditions } from \"src/queries/parsedConditions.ts\";\nimport { assertNever } from \"src/utils.ts\";\n\n// Remove any joins that are not used in the select or conditions\nexport function pruneUnusedJoins(parsed: ParsedFindQuery, keepAliases: string[]): void {\n const dt = new DependencyTracker();\n\n // First setup the alias -> alias dependencies...\n const todo = [...parsed.tables];\n while (todo.length > 0) {\n const t = todo.pop()!;\n if (t.join === \"lateral\") {\n dt.addAlias(t.alias, [t.fromAlias]);\n // Recurse into lateral joins...\n todo.push(...t.query.tables);\n } else if (t.join === \"cross\") {\n dt.markRequired(t.alias);\n } else if (t.join === \"primary\") {\n dt.markRequired(t.alias);\n } else if (parsed.ctes?.some((cte) => cte.alias === t.table)) {\n dt.addAlias(t.alias, joinDependencies(t));\n dt.markRequired(t.alias);\n } else {\n dt.addAlias(t.alias, joinDependencies(t));\n }\n }\n\n // Mark all terminal usages\n parsed.selects.forEach((s) => {\n if (typeof s === \"string\") {\n markSelectAliases(dt, parsed, s);\n } else if (\"aliases\" in s) {\n for (const a of s.aliases) dt.markRequired(a);\n markSelectAliases(dt, parsed, s.sql);\n }\n });\n parsed.orderBys.forEach((o) => dt.markRequired(o.alias));\n parsed.groupBys?.forEach((g) => {\n if (\"expression\" in g) {\n markSelectAliases(dt, parsed, g.expression);\n } else {\n dt.markRequired(g.alias);\n }\n });\n keepAliases.forEach((a) => dt.markRequired(a));\n // Look recursively into CTE & lateral join conditions\n const todo2 = [{ query: parsed, filterPruneable: true }];\n while (todo2.length > 0) {\n const { query, filterPruneable } = todo2.pop()!;\n deepFindConditions(query.condition, filterPruneable).forEach((c) => {\n if (c.kind === \"column\") {\n dt.markRequired(c.alias);\n } else if (c.kind === \"raw\") {\n for (const alias of c.aliases) dt.markRequired(alias);\n } else if (c.kind === \"exists\") {\n for (const alias of c.outerAliases) dt.markRequired(alias);\n } else {\n assertNever(c);\n }\n });\n todo2.push(\n ...query.tables.filter((t) => t.join === \"lateral\").map((t) => ({ query: t.query, filterPruneable: false })),\n );\n }\n\n // Now remove any unused joins\n parsed.tables = parsed.tables.filter((t) => dt.required.has(t.alias));\n\n // And then remove any inline soft-delete conditions we don't need anymore\n if (parsed.condition && parsed.condition.op === \"and\") {\n parsed.condition.conditions = parsed.condition.conditions.filter((c) => {\n if (c.kind === \"column\") {\n const prune = c.pruneable && !dt.required.has(c.alias);\n // if (prune) console.log(`DROPPING`, c);\n return !prune;\n } else {\n return c;\n }\n });\n }\n\n // Remove any `{ and: [...] }`s that are empty; we should probably do this deeply?\n if (parsed.condition && parsed.condition.conditions.length === 0) {\n parsed.condition = undefined;\n }\n}\n\n/** Returns the aliases needed to evaluate a join's ON clause, excluding the joined alias itself. */\nfunction joinDependencies(t: JoinTable): string[] {\n return [parseAlias(t.col1), parseAlias(t.col2)].filter((alias) => alias !== t.alias);\n}\n\n/** Marks aliases used by select strings, including generated CTI expressions like `COALESCE(st0.col, st1.col)`. */\nfunction markSelectAliases(dt: DependencyTracker, parsed: ParsedFindQuery, select: string): void {\n for (const table of parsed.tables) {\n if (selectReferencesAlias(select, table.alias)) {\n dt.markRequired(table.alias);\n }\n }\n}\n\n/** Returns true if a raw select expression references `alias.column` or the whole-row `alias`. */\nexport function selectReferencesAlias(select: string, alias: string): boolean {\n // Most selects are simple `a.*`, but CTI adds expressions like\n // `COALESCE(p_s0.shared_column, p_s1.shared_column) as shared_column`.\n // Those expressions must keep the subtype joins, but `parseAlias` only sees\n // the leading function name. Instead of parsing SQL, scan for the only alias\n // forms Joist generates in selects: `alias.column`, `\"alias\".column`, and whole-row aliases.\n return (\n selectReferencesCandidate(select, `${alias}.`) ||\n selectReferencesCandidate(select, `\"${alias}\".`) ||\n selectReferencesCandidate(select, alias) ||\n selectReferencesCandidate(select, `\"${alias}\"`)\n );\n}\n\n/**\n * Returns true when `candidate` is present at a SQL identifier boundary.\n *\n * Scans the select string for literal candidate matches, then verifies the characters before/after the match are not\n * part of a larger identifier or dotted path. I.e. `row_to_json(\"ap\")` matches, but `foo_\"ap\"` and `foo.ap` do not.\n */\nfunction selectReferencesCandidate(select: string, candidate: string): boolean {\n let index = select.indexOf(candidate);\n const quoted = candidate.startsWith('\"');\n while (index !== -1) {\n // Each loop inspects one literal occurrence of `candidate`, then either accepts it as a real alias reference or\n // advances to the next occurrence if the surrounding characters show it is part of a larger token.\n // Avoid treating `foo.a.id` as a reference to `a`; Joist-generated aliases\n // appear at the start of an expression or after punctuation/whitespace.\n const previous = select[index - 1];\n const next = select[index + candidate.length];\n if (\n (index === 0 || (previous !== \".\" && !isSqlIdentifierChar(previous))) &&\n !isSqlIdentifierChar(next) &&\n (quoted || (previous !== '\"' && next !== '\"'))\n ) {\n return true;\n }\n // Continue scanning after the current occurrence; `indexOf` returns -1 once there are no more candidates.\n index = select.indexOf(candidate, index + candidate.length);\n }\n return false;\n}\n\n/** Returns true for characters that can be part of an unquoted SQL identifier. */\nfunction isSqlIdentifierChar(char: string | undefined): boolean {\n return char !== undefined && /[A-Za-z0-9_]/.test(char);\n}\n\n/** Track join dependencies for `pruneUnusedJoins`. */\nclass DependencyTracker {\n private nodes: Map<string, string[]> = new Map();\n required: Set<string> = new Set();\n\n addAlias(alias: string, dependencies: string[] = []): void {\n this.nodes.set(alias, dependencies);\n }\n\n markRequired(alias: string): void {\n const marked = new Set<string>();\n const todo = [alias];\n while (todo.length > 0) {\n const alias = todo.pop()!;\n if (!marked.has(alias)) {\n marked.add(alias);\n todo.push(...(this.nodes.get(alias) || []));\n }\n }\n this.required = new Set([...this.required, ...marked]);\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"QueryVisitor.cjs","names":[],"sources":["../../../src/queries/find/QueryVisitor.ts"],"sourcesContent":["import { assertNever } from \"../../utils.ts\";\nimport type {\n ColumnCondition,\n ParsedExpressionCondition,\n ParsedExpressionFilter,\n RawCondition,\n} from \"../parsedConditions.ts\";\nimport type { ParsedFindQuery } from \"./QueryParser.ts\";\n\n/** A generic visitor over the simple & complex conditions of a query. */\ninterface Visitor {\n visitExp?(c: ParsedExpressionFilter): ParsedExpressionFilter | void;\n visitRaw?(c: RawCondition): RawCondition | ParsedExpressionFilter | void;\n visitCond(c: ColumnCondition): ColumnCondition | ParsedExpressionFilter | RawCondition | null | void;\n}\n\n/**\n * Visits the nested conditions within `query`.\n *\n * If the visitors return a new condition or expression, the returned expression\n * will replace the original one at that location in the expression.\n *\n * If the visitor returns null, the condition or expression will be removed from the tree.\n */\nexport function visitConditions(query: ParsedFindQuery, visitor: Visitor): void {\n const todo = [query];\n while (todo.length > 0) {\n const query = todo.pop()!;\n if (query.condition) visitFilter(query.condition, visitor);\n // Recurse into lateral subqueries (used by batching/preloading, not EXISTS rewrite)\n for (const table of query.tables) {\n if (table.join === \"lateral\") {\n todo.push(table.query);\n }\n }\n // Recurse into EXISTS subqueries so batching visitors can rewrite conditions inside them\n if (query.condition) {\n visitExistsSubqueries(query.condition, todo);\n }\n }\n}\n\n/** Finds ExistsCondition nodes in a condition tree and pushes their subqueries onto the todo list. */\nfunction visitExistsSubqueries(condition: ParsedExpressionCondition, todo: ParsedFindQuery[]): void {\n if (condition.kind === \"exp\") {\n for (const c of condition.conditions) {\n visitExistsSubqueries(c, todo);\n }\n } else if (condition.kind === \"exists\") {\n todo.push(condition.subquery);\n }\n}\n\nexport function visitFilter(pc: ParsedExpressionCondition, visitor: Visitor) {\n if (pc.kind === \"exp\") {\n const toRemove = new Set<number>();\n pc.conditions.forEach((c, i) => {\n if (c.kind === \"column\") {\n const result = visitor.visitCond(c);\n if (result === null) {\n toRemove.add(i);\n } else if (result) {\n pc.conditions[i] = result;\n }\n } else if (c.kind === \"exp\") {\n const result = visitor.visitExp?.(c);\n if (result === null) {\n toRemove.add(i);\n return;\n } else if (result) {\n pc.conditions[i] = result;\n }\n visitFilter(result ?? c, visitor);\n } else if (c.kind === \"raw\") {\n const result = visitor.visitRaw?.(c);\n if (result === null) {\n toRemove.add(i);\n } else if (result) {\n pc.conditions[i] = result;\n }\n } else if (c.kind === \"exists\") {\n // EXISTS conditions are visited via visitExistsSubqueries, not inline\n } else {\n assertNever(c);\n }\n });\n // do this after visiting the children, so we can do it in one pass and don't mess up the indices\n if (toRemove.size > 0) pc.conditions = pc.conditions.filter((_, i) => !toRemove.has(i));\n } else if (pc.kind === \"column\") {\n const result = visitor.visitCond(pc);\n if (result || result === null) {\n throw new Error(\"ParsedExpressionCondition overload not support mutating the condition\");\n }\n } else if (pc.kind === \"raw\") {\n const result = visitor.visitRaw?.(pc);\n if (result || result === null) {\n throw new Error(\"ParsedExpressionCondition overload not support mutating the condition\");\n }\n } else if (pc.kind === \"exists\") {\n // EXISTS conditions are handled at the query level\n } else {\n assertNever(pc);\n }\n}\n"],"mappings":";;;;;;;;;;;AAwBA,SAAgB,gBAAgB,OAAwB,SAAwB;CAC9E,MAAM,OAAO,CAAC,KAAK;CACnB,OAAO,KAAK,SAAS,GAAG;EACtB,MAAM,QAAQ,KAAK,IAAI;EACvB,IAAI,MAAM,WAAW,YAAY,MAAM,WAAW,OAAO;EAEzD,KAAK,MAAM,SAAS,MAAM,QACxB,IAAI,MAAM,SAAS,WACjB,KAAK,KAAK,MAAM,KAAK;EAIzB,IAAI,MAAM,WACR,sBAAsB,MAAM,WAAW,IAAI;CAE/C;AACF;;AAGA,SAAS,sBAAsB,WAAsC,MAA+B;CAClG,IAAI,UAAU,SAAS,OACrB,KAAK,MAAM,KAAK,UAAU,YACxB,sBAAsB,GAAG,IAAI;MAE1B,IAAI,UAAU,SAAS,UAC5B,KAAK,KAAK,UAAU,QAAQ;AAEhC;AAEA,SAAgB,YAAY,IAA+B,SAAkB;CAC3E,IAAI,GAAG,SAAS,OAAO;EACrB,MAAM,2BAAW,IAAI,IAAY;EACjC,GAAG,WAAW,SAAS,GAAG,MAAM;GAC9B,IAAI,EAAE,SAAS,UAAU;IACvB,MAAM,SAAS,QAAQ,UAAU,CAAC;IAClC,IAAI,WAAW,MACb,SAAS,IAAI,CAAC;SACT,IAAI,QACT,GAAG,WAAW,KAAK;GAEvB,OAAO,IAAI,EAAE,SAAS,OAAO;IAC3B,MAAM,SAAS,QAAQ,WAAW,CAAC;IACnC,IAAI,WAAW,MAAM;KACnB,SAAS,IAAI,CAAC;KACd;IACF,OAAO,IAAI,QACT,GAAG,WAAW,KAAK;IAErB,YAAY,UAAU,GAAG,OAAO;GAClC,OAAO,IAAI,EAAE,SAAS,OAAO;IAC3B,MAAM,SAAS,QAAQ,WAAW,CAAC;IACnC,IAAI,WAAW,MACb,SAAS,IAAI,CAAC;SACT,IAAI,QACT,GAAG,WAAW,KAAK;GAEvB,OAAO,IAAI,EAAE,SAAS,UAAU,CAEhC,OACE,cAAA,YAAY,CAAC;EAEjB,CAAC;EAED,IAAI,SAAS,OAAO,GAAG,GAAG,aAAa,GAAG,WAAW,QAAQ,GAAG,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;CACxF,OAAO,IAAI,GAAG,SAAS,UAAU;EAC/B,MAAM,SAAS,QAAQ,UAAU,EAAE;EACnC,IAAI,UAAU,WAAW,MACvB,MAAM,IAAI,MAAM,uEAAuE;CAE3F,OAAO,IAAI,GAAG,SAAS,OAAO;EAC5B,MAAM,SAAS,QAAQ,WAAW,EAAE;EACpC,IAAI,UAAU,WAAW,MACvB,MAAM,IAAI,MAAM,uEAAuE;CAE3F,OAAO,IAAI,GAAG,SAAS,UAAU,CAEjC,OACE,cAAA,YAAY,EAAE;AAElB"}
1
+ {"version":3,"file":"QueryVisitor.cjs","names":[],"sources":["../../../src/queries/find/QueryVisitor.ts"],"sourcesContent":["import type { ParsedFindQuery } from \"src/queries/find/QueryParser.ts\";\nimport type {\n ColumnCondition,\n ParsedExpressionCondition,\n ParsedExpressionFilter,\n RawCondition,\n} from \"src/queries/parsedConditions.ts\";\nimport { assertNever } from \"src/utils.ts\";\n\n/** A generic visitor over the simple & complex conditions of a query. */\ninterface Visitor {\n visitExp?(c: ParsedExpressionFilter): ParsedExpressionFilter | void;\n visitRaw?(c: RawCondition): RawCondition | ParsedExpressionFilter | void;\n visitCond(c: ColumnCondition): ColumnCondition | ParsedExpressionFilter | RawCondition | null | void;\n}\n\n/**\n * Visits the nested conditions within `query`.\n *\n * If the visitors return a new condition or expression, the returned expression\n * will replace the original one at that location in the expression.\n *\n * If the visitor returns null, the condition or expression will be removed from the tree.\n */\nexport function visitConditions(query: ParsedFindQuery, visitor: Visitor): void {\n const todo = [query];\n while (todo.length > 0) {\n const query = todo.pop()!;\n if (query.condition) visitFilter(query.condition, visitor);\n // Recurse into lateral subqueries (used by batching/preloading, not EXISTS rewrite)\n for (const table of query.tables) {\n if (table.join === \"lateral\") {\n todo.push(table.query);\n }\n }\n // Recurse into EXISTS subqueries so batching visitors can rewrite conditions inside them\n if (query.condition) {\n visitExistsSubqueries(query.condition, todo);\n }\n }\n}\n\n/** Finds ExistsCondition nodes in a condition tree and pushes their subqueries onto the todo list. */\nfunction visitExistsSubqueries(condition: ParsedExpressionCondition, todo: ParsedFindQuery[]): void {\n if (condition.kind === \"exp\") {\n for (const c of condition.conditions) {\n visitExistsSubqueries(c, todo);\n }\n } else if (condition.kind === \"exists\") {\n todo.push(condition.subquery);\n }\n}\n\nexport function visitFilter(pc: ParsedExpressionCondition, visitor: Visitor) {\n if (pc.kind === \"exp\") {\n const toRemove = new Set<number>();\n pc.conditions.forEach((c, i) => {\n if (c.kind === \"column\") {\n const result = visitor.visitCond(c);\n if (result === null) {\n toRemove.add(i);\n } else if (result) {\n pc.conditions[i] = result;\n }\n } else if (c.kind === \"exp\") {\n const result = visitor.visitExp?.(c);\n if (result === null) {\n toRemove.add(i);\n return;\n } else if (result) {\n pc.conditions[i] = result;\n }\n visitFilter(result ?? c, visitor);\n } else if (c.kind === \"raw\") {\n const result = visitor.visitRaw?.(c);\n if (result === null) {\n toRemove.add(i);\n } else if (result) {\n pc.conditions[i] = result;\n }\n } else if (c.kind === \"exists\") {\n // EXISTS conditions are visited via visitExistsSubqueries, not inline\n } else {\n assertNever(c);\n }\n });\n // do this after visiting the children, so we can do it in one pass and don't mess up the indices\n if (toRemove.size > 0) pc.conditions = pc.conditions.filter((_, i) => !toRemove.has(i));\n } else if (pc.kind === \"column\") {\n const result = visitor.visitCond(pc);\n if (result || result === null) {\n throw new Error(\"ParsedExpressionCondition overload not support mutating the condition\");\n }\n } else if (pc.kind === \"raw\") {\n const result = visitor.visitRaw?.(pc);\n if (result || result === null) {\n throw new Error(\"ParsedExpressionCondition overload not support mutating the condition\");\n }\n } else if (pc.kind === \"exists\") {\n // EXISTS conditions are handled at the query level\n } else {\n assertNever(pc);\n }\n}\n"],"mappings":";;;;;;;;;;;AAwBA,SAAgB,gBAAgB,OAAwB,SAAwB;CAC9E,MAAM,OAAO,CAAC,KAAK;CACnB,OAAO,KAAK,SAAS,GAAG;EACtB,MAAM,QAAQ,KAAK,IAAI;EACvB,IAAI,MAAM,WAAW,YAAY,MAAM,WAAW,OAAO;EAEzD,KAAK,MAAM,SAAS,MAAM,QACxB,IAAI,MAAM,SAAS,WACjB,KAAK,KAAK,MAAM,KAAK;EAIzB,IAAI,MAAM,WACR,sBAAsB,MAAM,WAAW,IAAI;CAE/C;AACF;;AAGA,SAAS,sBAAsB,WAAsC,MAA+B;CAClG,IAAI,UAAU,SAAS,OACrB,KAAK,MAAM,KAAK,UAAU,YACxB,sBAAsB,GAAG,IAAI;MAE1B,IAAI,UAAU,SAAS,UAC5B,KAAK,KAAK,UAAU,QAAQ;AAEhC;AAEA,SAAgB,YAAY,IAA+B,SAAkB;CAC3E,IAAI,GAAG,SAAS,OAAO;EACrB,MAAM,2BAAW,IAAI,IAAY;EACjC,GAAG,WAAW,SAAS,GAAG,MAAM;GAC9B,IAAI,EAAE,SAAS,UAAU;IACvB,MAAM,SAAS,QAAQ,UAAU,CAAC;IAClC,IAAI,WAAW,MACb,SAAS,IAAI,CAAC;SACT,IAAI,QACT,GAAG,WAAW,KAAK;GAEvB,OAAO,IAAI,EAAE,SAAS,OAAO;IAC3B,MAAM,SAAS,QAAQ,WAAW,CAAC;IACnC,IAAI,WAAW,MAAM;KACnB,SAAS,IAAI,CAAC;KACd;IACF,OAAO,IAAI,QACT,GAAG,WAAW,KAAK;IAErB,YAAY,UAAU,GAAG,OAAO;GAClC,OAAO,IAAI,EAAE,SAAS,OAAO;IAC3B,MAAM,SAAS,QAAQ,WAAW,CAAC;IACnC,IAAI,WAAW,MACb,SAAS,IAAI,CAAC;SACT,IAAI,QACT,GAAG,WAAW,KAAK;GAEvB,OAAO,IAAI,EAAE,SAAS,UAAU,CAEhC,OACE,cAAA,YAAY,CAAC;EAEjB,CAAC;EAED,IAAI,SAAS,OAAO,GAAG,GAAG,aAAa,GAAG,WAAW,QAAQ,GAAG,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;CACxF,OAAO,IAAI,GAAG,SAAS,UAAU;EAC/B,MAAM,SAAS,QAAQ,UAAU,EAAE;EACnC,IAAI,UAAU,WAAW,MACvB,MAAM,IAAI,MAAM,uEAAuE;CAE3F,OAAO,IAAI,GAAG,SAAS,OAAO;EAC5B,MAAM,SAAS,QAAQ,WAAW,EAAE;EACpC,IAAI,UAAU,WAAW,MACvB,MAAM,IAAI,MAAM,uEAAuE;CAE3F,OAAO,IAAI,GAAG,SAAS,UAAU,CAEjC,OACE,cAAA,YAAY,EAAE;AAElB"}
@@ -1 +1 @@
1
- {"version":3,"file":"QueryVisitor.js","names":[],"sources":["../../../src/queries/find/QueryVisitor.ts"],"sourcesContent":["import { assertNever } from \"../../utils.ts\";\nimport type {\n ColumnCondition,\n ParsedExpressionCondition,\n ParsedExpressionFilter,\n RawCondition,\n} from \"../parsedConditions.ts\";\nimport type { ParsedFindQuery } from \"./QueryParser.ts\";\n\n/** A generic visitor over the simple & complex conditions of a query. */\ninterface Visitor {\n visitExp?(c: ParsedExpressionFilter): ParsedExpressionFilter | void;\n visitRaw?(c: RawCondition): RawCondition | ParsedExpressionFilter | void;\n visitCond(c: ColumnCondition): ColumnCondition | ParsedExpressionFilter | RawCondition | null | void;\n}\n\n/**\n * Visits the nested conditions within `query`.\n *\n * If the visitors return a new condition or expression, the returned expression\n * will replace the original one at that location in the expression.\n *\n * If the visitor returns null, the condition or expression will be removed from the tree.\n */\nexport function visitConditions(query: ParsedFindQuery, visitor: Visitor): void {\n const todo = [query];\n while (todo.length > 0) {\n const query = todo.pop()!;\n if (query.condition) visitFilter(query.condition, visitor);\n // Recurse into lateral subqueries (used by batching/preloading, not EXISTS rewrite)\n for (const table of query.tables) {\n if (table.join === \"lateral\") {\n todo.push(table.query);\n }\n }\n // Recurse into EXISTS subqueries so batching visitors can rewrite conditions inside them\n if (query.condition) {\n visitExistsSubqueries(query.condition, todo);\n }\n }\n}\n\n/** Finds ExistsCondition nodes in a condition tree and pushes their subqueries onto the todo list. */\nfunction visitExistsSubqueries(condition: ParsedExpressionCondition, todo: ParsedFindQuery[]): void {\n if (condition.kind === \"exp\") {\n for (const c of condition.conditions) {\n visitExistsSubqueries(c, todo);\n }\n } else if (condition.kind === \"exists\") {\n todo.push(condition.subquery);\n }\n}\n\nexport function visitFilter(pc: ParsedExpressionCondition, visitor: Visitor) {\n if (pc.kind === \"exp\") {\n const toRemove = new Set<number>();\n pc.conditions.forEach((c, i) => {\n if (c.kind === \"column\") {\n const result = visitor.visitCond(c);\n if (result === null) {\n toRemove.add(i);\n } else if (result) {\n pc.conditions[i] = result;\n }\n } else if (c.kind === \"exp\") {\n const result = visitor.visitExp?.(c);\n if (result === null) {\n toRemove.add(i);\n return;\n } else if (result) {\n pc.conditions[i] = result;\n }\n visitFilter(result ?? c, visitor);\n } else if (c.kind === \"raw\") {\n const result = visitor.visitRaw?.(c);\n if (result === null) {\n toRemove.add(i);\n } else if (result) {\n pc.conditions[i] = result;\n }\n } else if (c.kind === \"exists\") {\n // EXISTS conditions are visited via visitExistsSubqueries, not inline\n } else {\n assertNever(c);\n }\n });\n // do this after visiting the children, so we can do it in one pass and don't mess up the indices\n if (toRemove.size > 0) pc.conditions = pc.conditions.filter((_, i) => !toRemove.has(i));\n } else if (pc.kind === \"column\") {\n const result = visitor.visitCond(pc);\n if (result || result === null) {\n throw new Error(\"ParsedExpressionCondition overload not support mutating the condition\");\n }\n } else if (pc.kind === \"raw\") {\n const result = visitor.visitRaw?.(pc);\n if (result || result === null) {\n throw new Error(\"ParsedExpressionCondition overload not support mutating the condition\");\n }\n } else if (pc.kind === \"exists\") {\n // EXISTS conditions are handled at the query level\n } else {\n assertNever(pc);\n }\n}\n"],"mappings":";;;;;;;;;;AAwBA,SAAgB,gBAAgB,OAAwB,SAAwB;CAC9E,MAAM,OAAO,CAAC,KAAK;CACnB,OAAO,KAAK,SAAS,GAAG;EACtB,MAAM,QAAQ,KAAK,IAAI;EACvB,IAAI,MAAM,WAAW,YAAY,MAAM,WAAW,OAAO;EAEzD,KAAK,MAAM,SAAS,MAAM,QACxB,IAAI,MAAM,SAAS,WACjB,KAAK,KAAK,MAAM,KAAK;EAIzB,IAAI,MAAM,WACR,sBAAsB,MAAM,WAAW,IAAI;CAE/C;AACF;;AAGA,SAAS,sBAAsB,WAAsC,MAA+B;CAClG,IAAI,UAAU,SAAS,OACrB,KAAK,MAAM,KAAK,UAAU,YACxB,sBAAsB,GAAG,IAAI;MAE1B,IAAI,UAAU,SAAS,UAC5B,KAAK,KAAK,UAAU,QAAQ;AAEhC;AAEA,SAAgB,YAAY,IAA+B,SAAkB;CAC3E,IAAI,GAAG,SAAS,OAAO;EACrB,MAAM,2BAAW,IAAI,IAAY;EACjC,GAAG,WAAW,SAAS,GAAG,MAAM;GAC9B,IAAI,EAAE,SAAS,UAAU;IACvB,MAAM,SAAS,QAAQ,UAAU,CAAC;IAClC,IAAI,WAAW,MACb,SAAS,IAAI,CAAC;SACT,IAAI,QACT,GAAG,WAAW,KAAK;GAEvB,OAAO,IAAI,EAAE,SAAS,OAAO;IAC3B,MAAM,SAAS,QAAQ,WAAW,CAAC;IACnC,IAAI,WAAW,MAAM;KACnB,SAAS,IAAI,CAAC;KACd;IACF,OAAO,IAAI,QACT,GAAG,WAAW,KAAK;IAErB,YAAY,UAAU,GAAG,OAAO;GAClC,OAAO,IAAI,EAAE,SAAS,OAAO;IAC3B,MAAM,SAAS,QAAQ,WAAW,CAAC;IACnC,IAAI,WAAW,MACb,SAAS,IAAI,CAAC;SACT,IAAI,QACT,GAAG,WAAW,KAAK;GAEvB,OAAO,IAAI,EAAE,SAAS,UAAU,CAEhC,OACE,YAAY,CAAC;EAEjB,CAAC;EAED,IAAI,SAAS,OAAO,GAAG,GAAG,aAAa,GAAG,WAAW,QAAQ,GAAG,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;CACxF,OAAO,IAAI,GAAG,SAAS,UAAU;EAC/B,MAAM,SAAS,QAAQ,UAAU,EAAE;EACnC,IAAI,UAAU,WAAW,MACvB,MAAM,IAAI,MAAM,uEAAuE;CAE3F,OAAO,IAAI,GAAG,SAAS,OAAO;EAC5B,MAAM,SAAS,QAAQ,WAAW,EAAE;EACpC,IAAI,UAAU,WAAW,MACvB,MAAM,IAAI,MAAM,uEAAuE;CAE3F,OAAO,IAAI,GAAG,SAAS,UAAU,CAEjC,OACE,YAAY,EAAE;AAElB"}
1
+ {"version":3,"file":"QueryVisitor.js","names":[],"sources":["../../../src/queries/find/QueryVisitor.ts"],"sourcesContent":["import type { ParsedFindQuery } from \"src/queries/find/QueryParser.ts\";\nimport type {\n ColumnCondition,\n ParsedExpressionCondition,\n ParsedExpressionFilter,\n RawCondition,\n} from \"src/queries/parsedConditions.ts\";\nimport { assertNever } from \"src/utils.ts\";\n\n/** A generic visitor over the simple & complex conditions of a query. */\ninterface Visitor {\n visitExp?(c: ParsedExpressionFilter): ParsedExpressionFilter | void;\n visitRaw?(c: RawCondition): RawCondition | ParsedExpressionFilter | void;\n visitCond(c: ColumnCondition): ColumnCondition | ParsedExpressionFilter | RawCondition | null | void;\n}\n\n/**\n * Visits the nested conditions within `query`.\n *\n * If the visitors return a new condition or expression, the returned expression\n * will replace the original one at that location in the expression.\n *\n * If the visitor returns null, the condition or expression will be removed from the tree.\n */\nexport function visitConditions(query: ParsedFindQuery, visitor: Visitor): void {\n const todo = [query];\n while (todo.length > 0) {\n const query = todo.pop()!;\n if (query.condition) visitFilter(query.condition, visitor);\n // Recurse into lateral subqueries (used by batching/preloading, not EXISTS rewrite)\n for (const table of query.tables) {\n if (table.join === \"lateral\") {\n todo.push(table.query);\n }\n }\n // Recurse into EXISTS subqueries so batching visitors can rewrite conditions inside them\n if (query.condition) {\n visitExistsSubqueries(query.condition, todo);\n }\n }\n}\n\n/** Finds ExistsCondition nodes in a condition tree and pushes their subqueries onto the todo list. */\nfunction visitExistsSubqueries(condition: ParsedExpressionCondition, todo: ParsedFindQuery[]): void {\n if (condition.kind === \"exp\") {\n for (const c of condition.conditions) {\n visitExistsSubqueries(c, todo);\n }\n } else if (condition.kind === \"exists\") {\n todo.push(condition.subquery);\n }\n}\n\nexport function visitFilter(pc: ParsedExpressionCondition, visitor: Visitor) {\n if (pc.kind === \"exp\") {\n const toRemove = new Set<number>();\n pc.conditions.forEach((c, i) => {\n if (c.kind === \"column\") {\n const result = visitor.visitCond(c);\n if (result === null) {\n toRemove.add(i);\n } else if (result) {\n pc.conditions[i] = result;\n }\n } else if (c.kind === \"exp\") {\n const result = visitor.visitExp?.(c);\n if (result === null) {\n toRemove.add(i);\n return;\n } else if (result) {\n pc.conditions[i] = result;\n }\n visitFilter(result ?? c, visitor);\n } else if (c.kind === \"raw\") {\n const result = visitor.visitRaw?.(c);\n if (result === null) {\n toRemove.add(i);\n } else if (result) {\n pc.conditions[i] = result;\n }\n } else if (c.kind === \"exists\") {\n // EXISTS conditions are visited via visitExistsSubqueries, not inline\n } else {\n assertNever(c);\n }\n });\n // do this after visiting the children, so we can do it in one pass and don't mess up the indices\n if (toRemove.size > 0) pc.conditions = pc.conditions.filter((_, i) => !toRemove.has(i));\n } else if (pc.kind === \"column\") {\n const result = visitor.visitCond(pc);\n if (result || result === null) {\n throw new Error(\"ParsedExpressionCondition overload not support mutating the condition\");\n }\n } else if (pc.kind === \"raw\") {\n const result = visitor.visitRaw?.(pc);\n if (result || result === null) {\n throw new Error(\"ParsedExpressionCondition overload not support mutating the condition\");\n }\n } else if (pc.kind === \"exists\") {\n // EXISTS conditions are handled at the query level\n } else {\n assertNever(pc);\n }\n}\n"],"mappings":";;;;;;;;;;AAwBA,SAAgB,gBAAgB,OAAwB,SAAwB;CAC9E,MAAM,OAAO,CAAC,KAAK;CACnB,OAAO,KAAK,SAAS,GAAG;EACtB,MAAM,QAAQ,KAAK,IAAI;EACvB,IAAI,MAAM,WAAW,YAAY,MAAM,WAAW,OAAO;EAEzD,KAAK,MAAM,SAAS,MAAM,QACxB,IAAI,MAAM,SAAS,WACjB,KAAK,KAAK,MAAM,KAAK;EAIzB,IAAI,MAAM,WACR,sBAAsB,MAAM,WAAW,IAAI;CAE/C;AACF;;AAGA,SAAS,sBAAsB,WAAsC,MAA+B;CAClG,IAAI,UAAU,SAAS,OACrB,KAAK,MAAM,KAAK,UAAU,YACxB,sBAAsB,GAAG,IAAI;MAE1B,IAAI,UAAU,SAAS,UAC5B,KAAK,KAAK,UAAU,QAAQ;AAEhC;AAEA,SAAgB,YAAY,IAA+B,SAAkB;CAC3E,IAAI,GAAG,SAAS,OAAO;EACrB,MAAM,2BAAW,IAAI,IAAY;EACjC,GAAG,WAAW,SAAS,GAAG,MAAM;GAC9B,IAAI,EAAE,SAAS,UAAU;IACvB,MAAM,SAAS,QAAQ,UAAU,CAAC;IAClC,IAAI,WAAW,MACb,SAAS,IAAI,CAAC;SACT,IAAI,QACT,GAAG,WAAW,KAAK;GAEvB,OAAO,IAAI,EAAE,SAAS,OAAO;IAC3B,MAAM,SAAS,QAAQ,WAAW,CAAC;IACnC,IAAI,WAAW,MAAM;KACnB,SAAS,IAAI,CAAC;KACd;IACF,OAAO,IAAI,QACT,GAAG,WAAW,KAAK;IAErB,YAAY,UAAU,GAAG,OAAO;GAClC,OAAO,IAAI,EAAE,SAAS,OAAO;IAC3B,MAAM,SAAS,QAAQ,WAAW,CAAC;IACnC,IAAI,WAAW,MACb,SAAS,IAAI,CAAC;SACT,IAAI,QACT,GAAG,WAAW,KAAK;GAEvB,OAAO,IAAI,EAAE,SAAS,UAAU,CAEhC,OACE,YAAY,CAAC;EAEjB,CAAC;EAED,IAAI,SAAS,OAAO,GAAG,GAAG,aAAa,GAAG,WAAW,QAAQ,GAAG,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;CACxF,OAAO,IAAI,GAAG,SAAS,UAAU;EAC/B,MAAM,SAAS,QAAQ,UAAU,EAAE;EACnC,IAAI,UAAU,WAAW,MACvB,MAAM,IAAI,MAAM,uEAAuE;CAE3F,OAAO,IAAI,GAAG,SAAS,OAAO;EAC5B,MAAM,SAAS,QAAQ,WAAW,EAAE;EACpC,IAAI,UAAU,WAAW,MACvB,MAAM,IAAI,MAAM,uEAAuE;CAE3F,OAAO,IAAI,GAAG,SAAS,UAAU,CAEjC,OACE,YAAY,EAAE;AAElB"}
@@ -1 +1 @@
1
- {"version":3,"file":"buildFindQuery.cjs","names":["kq","cleanSql","kqDot","buildWhereClause"],"sources":["../../../src/queries/find/buildFindQuery.ts"],"sourcesContent":["import { assertNever, cleanSql } from \"../../utils.ts\";\nimport { buildWhereClause } from \"../renderConditions.ts\";\nimport { kq, kqDot } from \"../sql/keywords.ts\";\nimport type { ParsedCteClause, ParsedFindQuery, ParsedTable } from \"./QueryParser.ts\";\n\ntype QuerySettings = { limit?: number; offset?: number };\n\n/**\n * Transforms `ParsedFindQuery` into a raw SQL string.\n *\n * In theory this should be implemented within each Driver, but the logic will be largely\n * the same for different dbs.\n */\nexport function buildRawQuery(\n parsed: ParsedFindQuery,\n settings: QuerySettings,\n): { sql: string; bindings: readonly any[] } {\n const { limit, offset } = settings;\n\n const primary = parsed.tables.find((t) => t.join === \"primary\")!;\n\n // If we're doing o2m joins, add a `DISTINCT` clause to avoid duplicates\n const needsDistinct =\n parsed.tables.some((t) => t.join === \"outer\" && t.distinct !== false) &&\n // If this is a `findCount`, it will rewrite the `select` to have its own distinct\n !parsed.selects.find((s) => typeof s === \"string\" && s.startsWith(\"count(\"));\n\n let sql = \"\";\n const bindings: any[] = [];\n\n if (parsed.ctes && parsed.ctes.length > 0) {\n const hasRecursive = parsed.ctes.some((cte) => cte.recursive);\n const maybeRecursive = hasRecursive ? \" RECURSIVE\" : \"\";\n sql += `WITH${maybeRecursive}`;\n for (let i = 0; i < parsed.ctes.length; i++) {\n const cte = parsed.ctes[i];\n sql += i > 0 ? \", \" : \"\";\n sql += ` ${cte.alias}`;\n if (cte.columns) {\n sql += \" (\";\n for (let j = 0; j < cte.columns.length; j++) {\n sql += j > 0 ? \", \" : \"\";\n sql += kq(cte.columns[j].columnName);\n }\n sql += \")\";\n }\n if (cte.query.kind === \"raw\") {\n sql += ` AS (${cleanSql(cte.query.sql)})`;\n bindings.push(...cte.query.bindings);\n } else if (cte.query.kind === \"ast\") {\n const nested = buildRawQuery(cte.query.query, {});\n sql += ` AS (${nested.sql})`;\n bindings.push(...nested.bindings);\n } else {\n assertNever(cte.query);\n }\n }\n sql += \" \";\n }\n\n sql += \"SELECT \";\n const subqueryRenderer = (q: ParsedFindQuery) => buildRawQuery(q, {});\n\n parsed.selects.forEach((s, i) => {\n const maybeDistinct = i === 0 && needsDistinct ? buildDistinctOn(parsed, primary) : \"\";\n const maybeComma = i === parsed.selects.length - 1 ? \"\" : \", \";\n if (typeof s === \"string\") {\n sql += maybeDistinct + s + maybeComma;\n } else if (\"sql\" in s) {\n sql += maybeDistinct + s.sql + maybeComma;\n bindings.push(...s.bindings);\n }\n });\n\n // If we're doing \"select distinct\" for o2m joins, then all order bys must be selects\n if (needsDistinct && parsed.orderBys.length > 0) {\n for (const { alias, column } of parsed.orderBys) {\n sql += `, ${kqDot(alias, column)}`;\n }\n }\n\n // Make sure the primary is first\n sql += ` FROM ${as(primary)}`;\n\n // Then the joins\n for (const t of parsed.tables) {\n if (t.join === \"inner\") {\n sql += ` JOIN ${as(t)} ON ${t.col1} = ${t.col2}`;\n } else if (t.join === \"outer\") {\n sql += ` LEFT OUTER JOIN ${as(t)} ON ${t.col1} = ${t.col2}`;\n } else if (t.join === \"primary\") {\n // handled above\n } else if (t.join === \"lateral\") {\n const { sql: subQ, bindings: subB } = buildRawQuery(t.query, t.settings ?? {});\n sql += ` CROSS JOIN LATERAL (${subQ}) AS ${kq(t.alias)}`;\n bindings.push(...subB);\n } else if (t.join === \"cross\") {\n sql += ` CROSS JOIN ${as(t)}`;\n } else {\n assertNever(t.join);\n }\n }\n\n if (parsed.condition) {\n const where = buildWhereClause(parsed.condition, true, subqueryRenderer);\n if (where) {\n sql += \" WHERE \" + where[0];\n bindings.push(...where[1]);\n }\n }\n\n if (parsed.groupBys && parsed.groupBys.length > 0) {\n sql +=\n \" GROUP BY \" +\n parsed.groupBys.map((gb) => (\"expression\" in gb ? gb.expression : kqDot(gb.alias, gb.column))).join(\", \");\n }\n\n if (parsed.orderBys.length > 0) {\n sql += \" ORDER BY \" + parsed.orderBys.map((ob) => kqDot(ob.alias, ob.column) + \" \" + ob.order).join(\", \");\n }\n\n if (limit !== undefined) {\n sql += ` LIMIT ?`;\n bindings.push(limit);\n }\n if (offset !== undefined) {\n sql += ` OFFSET ?`;\n bindings.push(offset);\n }\n\n return { sql, bindings };\n}\n\nfunction buildDistinctOn(parsed: ParsedFindQuery, primary: ParsedTable): string {\n const columns = [\n // If we have an order by, it needs to be included in the DISTINCT ON\n ...parsed.orderBys.map((ob) => kqDot(ob.alias, ob.column)),\n kqDot(primary.alias, \"id\"),\n ];\n return `DISTINCT ON (${columns.join(\", \")}) `;\n}\n\n/** Creates the `WITH alias (...)` SQL for the given `cte`. */\nexport function buildCteSql(cte: ParsedCteClause): { sql: string; bindings: readonly any[] } {\n const maybeRecursive = cte.recursive ? \"RECURSIVE \" : \"\";\n const maybeColumns = cte.columns ? ` (${cte.columns.map((c) => kq(c.columnName)).join(\", \")})` : \"\";\n const prefix = `WITH ${maybeRecursive}${cte.alias}${maybeColumns} AS`;\n if (cte.query.kind === \"raw\") {\n return {\n sql: `${prefix} (${cleanSql(cte.query.sql)} )`,\n bindings: cte.query.bindings,\n };\n } else if (cte.query.kind === \"ast\") {\n const { sql, bindings } = buildRawQuery(cte.query.query, {});\n return { sql: `${prefix} (${sql})`, bindings };\n } else {\n assertNever(cte.query);\n }\n}\n\nconst as = (t: ParsedTable) => `${kq(t.table)} AS ${kq(t.alias)}`;\n"],"mappings":"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"}
1
+ {"version":3,"file":"buildFindQuery.cjs","names":["kq","cleanSql","kqDot","buildWhereClause"],"sources":["../../../src/queries/find/buildFindQuery.ts"],"sourcesContent":["import type { ParsedCteClause, ParsedFindQuery, ParsedTable } from \"src/queries/find/QueryParser.ts\";\nimport { buildWhereClause } from \"src/queries/renderConditions.ts\";\nimport { kq, kqDot } from \"src/queries/sql/keywords.ts\";\nimport { assertNever, cleanSql } from \"src/utils.ts\";\n\ntype QuerySettings = { limit?: number; offset?: number };\n\n/**\n * Transforms `ParsedFindQuery` into a raw SQL string.\n *\n * In theory this should be implemented within each Driver, but the logic will be largely\n * the same for different dbs.\n */\nexport function buildRawQuery(\n parsed: ParsedFindQuery,\n settings: QuerySettings,\n): { sql: string; bindings: readonly any[] } {\n const { limit, offset } = settings;\n\n const primary = parsed.tables.find((t) => t.join === \"primary\")!;\n\n // If we're doing o2m joins, add a `DISTINCT` clause to avoid duplicates\n const needsDistinct =\n parsed.tables.some((t) => t.join === \"outer\" && t.distinct !== false) &&\n // If this is a `findCount`, it will rewrite the `select` to have its own distinct\n !parsed.selects.find((s) => typeof s === \"string\" && s.startsWith(\"count(\"));\n\n let sql = \"\";\n const bindings: any[] = [];\n\n if (parsed.ctes && parsed.ctes.length > 0) {\n const hasRecursive = parsed.ctes.some((cte) => cte.recursive);\n const maybeRecursive = hasRecursive ? \" RECURSIVE\" : \"\";\n sql += `WITH${maybeRecursive}`;\n for (let i = 0; i < parsed.ctes.length; i++) {\n const cte = parsed.ctes[i];\n sql += i > 0 ? \", \" : \"\";\n sql += ` ${cte.alias}`;\n if (cte.columns) {\n sql += \" (\";\n for (let j = 0; j < cte.columns.length; j++) {\n sql += j > 0 ? \", \" : \"\";\n sql += kq(cte.columns[j].columnName);\n }\n sql += \")\";\n }\n if (cte.query.kind === \"raw\") {\n sql += ` AS (${cleanSql(cte.query.sql)})`;\n bindings.push(...cte.query.bindings);\n } else if (cte.query.kind === \"ast\") {\n const nested = buildRawQuery(cte.query.query, {});\n sql += ` AS (${nested.sql})`;\n bindings.push(...nested.bindings);\n } else {\n assertNever(cte.query);\n }\n }\n sql += \" \";\n }\n\n sql += \"SELECT \";\n const subqueryRenderer = (q: ParsedFindQuery) => buildRawQuery(q, {});\n\n parsed.selects.forEach((s, i) => {\n const maybeDistinct = i === 0 && needsDistinct ? buildDistinctOn(parsed, primary) : \"\";\n const maybeComma = i === parsed.selects.length - 1 ? \"\" : \", \";\n if (typeof s === \"string\") {\n sql += maybeDistinct + s + maybeComma;\n } else if (\"sql\" in s) {\n sql += maybeDistinct + s.sql + maybeComma;\n bindings.push(...s.bindings);\n }\n });\n\n // If we're doing \"select distinct\" for o2m joins, then all order bys must be selects\n if (needsDistinct && parsed.orderBys.length > 0) {\n for (const { alias, column } of parsed.orderBys) {\n sql += `, ${kqDot(alias, column)}`;\n }\n }\n\n // Make sure the primary is first\n sql += ` FROM ${as(primary)}`;\n\n // Then the joins\n for (const t of parsed.tables) {\n if (t.join === \"inner\") {\n sql += ` JOIN ${as(t)} ON ${t.col1} = ${t.col2}`;\n } else if (t.join === \"outer\") {\n sql += ` LEFT OUTER JOIN ${as(t)} ON ${t.col1} = ${t.col2}`;\n } else if (t.join === \"primary\") {\n // handled above\n } else if (t.join === \"lateral\") {\n const { sql: subQ, bindings: subB } = buildRawQuery(t.query, t.settings ?? {});\n sql += ` CROSS JOIN LATERAL (${subQ}) AS ${kq(t.alias)}`;\n bindings.push(...subB);\n } else if (t.join === \"cross\") {\n sql += ` CROSS JOIN ${as(t)}`;\n } else {\n assertNever(t.join);\n }\n }\n\n if (parsed.condition) {\n const where = buildWhereClause(parsed.condition, true, subqueryRenderer);\n if (where) {\n sql += \" WHERE \" + where[0];\n bindings.push(...where[1]);\n }\n }\n\n if (parsed.groupBys && parsed.groupBys.length > 0) {\n sql +=\n \" GROUP BY \" +\n parsed.groupBys.map((gb) => (\"expression\" in gb ? gb.expression : kqDot(gb.alias, gb.column))).join(\", \");\n }\n\n if (parsed.orderBys.length > 0) {\n sql += \" ORDER BY \" + parsed.orderBys.map((ob) => kqDot(ob.alias, ob.column) + \" \" + ob.order).join(\", \");\n }\n\n if (limit !== undefined) {\n sql += ` LIMIT ?`;\n bindings.push(limit);\n }\n if (offset !== undefined) {\n sql += ` OFFSET ?`;\n bindings.push(offset);\n }\n\n return { sql, bindings };\n}\n\nfunction buildDistinctOn(parsed: ParsedFindQuery, primary: ParsedTable): string {\n const columns = [\n // If we have an order by, it needs to be included in the DISTINCT ON\n ...parsed.orderBys.map((ob) => kqDot(ob.alias, ob.column)),\n kqDot(primary.alias, \"id\"),\n ];\n return `DISTINCT ON (${columns.join(\", \")}) `;\n}\n\n/** Creates the `WITH alias (...)` SQL for the given `cte`. */\nexport function buildCteSql(cte: ParsedCteClause): { sql: string; bindings: readonly any[] } {\n const maybeRecursive = cte.recursive ? \"RECURSIVE \" : \"\";\n const maybeColumns = cte.columns ? ` (${cte.columns.map((c) => kq(c.columnName)).join(\", \")})` : \"\";\n const prefix = `WITH ${maybeRecursive}${cte.alias}${maybeColumns} AS`;\n if (cte.query.kind === \"raw\") {\n return {\n sql: `${prefix} (${cleanSql(cte.query.sql)} )`,\n bindings: cte.query.bindings,\n };\n } else if (cte.query.kind === \"ast\") {\n const { sql, bindings } = buildRawQuery(cte.query.query, {});\n return { sql: `${prefix} (${sql})`, bindings };\n } else {\n assertNever(cte.query);\n }\n}\n\nconst as = (t: ParsedTable) => `${kq(t.table)} AS ${kq(t.alias)}`;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"buildFindQuery.js","names":[],"sources":["../../../src/queries/find/buildFindQuery.ts"],"sourcesContent":["import { assertNever, cleanSql } from \"../../utils.ts\";\nimport { buildWhereClause } from \"../renderConditions.ts\";\nimport { kq, kqDot } from \"../sql/keywords.ts\";\nimport type { ParsedCteClause, ParsedFindQuery, ParsedTable } from \"./QueryParser.ts\";\n\ntype QuerySettings = { limit?: number; offset?: number };\n\n/**\n * Transforms `ParsedFindQuery` into a raw SQL string.\n *\n * In theory this should be implemented within each Driver, but the logic will be largely\n * the same for different dbs.\n */\nexport function buildRawQuery(\n parsed: ParsedFindQuery,\n settings: QuerySettings,\n): { sql: string; bindings: readonly any[] } {\n const { limit, offset } = settings;\n\n const primary = parsed.tables.find((t) => t.join === \"primary\")!;\n\n // If we're doing o2m joins, add a `DISTINCT` clause to avoid duplicates\n const needsDistinct =\n parsed.tables.some((t) => t.join === \"outer\" && t.distinct !== false) &&\n // If this is a `findCount`, it will rewrite the `select` to have its own distinct\n !parsed.selects.find((s) => typeof s === \"string\" && s.startsWith(\"count(\"));\n\n let sql = \"\";\n const bindings: any[] = [];\n\n if (parsed.ctes && parsed.ctes.length > 0) {\n const hasRecursive = parsed.ctes.some((cte) => cte.recursive);\n const maybeRecursive = hasRecursive ? \" RECURSIVE\" : \"\";\n sql += `WITH${maybeRecursive}`;\n for (let i = 0; i < parsed.ctes.length; i++) {\n const cte = parsed.ctes[i];\n sql += i > 0 ? \", \" : \"\";\n sql += ` ${cte.alias}`;\n if (cte.columns) {\n sql += \" (\";\n for (let j = 0; j < cte.columns.length; j++) {\n sql += j > 0 ? \", \" : \"\";\n sql += kq(cte.columns[j].columnName);\n }\n sql += \")\";\n }\n if (cte.query.kind === \"raw\") {\n sql += ` AS (${cleanSql(cte.query.sql)})`;\n bindings.push(...cte.query.bindings);\n } else if (cte.query.kind === \"ast\") {\n const nested = buildRawQuery(cte.query.query, {});\n sql += ` AS (${nested.sql})`;\n bindings.push(...nested.bindings);\n } else {\n assertNever(cte.query);\n }\n }\n sql += \" \";\n }\n\n sql += \"SELECT \";\n const subqueryRenderer = (q: ParsedFindQuery) => buildRawQuery(q, {});\n\n parsed.selects.forEach((s, i) => {\n const maybeDistinct = i === 0 && needsDistinct ? buildDistinctOn(parsed, primary) : \"\";\n const maybeComma = i === parsed.selects.length - 1 ? \"\" : \", \";\n if (typeof s === \"string\") {\n sql += maybeDistinct + s + maybeComma;\n } else if (\"sql\" in s) {\n sql += maybeDistinct + s.sql + maybeComma;\n bindings.push(...s.bindings);\n }\n });\n\n // If we're doing \"select distinct\" for o2m joins, then all order bys must be selects\n if (needsDistinct && parsed.orderBys.length > 0) {\n for (const { alias, column } of parsed.orderBys) {\n sql += `, ${kqDot(alias, column)}`;\n }\n }\n\n // Make sure the primary is first\n sql += ` FROM ${as(primary)}`;\n\n // Then the joins\n for (const t of parsed.tables) {\n if (t.join === \"inner\") {\n sql += ` JOIN ${as(t)} ON ${t.col1} = ${t.col2}`;\n } else if (t.join === \"outer\") {\n sql += ` LEFT OUTER JOIN ${as(t)} ON ${t.col1} = ${t.col2}`;\n } else if (t.join === \"primary\") {\n // handled above\n } else if (t.join === \"lateral\") {\n const { sql: subQ, bindings: subB } = buildRawQuery(t.query, t.settings ?? {});\n sql += ` CROSS JOIN LATERAL (${subQ}) AS ${kq(t.alias)}`;\n bindings.push(...subB);\n } else if (t.join === \"cross\") {\n sql += ` CROSS JOIN ${as(t)}`;\n } else {\n assertNever(t.join);\n }\n }\n\n if (parsed.condition) {\n const where = buildWhereClause(parsed.condition, true, subqueryRenderer);\n if (where) {\n sql += \" WHERE \" + where[0];\n bindings.push(...where[1]);\n }\n }\n\n if (parsed.groupBys && parsed.groupBys.length > 0) {\n sql +=\n \" GROUP BY \" +\n parsed.groupBys.map((gb) => (\"expression\" in gb ? gb.expression : kqDot(gb.alias, gb.column))).join(\", \");\n }\n\n if (parsed.orderBys.length > 0) {\n sql += \" ORDER BY \" + parsed.orderBys.map((ob) => kqDot(ob.alias, ob.column) + \" \" + ob.order).join(\", \");\n }\n\n if (limit !== undefined) {\n sql += ` LIMIT ?`;\n bindings.push(limit);\n }\n if (offset !== undefined) {\n sql += ` OFFSET ?`;\n bindings.push(offset);\n }\n\n return { sql, bindings };\n}\n\nfunction buildDistinctOn(parsed: ParsedFindQuery, primary: ParsedTable): string {\n const columns = [\n // If we have an order by, it needs to be included in the DISTINCT ON\n ...parsed.orderBys.map((ob) => kqDot(ob.alias, ob.column)),\n kqDot(primary.alias, \"id\"),\n ];\n return `DISTINCT ON (${columns.join(\", \")}) `;\n}\n\n/** Creates the `WITH alias (...)` SQL for the given `cte`. */\nexport function buildCteSql(cte: ParsedCteClause): { sql: string; bindings: readonly any[] } {\n const maybeRecursive = cte.recursive ? \"RECURSIVE \" : \"\";\n const maybeColumns = cte.columns ? ` (${cte.columns.map((c) => kq(c.columnName)).join(\", \")})` : \"\";\n const prefix = `WITH ${maybeRecursive}${cte.alias}${maybeColumns} AS`;\n if (cte.query.kind === \"raw\") {\n return {\n sql: `${prefix} (${cleanSql(cte.query.sql)} )`,\n bindings: cte.query.bindings,\n };\n } else if (cte.query.kind === \"ast\") {\n const { sql, bindings } = buildRawQuery(cte.query.query, {});\n return { sql: `${prefix} (${sql})`, bindings };\n } else {\n assertNever(cte.query);\n }\n}\n\nconst as = (t: ParsedTable) => `${kq(t.table)} AS ${kq(t.alias)}`;\n"],"mappings":"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"}
1
+ {"version":3,"file":"buildFindQuery.js","names":[],"sources":["../../../src/queries/find/buildFindQuery.ts"],"sourcesContent":["import type { ParsedCteClause, ParsedFindQuery, ParsedTable } from \"src/queries/find/QueryParser.ts\";\nimport { buildWhereClause } from \"src/queries/renderConditions.ts\";\nimport { kq, kqDot } from \"src/queries/sql/keywords.ts\";\nimport { assertNever, cleanSql } from \"src/utils.ts\";\n\ntype QuerySettings = { limit?: number; offset?: number };\n\n/**\n * Transforms `ParsedFindQuery` into a raw SQL string.\n *\n * In theory this should be implemented within each Driver, but the logic will be largely\n * the same for different dbs.\n */\nexport function buildRawQuery(\n parsed: ParsedFindQuery,\n settings: QuerySettings,\n): { sql: string; bindings: readonly any[] } {\n const { limit, offset } = settings;\n\n const primary = parsed.tables.find((t) => t.join === \"primary\")!;\n\n // If we're doing o2m joins, add a `DISTINCT` clause to avoid duplicates\n const needsDistinct =\n parsed.tables.some((t) => t.join === \"outer\" && t.distinct !== false) &&\n // If this is a `findCount`, it will rewrite the `select` to have its own distinct\n !parsed.selects.find((s) => typeof s === \"string\" && s.startsWith(\"count(\"));\n\n let sql = \"\";\n const bindings: any[] = [];\n\n if (parsed.ctes && parsed.ctes.length > 0) {\n const hasRecursive = parsed.ctes.some((cte) => cte.recursive);\n const maybeRecursive = hasRecursive ? \" RECURSIVE\" : \"\";\n sql += `WITH${maybeRecursive}`;\n for (let i = 0; i < parsed.ctes.length; i++) {\n const cte = parsed.ctes[i];\n sql += i > 0 ? \", \" : \"\";\n sql += ` ${cte.alias}`;\n if (cte.columns) {\n sql += \" (\";\n for (let j = 0; j < cte.columns.length; j++) {\n sql += j > 0 ? \", \" : \"\";\n sql += kq(cte.columns[j].columnName);\n }\n sql += \")\";\n }\n if (cte.query.kind === \"raw\") {\n sql += ` AS (${cleanSql(cte.query.sql)})`;\n bindings.push(...cte.query.bindings);\n } else if (cte.query.kind === \"ast\") {\n const nested = buildRawQuery(cte.query.query, {});\n sql += ` AS (${nested.sql})`;\n bindings.push(...nested.bindings);\n } else {\n assertNever(cte.query);\n }\n }\n sql += \" \";\n }\n\n sql += \"SELECT \";\n const subqueryRenderer = (q: ParsedFindQuery) => buildRawQuery(q, {});\n\n parsed.selects.forEach((s, i) => {\n const maybeDistinct = i === 0 && needsDistinct ? buildDistinctOn(parsed, primary) : \"\";\n const maybeComma = i === parsed.selects.length - 1 ? \"\" : \", \";\n if (typeof s === \"string\") {\n sql += maybeDistinct + s + maybeComma;\n } else if (\"sql\" in s) {\n sql += maybeDistinct + s.sql + maybeComma;\n bindings.push(...s.bindings);\n }\n });\n\n // If we're doing \"select distinct\" for o2m joins, then all order bys must be selects\n if (needsDistinct && parsed.orderBys.length > 0) {\n for (const { alias, column } of parsed.orderBys) {\n sql += `, ${kqDot(alias, column)}`;\n }\n }\n\n // Make sure the primary is first\n sql += ` FROM ${as(primary)}`;\n\n // Then the joins\n for (const t of parsed.tables) {\n if (t.join === \"inner\") {\n sql += ` JOIN ${as(t)} ON ${t.col1} = ${t.col2}`;\n } else if (t.join === \"outer\") {\n sql += ` LEFT OUTER JOIN ${as(t)} ON ${t.col1} = ${t.col2}`;\n } else if (t.join === \"primary\") {\n // handled above\n } else if (t.join === \"lateral\") {\n const { sql: subQ, bindings: subB } = buildRawQuery(t.query, t.settings ?? {});\n sql += ` CROSS JOIN LATERAL (${subQ}) AS ${kq(t.alias)}`;\n bindings.push(...subB);\n } else if (t.join === \"cross\") {\n sql += ` CROSS JOIN ${as(t)}`;\n } else {\n assertNever(t.join);\n }\n }\n\n if (parsed.condition) {\n const where = buildWhereClause(parsed.condition, true, subqueryRenderer);\n if (where) {\n sql += \" WHERE \" + where[0];\n bindings.push(...where[1]);\n }\n }\n\n if (parsed.groupBys && parsed.groupBys.length > 0) {\n sql +=\n \" GROUP BY \" +\n parsed.groupBys.map((gb) => (\"expression\" in gb ? gb.expression : kqDot(gb.alias, gb.column))).join(\", \");\n }\n\n if (parsed.orderBys.length > 0) {\n sql += \" ORDER BY \" + parsed.orderBys.map((ob) => kqDot(ob.alias, ob.column) + \" \" + ob.order).join(\", \");\n }\n\n if (limit !== undefined) {\n sql += ` LIMIT ?`;\n bindings.push(limit);\n }\n if (offset !== undefined) {\n sql += ` OFFSET ?`;\n bindings.push(offset);\n }\n\n return { sql, bindings };\n}\n\nfunction buildDistinctOn(parsed: ParsedFindQuery, primary: ParsedTable): string {\n const columns = [\n // If we have an order by, it needs to be included in the DISTINCT ON\n ...parsed.orderBys.map((ob) => kqDot(ob.alias, ob.column)),\n kqDot(primary.alias, \"id\"),\n ];\n return `DISTINCT ON (${columns.join(\", \")}) `;\n}\n\n/** Creates the `WITH alias (...)` SQL for the given `cte`. */\nexport function buildCteSql(cte: ParsedCteClause): { sql: string; bindings: readonly any[] } {\n const maybeRecursive = cte.recursive ? \"RECURSIVE \" : \"\";\n const maybeColumns = cte.columns ? ` (${cte.columns.map((c) => kq(c.columnName)).join(\", \")})` : \"\";\n const prefix = `WITH ${maybeRecursive}${cte.alias}${maybeColumns} AS`;\n if (cte.query.kind === \"raw\") {\n return {\n sql: `${prefix} (${cleanSql(cte.query.sql)} )`,\n bindings: cte.query.bindings,\n };\n } else if (cte.query.kind === \"ast\") {\n const { sql, bindings } = buildRawQuery(cte.query.query, {});\n return { sql: `${prefix} (${sql})`, bindings };\n } else {\n assertNever(cte.query);\n }\n}\n\nconst as = (t: ParsedTable) => `${kq(t.table)} AS ${kq(t.alias)}`;\n"],"mappings":"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"}