@nicia-ai/typegraph 0.37.1 → 0.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -10
- package/dist/backend/drizzle/indexes.cjs +32 -0
- package/dist/backend/drizzle/indexes.cjs.map +1 -0
- package/dist/backend/drizzle/indexes.d.cts +43 -0
- package/dist/backend/drizzle/indexes.d.ts +43 -0
- package/dist/backend/drizzle/indexes.js +11 -0
- package/dist/backend/drizzle/indexes.js.map +1 -0
- package/dist/backend/index.cjs +161 -0
- package/dist/backend/index.cjs.map +1 -0
- package/dist/backend/index.d.cts +3 -0
- package/dist/backend/index.d.ts +3 -0
- package/dist/backend/index.js +8 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/postgres/index.cjs +32 -28
- package/dist/backend/postgres/index.d.cts +13 -12
- package/dist/backend/postgres/index.d.ts +13 -12
- package/dist/backend/postgres/index.js +19 -15
- package/dist/backend/postgres/pglite-store.cjs +67 -0
- package/dist/backend/postgres/pglite-store.cjs.map +1 -0
- package/dist/backend/postgres/pglite-store.d.cts +38 -0
- package/dist/backend/postgres/pglite-store.d.ts +38 -0
- package/dist/backend/postgres/pglite-store.js +65 -0
- package/dist/backend/postgres/pglite-store.js.map +1 -0
- package/dist/backend/postgres/pglite.cjs +25 -50
- package/dist/backend/postgres/pglite.cjs.map +1 -1
- package/dist/backend/postgres/pglite.d.cts +10 -9
- package/dist/backend/postgres/pglite.d.ts +10 -9
- package/dist/backend/postgres/pglite.js +20 -52
- package/dist/backend/postgres/pglite.js.map +1 -1
- package/dist/backend/sqlite/index.cjs +29 -25
- package/dist/backend/sqlite/index.d.cts +11 -11
- package/dist/backend/sqlite/index.d.ts +11 -11
- package/dist/backend/sqlite/index.js +17 -13
- package/dist/backend/sqlite/libsql.cjs +23 -19
- package/dist/backend/sqlite/libsql.cjs.map +1 -1
- package/dist/backend/sqlite/libsql.d.cts +9 -10
- package/dist/backend/sqlite/libsql.d.ts +9 -10
- package/dist/backend/sqlite/libsql.js +19 -15
- package/dist/backend/sqlite/libsql.js.map +1 -1
- package/dist/backend/sqlite/local-store.cjs +72 -0
- package/dist/backend/sqlite/local-store.cjs.map +1 -0
- package/dist/backend/sqlite/local-store.d.cts +42 -0
- package/dist/backend/sqlite/local-store.d.ts +42 -0
- package/dist/backend/sqlite/local-store.js +67 -0
- package/dist/backend/sqlite/local-store.js.map +1 -0
- package/dist/backend/sqlite/local.cjs +28 -183
- package/dist/backend/sqlite/local.cjs.map +1 -1
- package/dist/backend/sqlite/local.d.cts +8 -81
- package/dist/backend/sqlite/local.d.ts +8 -81
- package/dist/backend/sqlite/local.js +20 -180
- package/dist/backend/sqlite/local.js.map +1 -1
- package/dist/chunk-2EBMPJBO.js +16 -0
- package/dist/chunk-2EBMPJBO.js.map +1 -0
- package/dist/chunk-35S6P5ZU.js +27 -0
- package/dist/chunk-35S6P5ZU.js.map +1 -0
- package/dist/chunk-3LKL3S6X.js +50 -0
- package/dist/chunk-3LKL3S6X.js.map +1 -0
- package/dist/{chunk-RCVLFTCT.js → chunk-3SK4SVTW.js} +13 -12
- package/dist/chunk-3SK4SVTW.js.map +1 -0
- package/dist/chunk-3YFDFOYB.cjs +192 -0
- package/dist/chunk-3YFDFOYB.cjs.map +1 -0
- package/dist/{chunk-WOJMKB3N.cjs → chunk-5ELKD2FQ.cjs} +1677 -308
- package/dist/chunk-5ELKD2FQ.cjs.map +1 -0
- package/dist/{chunk-5AVRFNP4.cjs → chunk-6SRLCSAV.cjs} +3012 -1513
- package/dist/chunk-6SRLCSAV.cjs.map +1 -0
- package/dist/chunk-6XDBRDZE.js +312 -0
- package/dist/chunk-6XDBRDZE.js.map +1 -0
- package/dist/chunk-764JHTLT.cjs +15 -0
- package/dist/chunk-764JHTLT.cjs.map +1 -0
- package/dist/chunk-76HE7DJP.js +68 -0
- package/dist/chunk-76HE7DJP.js.map +1 -0
- package/dist/{chunk-VGDDG3XJ.cjs → chunk-7M3NACL3.cjs} +12 -12
- package/dist/{chunk-VGDDG3XJ.cjs.map → chunk-7M3NACL3.cjs.map} +1 -1
- package/dist/chunk-AOL64O4Z.js +165 -0
- package/dist/chunk-AOL64O4Z.js.map +1 -0
- package/dist/{chunk-27SSDCEP.cjs → chunk-B63IFHXR.cjs} +53 -74
- package/dist/chunk-B63IFHXR.cjs.map +1 -0
- package/dist/{chunk-3XXGYU62.cjs → chunk-BKAKAVRW.cjs} +56 -53
- package/dist/chunk-BKAKAVRW.cjs.map +1 -0
- package/dist/{chunk-YTSN73ND.js → chunk-BQITNFQJ.js} +3 -3
- package/dist/{chunk-YTSN73ND.js.map → chunk-BQITNFQJ.js.map} +1 -1
- package/dist/{chunk-GA4TT3DH.js → chunk-CBK2IVI2.js} +1999 -503
- package/dist/chunk-CBK2IVI2.js.map +1 -0
- package/dist/{chunk-6EEO3OVU.cjs → chunk-CWX77JB4.cjs} +22 -59
- package/dist/chunk-CWX77JB4.cjs.map +1 -0
- package/dist/{chunk-UGZUAYAR.js → chunk-D7PG5D5K.js} +4 -3
- package/dist/chunk-D7PG5D5K.js.map +1 -0
- package/dist/chunk-DDCIXXOO.js +9 -0
- package/dist/chunk-DDCIXXOO.js.map +1 -0
- package/dist/chunk-DDCYVIVV.cjs +44 -0
- package/dist/chunk-DDCYVIVV.cjs.map +1 -0
- package/dist/{chunk-UV3WP5WZ.js → chunk-DOKUXLFH.js} +61 -29
- package/dist/chunk-DOKUXLFH.js.map +1 -0
- package/dist/{chunk-XPCZADMT.cjs → chunk-DOVMTPKE.cjs} +89 -27
- package/dist/chunk-DOVMTPKE.cjs.map +1 -0
- package/dist/{chunk-5PNMDJ7J.js → chunk-DPNA466P.js} +14 -9
- package/dist/chunk-DPNA466P.js.map +1 -0
- package/dist/{chunk-BYPOGQWK.js → chunk-DRACN6XG.js} +6 -4
- package/dist/chunk-DRACN6XG.js.map +1 -0
- package/dist/{chunk-TGOMW4MB.cjs → chunk-E2Q7SP2K.cjs} +110 -109
- package/dist/chunk-E2Q7SP2K.cjs.map +1 -0
- package/dist/chunk-E6TXEISH.cjs +175 -0
- package/dist/chunk-E6TXEISH.cjs.map +1 -0
- package/dist/{chunk-3C2RYI6L.cjs → chunk-EOJFGECD.cjs} +11 -11
- package/dist/chunk-EOJFGECD.cjs.map +1 -0
- package/dist/{chunk-XWV4JT34.js → chunk-ERZ4QPQX.js} +27 -22
- package/dist/chunk-ERZ4QPQX.js.map +1 -0
- package/dist/{chunk-DFVLCOP6.js → chunk-EZH7FNUS.js} +3 -3
- package/dist/{chunk-DFVLCOP6.js.map → chunk-EZH7FNUS.js.map} +1 -1
- package/dist/{chunk-WWFHO375.cjs → chunk-FJMPR3OH.cjs} +4 -3
- package/dist/chunk-FJMPR3OH.cjs.map +1 -0
- package/dist/chunk-FMNUSGZ4.cjs +12 -0
- package/dist/chunk-FMNUSGZ4.cjs.map +1 -0
- package/dist/{chunk-EXU3RASM.js → chunk-G3CSQLLT.js} +20 -474
- package/dist/chunk-G3CSQLLT.js.map +1 -0
- package/dist/{chunk-EJYMTO3K.cjs → chunk-GKQU44SQ.cjs} +150 -118
- package/dist/chunk-GKQU44SQ.cjs.map +1 -0
- package/dist/chunk-GNPGGLAE.cjs +212 -0
- package/dist/chunk-GNPGGLAE.cjs.map +1 -0
- package/dist/{chunk-QARBLBXT.cjs → chunk-GUUWKPTK.cjs} +7 -7
- package/dist/{chunk-QARBLBXT.cjs.map → chunk-GUUWKPTK.cjs.map} +1 -1
- package/dist/chunk-GYA4JRP5.js +31 -0
- package/dist/chunk-GYA4JRP5.js.map +1 -0
- package/dist/{chunk-3GH67G4Z.cjs → chunk-HP6LWBLB.cjs} +16 -42
- package/dist/chunk-HP6LWBLB.cjs.map +1 -0
- package/dist/{chunk-NXQFATMF.cjs → chunk-HTQOBY75.cjs} +153 -123
- package/dist/chunk-HTQOBY75.cjs.map +1 -0
- package/dist/chunk-I6FX7AAG.js +39 -0
- package/dist/chunk-I6FX7AAG.js.map +1 -0
- package/dist/{chunk-VKGKDOKR.js → chunk-IFDXG2YJ.js} +1539 -206
- package/dist/chunk-IFDXG2YJ.js.map +1 -0
- package/dist/{chunk-IXGYRP2P.js → chunk-IFRPHG7O.js} +79 -49
- package/dist/chunk-IFRPHG7O.js.map +1 -0
- package/dist/chunk-IMQKXL4E.cjs +12 -0
- package/dist/{chunk-QSXTWU4U.cjs.map → chunk-IMQKXL4E.cjs.map} +1 -1
- package/dist/chunk-J6IJARLG.js +94 -0
- package/dist/chunk-J6IJARLG.js.map +1 -0
- package/dist/{chunk-3DS7Z4T4.cjs → chunk-JD2YC62H.cjs} +44 -43
- package/dist/chunk-JD2YC62H.cjs.map +1 -0
- package/dist/{chunk-W63OVYY4.js → chunk-K34OPSJK.js} +3 -3
- package/dist/{chunk-W63OVYY4.js.map → chunk-K34OPSJK.js.map} +1 -1
- package/dist/chunk-KAFXPB2L.js +184 -0
- package/dist/chunk-KAFXPB2L.js.map +1 -0
- package/dist/chunk-KIZSHRUI.cjs +49 -0
- package/dist/chunk-KIZSHRUI.cjs.map +1 -0
- package/dist/{chunk-K3Q3LJY3.js → chunk-KXFUQNF2.js} +201 -100
- package/dist/chunk-KXFUQNF2.js.map +1 -0
- package/dist/{chunk-UXLSNRYL.js → chunk-MTNEGGM2.js} +4 -4
- package/dist/chunk-MTNEGGM2.js.map +1 -0
- package/dist/{chunk-IP3CGGPA.cjs → chunk-N2V3HJFV.cjs} +92 -185
- package/dist/chunk-N2V3HJFV.cjs.map +1 -0
- package/dist/chunk-NAUA4PW5.cjs +28 -0
- package/dist/chunk-NAUA4PW5.cjs.map +1 -0
- package/dist/chunk-NMQ6C6TS.cjs +61 -0
- package/dist/chunk-NMQ6C6TS.cjs.map +1 -0
- package/dist/{chunk-2N6EOBTH.cjs → chunk-NPWACFQJ.cjs} +58 -53
- package/dist/chunk-NPWACFQJ.cjs.map +1 -0
- package/dist/{chunk-TKT2XHED.js → chunk-NQBYTLPW.js} +13 -12
- package/dist/chunk-NQBYTLPW.js.map +1 -0
- package/dist/{chunk-5KEQ74YU.cjs → chunk-NT6ILURI.cjs} +9 -86
- package/dist/chunk-NT6ILURI.cjs.map +1 -0
- package/dist/{chunk-3SLPDKHQ.js → chunk-PH4IJ3V5.js} +5 -77
- package/dist/chunk-PH4IJ3V5.js.map +1 -0
- package/dist/chunk-PWXGB77L.cjs +56 -0
- package/dist/chunk-PWXGB77L.cjs.map +1 -0
- package/dist/chunk-PZHC5GCD.js +193 -0
- package/dist/chunk-PZHC5GCD.js.map +1 -0
- package/dist/chunk-QMQLUA66.js +12 -0
- package/dist/chunk-QMQLUA66.js.map +1 -0
- package/dist/{chunk-5WWVZMVX.js → chunk-QZ7A6HBM.js} +2 -2
- package/dist/{chunk-5WWVZMVX.js.map → chunk-QZ7A6HBM.js.map} +1 -1
- package/dist/chunk-RW24SAHI.cjs +74 -0
- package/dist/chunk-RW24SAHI.cjs.map +1 -0
- package/dist/{chunk-BVRDGYXQ.cjs → chunk-SAFZ6JTI.cjs} +14 -9
- package/dist/chunk-SAFZ6JTI.cjs.map +1 -0
- package/dist/{chunk-L7HQ2OSI.js → chunk-SCTZRFW5.js} +87 -166
- package/dist/chunk-SCTZRFW5.js.map +1 -0
- package/dist/{chunk-5KPNWT6X.js → chunk-SDHV2MWU.js} +24 -45
- package/dist/chunk-SDHV2MWU.js.map +1 -0
- package/dist/{chunk-3RWZPJKV.js → chunk-SU7VQOJ3.js} +21 -78
- package/dist/chunk-SU7VQOJ3.js.map +1 -0
- package/dist/chunk-SVJ5GEXW.cjs +45 -0
- package/dist/chunk-SVJ5GEXW.cjs.map +1 -0
- package/dist/chunk-SVUKGWSN.cjs +102 -0
- package/dist/chunk-SVUKGWSN.cjs.map +1 -0
- package/dist/chunk-TAUGGLNQ.js +59 -0
- package/dist/chunk-TAUGGLNQ.js.map +1 -0
- package/dist/{chunk-A42GCBGX.cjs → chunk-TRF4EBJT.cjs} +6 -4
- package/dist/chunk-TRF4EBJT.cjs.map +1 -0
- package/dist/{chunk-KQJ54OG5.js → chunk-U4JDJKPD.js} +19 -56
- package/dist/chunk-U4JDJKPD.js.map +1 -0
- package/dist/chunk-UH2USOMG.cjs +627 -0
- package/dist/chunk-UH2USOMG.cjs.map +1 -0
- package/dist/{chunk-XGPUQ56G.js → chunk-UUIBACKJ.js} +15 -38
- package/dist/chunk-UUIBACKJ.js.map +1 -0
- package/dist/{chunk-5VQM6VWP.cjs → chunk-UWG5GX6E.cjs} +2 -2
- package/dist/{chunk-5VQM6VWP.cjs.map → chunk-UWG5GX6E.cjs.map} +1 -1
- package/dist/{chunk-K5UBVGJN.js → chunk-VDYA2HMS.js} +6 -6
- package/dist/{chunk-K5UBVGJN.js.map → chunk-VDYA2HMS.js.map} +1 -1
- package/dist/{chunk-NUIG3BCV.cjs → chunk-VXAFOF6Z.cjs} +93 -155
- package/dist/chunk-VXAFOF6Z.cjs.map +1 -0
- package/dist/chunk-X4PVHAZ6.cjs +83 -0
- package/dist/chunk-X4PVHAZ6.cjs.map +1 -0
- package/dist/{chunk-UYQMBBWJ.js → chunk-X6CNEA32.js} +23 -20
- package/dist/chunk-X6CNEA32.js.map +1 -0
- package/dist/chunk-X6RDQ5NB.cjs +335 -0
- package/dist/chunk-X6RDQ5NB.cjs.map +1 -0
- package/dist/{chunk-DEFQM7JU.cjs → chunk-XRU7V7FF.cjs} +7 -7
- package/dist/{chunk-DEFQM7JU.cjs.map → chunk-XRU7V7FF.cjs.map} +1 -1
- package/dist/{chunk-TPF25IG6.js → chunk-XZA3Y4YH.js} +3 -3
- package/dist/{chunk-TPF25IG6.js.map → chunk-XZA3Y4YH.js.map} +1 -1
- package/dist/{chunk-DIQ3AV5W.cjs → chunk-Y6UA55YS.cjs} +324 -224
- package/dist/chunk-Y6UA55YS.cjs.map +1 -0
- package/dist/chunk-Y7M44XEK.js +462 -0
- package/dist/chunk-Y7M44XEK.js.map +1 -0
- package/dist/{chunk-RRSNR3TP.js → chunk-YIRLBUNN.js} +3 -3
- package/dist/{chunk-RRSNR3TP.js.map → chunk-YIRLBUNN.js.map} +1 -1
- package/dist/chunk-YPUNPG2T.js +47 -0
- package/dist/chunk-YPUNPG2T.js.map +1 -0
- package/dist/{chunk-QERAIDRJ.js → chunk-Z2PPIVOO.js} +82 -22
- package/dist/chunk-Z2PPIVOO.js.map +1 -0
- package/dist/chunk-Z5QHVL5U.cjs +12 -0
- package/dist/chunk-Z5QHVL5U.cjs.map +1 -0
- package/dist/chunk-ZDH3DX3C.cjs +30 -0
- package/dist/chunk-ZDH3DX3C.cjs.map +1 -0
- package/dist/chunk-ZE6NVENI.js +77 -0
- package/dist/chunk-ZE6NVENI.js.map +1 -0
- package/dist/chunk-ZKZAIX42.cjs +479 -0
- package/dist/chunk-ZKZAIX42.cjs.map +1 -0
- package/dist/{chunk-TEDRJXOG.cjs → chunk-ZY4GXIVN.cjs} +5 -5
- package/dist/{chunk-TEDRJXOG.cjs.map → chunk-ZY4GXIVN.cjs.map} +1 -1
- package/dist/core/index.cjs +117 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +225 -0
- package/dist/core/index.d.ts +225 -0
- package/dist/core/index.js +12 -0
- package/dist/core/index.js.map +1 -0
- package/dist/{ddl-CS0KUVwB.d.ts → ddl-Dx3Z0_WC.d.ts} +3 -3
- package/dist/{ddl-BD-ZfKeX.d.cts → ddl-J6sDyABg.d.cts} +3 -3
- package/dist/define-graph-CzEvA_8F.d.cts +174 -0
- package/dist/define-graph-DRo9xpYN.d.ts +174 -0
- package/dist/{extension-types-BM2ACfYO.d.cts → extension-types-BLEVH4SG.d.cts} +1 -1
- package/dist/{extension-types-BM2ACfYO.d.ts → extension-types-BLEVH4SG.d.ts} +1 -1
- package/dist/graph-extension/index.cjs +21 -19
- package/dist/graph-extension/index.d.cts +4 -4
- package/dist/graph-extension/index.d.ts +4 -4
- package/dist/graph-extension/index.js +6 -4
- package/dist/graph-merge/index.cjs +267 -218
- package/dist/graph-merge/index.cjs.map +1 -1
- package/dist/graph-merge/index.d.cts +17 -93
- package/dist/graph-merge/index.d.ts +17 -93
- package/dist/graph-merge/index.js +143 -94
- package/dist/graph-merge/index.js.map +1 -1
- package/dist/{index-BeacbPoe.d.ts → index-BD_3TCgh.d.ts} +6 -4
- package/dist/{index-BPM59vsg.d.cts → index-BihFPsPu.d.cts} +6 -4
- package/dist/{fulltext-strategy-C27vXaeB.d.cts → index-Bq7vSPHy.d.ts} +3195 -2646
- package/dist/{fulltext-strategy-DebsMrqg.d.ts → index-CrFL_ENI.d.cts} +3195 -2646
- package/dist/index.cjs +326 -315
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -240
- package/dist/index.d.ts +59 -240
- package/dist/index.js +46 -79
- package/dist/index.js.map +1 -1
- package/dist/indexes/index.cjs +26 -38
- package/dist/indexes/index.d.cts +6 -41
- package/dist/indexes/index.d.ts +6 -41
- package/dist/indexes/index.js +14 -10
- package/dist/interchange/index.cjs +48 -39
- package/dist/interchange/index.cjs.map +1 -1
- package/dist/interchange/index.d.cts +7 -8
- package/dist/interchange/index.d.ts +7 -8
- package/dist/interchange/index.js +23 -14
- package/dist/interchange/index.js.map +1 -1
- package/dist/local-options-CZ1BnIoF.d.cts +29 -0
- package/dist/local-options-CZ1BnIoF.d.ts +29 -0
- package/dist/{manager-D00_NXvT.d.ts → manager-CASfhmzV.d.ts} +4 -173
- package/dist/{manager-nU1vTJLy.d.cts → manager-nCEJiYBb.d.cts} +4 -173
- package/dist/{materialize-indexes-zK2J_flP.d.ts → materialize-indexes-D4iei4Kp.d.ts} +1 -1
- package/dist/{materialize-indexes-CuR3gAZb.d.cts → materialize-indexes-ExQ6OrAh.d.cts} +1 -1
- package/dist/{postgres-IaBA4RgE.d.ts → postgres-Cl1ZAN1G.d.ts} +1 -1
- package/dist/{postgres-YrYmPlaU.d.cts → postgres-DMgIKQU-.d.cts} +1 -1
- package/dist/postgres-execution-fKW0qRiN.d.cts +14 -0
- package/dist/postgres-execution-fKW0qRiN.d.ts +14 -0
- package/dist/profiler/index.cjs +9 -8
- package/dist/profiler/index.cjs.map +1 -1
- package/dist/profiler/index.d.cts +9 -17
- package/dist/profiler/index.d.ts +9 -17
- package/dist/profiler/index.js +8 -7
- package/dist/profiler/index.js.map +1 -1
- package/dist/provenance/index.cjs +61 -55
- package/dist/provenance/index.cjs.map +1 -1
- package/dist/provenance/index.d.cts +7 -8
- package/dist/provenance/index.d.ts +7 -8
- package/dist/provenance/index.js +34 -28
- package/dist/provenance/index.js.map +1 -1
- package/dist/schema/index.cjs +46 -37
- package/dist/schema/index.cjs.map +1 -1
- package/dist/schema/index.d.cts +8 -10
- package/dist/schema/index.d.ts +8 -10
- package/dist/schema/index.js +22 -13
- package/dist/schema/index.js.map +1 -1
- package/dist/{sqlite-BUOHPx7p.d.ts → sqlite-BDkW39aa.d.cts} +1 -1
- package/dist/{sqlite-Pp8O19WE.d.cts → sqlite-CYfhvESj.d.ts} +1 -1
- package/dist/sqlite-execution-DwbE2a9y.d.cts +32 -0
- package/dist/sqlite-execution-DwbE2a9y.d.ts +32 -0
- package/dist/{store-view-X96Rd00T.d.cts → store-view-BJd6Vwpt.d.cts} +427 -1404
- package/dist/{store-view-ANL6mTph.d.ts → store-view-CLIhwMMX.d.ts} +427 -1404
- package/dist/temporal-BC_NQV5Y.d.cts +281 -0
- package/dist/temporal-DqtOEo_B.d.ts +281 -0
- package/dist/{types-r-Zyq2Hz.d.cts → types-COq3-vMC.d.cts} +2 -2
- package/dist/{types-wsvuBgPK.d.ts → types-CUevi_D1.d.ts} +2 -2
- package/dist/{where-CJOpJj3a.d.ts → where-BdE_cYtx.d.ts} +5 -5
- package/dist/{where-K3uBP33l.d.cts → where-C92TXCzT.d.cts} +5 -5
- package/package.json +37 -6
- package/dist/chunk-27SSDCEP.cjs.map +0 -1
- package/dist/chunk-2N6EOBTH.cjs.map +0 -1
- package/dist/chunk-3C2RYI6L.cjs.map +0 -1
- package/dist/chunk-3DS7Z4T4.cjs.map +0 -1
- package/dist/chunk-3GH67G4Z.cjs.map +0 -1
- package/dist/chunk-3RWZPJKV.js.map +0 -1
- package/dist/chunk-3SLPDKHQ.js.map +0 -1
- package/dist/chunk-3XXGYU62.cjs.map +0 -1
- package/dist/chunk-44TA22QT.js +0 -1478
- package/dist/chunk-44TA22QT.js.map +0 -1
- package/dist/chunk-5AVRFNP4.cjs.map +0 -1
- package/dist/chunk-5KEQ74YU.cjs.map +0 -1
- package/dist/chunk-5KPNWT6X.js.map +0 -1
- package/dist/chunk-5PNMDJ7J.js.map +0 -1
- package/dist/chunk-6EEO3OVU.cjs.map +0 -1
- package/dist/chunk-7YSP4V4R.cjs +0 -69
- package/dist/chunk-7YSP4V4R.cjs.map +0 -1
- package/dist/chunk-A42GCBGX.cjs.map +0 -1
- package/dist/chunk-BVRDGYXQ.cjs.map +0 -1
- package/dist/chunk-BYPOGQWK.js.map +0 -1
- package/dist/chunk-CUHM5CWJ.cjs +0 -12
- package/dist/chunk-CUHM5CWJ.cjs.map +0 -1
- package/dist/chunk-DIQ3AV5W.cjs.map +0 -1
- package/dist/chunk-EJYMTO3K.cjs.map +0 -1
- package/dist/chunk-EXU3RASM.js.map +0 -1
- package/dist/chunk-GA4TT3DH.js.map +0 -1
- package/dist/chunk-IP3CGGPA.cjs.map +0 -1
- package/dist/chunk-IPSVVTWT.cjs +0 -1540
- package/dist/chunk-IPSVVTWT.cjs.map +0 -1
- package/dist/chunk-IXGYRP2P.js.map +0 -1
- package/dist/chunk-K3Q3LJY3.js.map +0 -1
- package/dist/chunk-KQJ54OG5.js.map +0 -1
- package/dist/chunk-L7HQ2OSI.js.map +0 -1
- package/dist/chunk-M6VES7V6.js +0 -239
- package/dist/chunk-M6VES7V6.js.map +0 -1
- package/dist/chunk-NUIG3BCV.cjs.map +0 -1
- package/dist/chunk-NXQFATMF.cjs.map +0 -1
- package/dist/chunk-OHMP6N2J.js +0 -47
- package/dist/chunk-OHMP6N2J.js.map +0 -1
- package/dist/chunk-QERAIDRJ.js.map +0 -1
- package/dist/chunk-QSXTWU4U.cjs +0 -12
- package/dist/chunk-RCVLFTCT.js.map +0 -1
- package/dist/chunk-TGOMW4MB.cjs.map +0 -1
- package/dist/chunk-TKT2XHED.js.map +0 -1
- package/dist/chunk-UGZUAYAR.js.map +0 -1
- package/dist/chunk-UV3WP5WZ.js.map +0 -1
- package/dist/chunk-UXLSNRYL.js.map +0 -1
- package/dist/chunk-UYQMBBWJ.js.map +0 -1
- package/dist/chunk-VKGKDOKR.js.map +0 -1
- package/dist/chunk-VL2V6PEN.cjs +0 -261
- package/dist/chunk-VL2V6PEN.cjs.map +0 -1
- package/dist/chunk-WOJMKB3N.cjs.map +0 -1
- package/dist/chunk-WWFHO375.cjs.map +0 -1
- package/dist/chunk-XGPUQ56G.js.map +0 -1
- package/dist/chunk-XGU7DZDA.cjs +0 -1095
- package/dist/chunk-XGU7DZDA.cjs.map +0 -1
- package/dist/chunk-XPCZADMT.cjs.map +0 -1
- package/dist/chunk-XWV4JT34.js.map +0 -1
|
@@ -1,101 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { groupBy, chunk } from './chunk-35S6P5ZU.js';
|
|
2
|
+
import { createBackendOverlay, rowPropsToObject, rowPropsToJsonText } from './chunk-PZHC5GCD.js';
|
|
3
|
+
import { RECORDED_MAX } from './chunk-J6IJARLG.js';
|
|
4
|
+
import { withRecordedRelationsPrecondition } from './chunk-UUIBACKJ.js';
|
|
5
|
+
import { nowIso } from './chunk-I6FX7AAG.js';
|
|
6
|
+
import { MAX_PG_IDENTIFIER_LENGTH } from './chunk-2EBMPJBO.js';
|
|
7
|
+
import { likeEscapeClause, LIKE_ESCAPE_CHARACTER } from './chunk-DDCIXXOO.js';
|
|
8
|
+
import { typeGraphGlobalSymbol, sql, asCompiledRowsSql, isSqlFragment, asCompiledStatementSql } from './chunk-6XDBRDZE.js';
|
|
9
|
+
import { resolveFieldTypeInfoAtJsonPointer } from './chunk-SNXVDZAJ.js';
|
|
10
|
+
import { requireDefined, isPresent } from './chunk-QMQLUA66.js';
|
|
4
11
|
import { resolveEmbeddingFields, getSearchableFields, DEFAULT_SEARCHABLE_LANGUAGE } from './chunk-PC2UBAUB.js';
|
|
5
|
-
import { ConfigurationError,
|
|
6
|
-
import {
|
|
12
|
+
import { ConfigurationError, UnsupportedPredicateError, CompilerInvariantError, CardinalityError, EndpointError, DisjointError, UniquenessError, RestrictedDeleteError } from './chunk-DPNA466P.js';
|
|
13
|
+
import { normalizeJsonPointer, joinJsonPointers, jsonPointer } from './chunk-G6Q5UM7U.js';
|
|
7
14
|
import { nanoid } from 'nanoid';
|
|
8
15
|
|
|
9
|
-
// src/
|
|
10
|
-
var
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
throw new ValidationError(
|
|
15
|
-
`${path} must be before the recorded-time open sentinel ${RECORDED_MAX}.`,
|
|
16
|
-
{
|
|
17
|
-
issues: [
|
|
18
|
-
{
|
|
19
|
-
path,
|
|
20
|
-
message: `Expected a timestamp before ${RECORDED_MAX}, got "${value}"`
|
|
21
|
-
}
|
|
22
|
-
]
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
suggestion: "Use a real recorded-time commit instant, not the open-interval sentinel."
|
|
26
|
-
}
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
function asRecordedInstant(value) {
|
|
31
|
-
assertValidRecordedInstant(value, "asRecordedInstant");
|
|
32
|
-
return value;
|
|
33
|
-
}
|
|
34
|
-
function resolveReadCoordinate(mode, asOf, suggestion) {
|
|
35
|
-
if (mode !== "asOf" && asOf !== void 0) {
|
|
36
|
-
throw new ValidationError(
|
|
37
|
-
`Temporal mode "${mode}" does not take an asOf timestamp.`,
|
|
38
|
-
{
|
|
39
|
-
issues: [
|
|
40
|
-
{
|
|
41
|
-
path: "asOf",
|
|
42
|
-
message: `asOf is only valid with mode "asOf", not "${mode}"`
|
|
43
|
-
}
|
|
44
|
-
]
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
suggestion: 'Pin an instant with store.asOf(timestamp) or store.view({ mode: "asOf", asOf }); drop asOf for other modes.'
|
|
48
|
-
}
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
assertValidAsOf(
|
|
52
|
-
mode,
|
|
53
|
-
asOf,
|
|
54
|
-
suggestion === void 0 ? void 0 : { suggestion }
|
|
55
|
-
);
|
|
56
|
-
return { valid: asOf === void 0 ? { mode } : { mode, asOf } };
|
|
57
|
-
}
|
|
58
|
-
function withRecordedCoordinate(coordinate, recordedAsOf) {
|
|
59
|
-
assertValidRecordedInstant(recordedAsOf, "asOfRecorded");
|
|
60
|
-
return {
|
|
61
|
-
...coordinate,
|
|
62
|
-
recorded: { asOf: recordedAsOf }
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
function assertValidAsOf(mode, asOf, options) {
|
|
66
|
-
if (mode === "asOf" && asOf === void 0) {
|
|
67
|
-
throw new ValidationError(
|
|
68
|
-
'Temporal mode "asOf" requires a timestamp',
|
|
69
|
-
{
|
|
70
|
-
issues: [
|
|
71
|
-
{ path: "asOf", message: "Timestamp is required for asOf mode" }
|
|
72
|
-
]
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
suggestion: options?.suggestion ?? 'Provide an ISO-8601 timestamp for asOf mode, e.g. "2026-01-01T00:00:00.000Z".'
|
|
76
|
-
}
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
if (asOf !== void 0) {
|
|
80
|
-
validateCanonicalIsoDate(asOf, "asOf");
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
function describeCoordinate(coordinate) {
|
|
84
|
-
const { mode, asOf } = coordinate.valid;
|
|
85
|
-
const valid = asOf === void 0 ? `mode "${mode}"` : `mode "${mode}" asOf ${asOf}`;
|
|
86
|
-
return coordinate.recorded === void 0 ? valid : `${valid}, recorded asOf ${coordinate.recorded.asOf}`;
|
|
87
|
-
}
|
|
88
|
-
function coordinateContext(coordinate) {
|
|
89
|
-
const { mode, asOf } = coordinate.valid;
|
|
90
|
-
return {
|
|
91
|
-
temporalMode: mode,
|
|
92
|
-
...asOf !== void 0 && { asOf },
|
|
93
|
-
...coordinate.recorded === void 0 ? {} : { recordedAsOf: coordinate.recorded.asOf }
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
var SqlSchemaDescriptor = class {
|
|
97
|
-
// Private field gives SqlSchema nominal identity; runtime checks use instanceof.
|
|
98
|
-
#brand = true;
|
|
16
|
+
// src/query/compiler/schema.ts
|
|
17
|
+
var SQL_SCHEMA_BRAND = typeGraphGlobalSymbol("sql-schema-v1");
|
|
18
|
+
var SqlSchema = class {
|
|
19
|
+
};
|
|
20
|
+
var SqlSchemaDescriptor = class extends SqlSchema {
|
|
99
21
|
tables;
|
|
100
22
|
nodesTable;
|
|
101
23
|
edgesTable;
|
|
@@ -105,6 +27,13 @@ var SqlSchemaDescriptor = class {
|
|
|
105
27
|
revisionOriginsTable;
|
|
106
28
|
fulltextTable;
|
|
107
29
|
constructor(fields) {
|
|
30
|
+
super();
|
|
31
|
+
Object.defineProperty(this, SQL_SCHEMA_BRAND, {
|
|
32
|
+
configurable: false,
|
|
33
|
+
enumerable: false,
|
|
34
|
+
value: true,
|
|
35
|
+
writable: false
|
|
36
|
+
});
|
|
108
37
|
this.tables = fields.tables;
|
|
109
38
|
this.nodesTable = fields.nodesTable;
|
|
110
39
|
this.edgesTable = fields.edgesTable;
|
|
@@ -113,7 +42,6 @@ var SqlSchemaDescriptor = class {
|
|
|
113
42
|
this.recordedClockTable = fields.recordedClockTable;
|
|
114
43
|
this.revisionOriginsTable = fields.revisionOriginsTable;
|
|
115
44
|
this.fulltextTable = fields.fulltextTable;
|
|
116
|
-
void this.#brand;
|
|
117
45
|
Object.freeze(this);
|
|
118
46
|
}
|
|
119
47
|
};
|
|
@@ -155,14 +83,13 @@ function validateTableName(name, label) {
|
|
|
155
83
|
);
|
|
156
84
|
}
|
|
157
85
|
}
|
|
158
|
-
function quoteIdentifier(name) {
|
|
159
|
-
return `"${name.replaceAll('"', '""')}"`;
|
|
160
|
-
}
|
|
161
86
|
function freezeSqlSchema(fields) {
|
|
162
87
|
return new SqlSchemaDescriptor(fields);
|
|
163
88
|
}
|
|
164
89
|
function isSqlSchema(schema) {
|
|
165
|
-
|
|
90
|
+
if (typeof schema !== "object" || schema === null) return false;
|
|
91
|
+
const candidate = schema;
|
|
92
|
+
return candidate[SQL_SCHEMA_BRAND] === true && typeof candidate["tables"] === "object" && candidate["tables"] !== null && Object.isFrozen(candidate["tables"]) && isSqlFragment(candidate["nodesTable"]) && isSqlFragment(candidate["edgesTable"]) && isSqlFragment(candidate["recordedNodesTable"]) && isSqlFragment(candidate["recordedEdgesTable"]) && isSqlFragment(candidate["recordedClockTable"]) && isSqlFragment(candidate["revisionOriginsTable"]) && isSqlFragment(candidate["fulltextTable"]) && Object.isFrozen(candidate);
|
|
166
93
|
}
|
|
167
94
|
function requireSqlSchema(schema, surface = "SqlSchema") {
|
|
168
95
|
if (isSqlSchema(schema)) return schema;
|
|
@@ -186,20 +113,20 @@ function createSqlSchema(names = {}) {
|
|
|
186
113
|
validateTableName(tables.uniques, "uniques");
|
|
187
114
|
return freezeSqlSchema({
|
|
188
115
|
tables: Object.freeze(tables),
|
|
189
|
-
nodesTable: sql.
|
|
190
|
-
edgesTable: sql.
|
|
191
|
-
recordedNodesTable: sql.
|
|
192
|
-
recordedEdgesTable: sql.
|
|
193
|
-
recordedClockTable: sql.
|
|
194
|
-
revisionOriginsTable: sql.
|
|
195
|
-
fulltextTable: sql.
|
|
116
|
+
nodesTable: sql.identifier(tables.nodes),
|
|
117
|
+
edgesTable: sql.identifier(tables.edges),
|
|
118
|
+
recordedNodesTable: sql.identifier(tables.recordedNodes),
|
|
119
|
+
recordedEdgesTable: sql.identifier(tables.recordedEdges),
|
|
120
|
+
recordedClockTable: sql.identifier(tables.recordedClock),
|
|
121
|
+
revisionOriginsTable: sql.identifier(tables.revisionOrigins),
|
|
122
|
+
fulltextTable: sql.identifier(tables.fulltext)
|
|
196
123
|
});
|
|
197
124
|
}
|
|
198
|
-
var EXTERNAL_RECORDED_READ_SOURCE =
|
|
199
|
-
"
|
|
125
|
+
var EXTERNAL_RECORDED_READ_SOURCE = typeGraphGlobalSymbol(
|
|
126
|
+
"external-recorded-read-source-v1"
|
|
200
127
|
);
|
|
201
|
-
var TYPEGRAPH_RECORDED_READ_SOURCE =
|
|
202
|
-
"
|
|
128
|
+
var TYPEGRAPH_RECORDED_READ_SOURCE = typeGraphGlobalSymbol(
|
|
129
|
+
"typegraph-recorded-read-source-v1"
|
|
203
130
|
);
|
|
204
131
|
function recordedRelation(options) {
|
|
205
132
|
const schema = requireSqlSchema(options.schema, "recordedRelation schema");
|
|
@@ -289,9 +216,663 @@ var ALIAS_CTE_PREFIX = "cte_";
|
|
|
289
216
|
var EMBEDDINGS_CTE_ALIAS = "cte_embeddings";
|
|
290
217
|
var FULLTEXT_CTE_ALIAS = "cte_fulltext";
|
|
291
218
|
var HYBRID_CANDIDATES_CTE_ALIAS = "cte_relevance_candidates";
|
|
219
|
+
|
|
220
|
+
// src/store/types.ts
|
|
221
|
+
var AUTO_REFRESH_STATISTICS_ROW_THRESHOLD = 1e3;
|
|
222
|
+
var TRANSACTION_RUNTIME = typeGraphGlobalSymbol(
|
|
223
|
+
"transaction-runtime-v1"
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
// src/store/runtime-port.ts
|
|
227
|
+
var STORE_RUNTIME = typeGraphGlobalSymbol("store-runtime-v1");
|
|
228
|
+
function storeRuntime(store) {
|
|
229
|
+
const runtime = store[STORE_RUNTIME];
|
|
230
|
+
if (runtime === void 0) {
|
|
231
|
+
throw new TypeError(
|
|
232
|
+
"Cannot access this Store's runtime port. The Store may come from an incompatible TypeGraph version."
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
return runtime;
|
|
236
|
+
}
|
|
237
|
+
function storeBackend(store) {
|
|
238
|
+
return storeRuntime(store).backend;
|
|
239
|
+
}
|
|
240
|
+
function transactionBackend(transaction) {
|
|
241
|
+
const runtime = transaction[TRANSACTION_RUNTIME];
|
|
242
|
+
if (runtime === void 0) {
|
|
243
|
+
throw new TypeError(
|
|
244
|
+
"Cannot access this transaction's runtime port. The transaction may come from an incompatible TypeGraph version."
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
return runtime.backend;
|
|
248
|
+
}
|
|
249
|
+
function transactionNodeOperationHookRunner(transaction) {
|
|
250
|
+
const runtime = transaction[TRANSACTION_RUNTIME];
|
|
251
|
+
if (runtime === void 0) {
|
|
252
|
+
throw new TypeError(
|
|
253
|
+
"Cannot access this transaction's runtime port. The transaction may come from an incompatible TypeGraph version."
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
return runtime.runNodeOperationHooks;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// src/query/compiler/temporal.ts
|
|
260
|
+
var pinnedReadInstant;
|
|
261
|
+
function withPinnedReadInstant(emit) {
|
|
262
|
+
if (pinnedReadInstant !== void 0) return emit();
|
|
263
|
+
pinnedReadInstant = nowIso();
|
|
264
|
+
try {
|
|
265
|
+
return emit();
|
|
266
|
+
} finally {
|
|
267
|
+
pinnedReadInstant = void 0;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
function currentReadInstant() {
|
|
271
|
+
return sql`${pinnedReadInstant ?? nowIso()}`;
|
|
272
|
+
}
|
|
273
|
+
var CURRENT_READ_INSTANT_PLACEHOLDER = "__typegraph_current_read_instant__";
|
|
274
|
+
function currentReadInstantPlaceholder() {
|
|
275
|
+
return sql`${sql.placeholder(CURRENT_READ_INSTANT_PLACEHOLDER)}`;
|
|
276
|
+
}
|
|
277
|
+
function currentReadInstantFor(mode) {
|
|
278
|
+
return mode === "placeholder" ? currentReadInstantPlaceholder() : currentReadInstant();
|
|
279
|
+
}
|
|
280
|
+
function compileTemporalFilter(options) {
|
|
281
|
+
const { mode, asOf, tableAlias, currentTimestamp, recordedAsOf } = options;
|
|
282
|
+
const prefix = tableAlias ? sql.raw(`${tableAlias}.`) : sql.raw("");
|
|
283
|
+
const deletedAt = sql`${prefix}deleted_at`;
|
|
284
|
+
const validFrom = sql`${prefix}valid_from`;
|
|
285
|
+
const validTo = sql`${prefix}valid_to`;
|
|
286
|
+
const validFilter = (() => {
|
|
287
|
+
switch (mode) {
|
|
288
|
+
case "current": {
|
|
289
|
+
const now = recordedAsOf === void 0 ? currentTimestamp ?? currentReadInstant() : sql`${recordedAsOf}`;
|
|
290
|
+
return sql`${deletedAt} IS NULL AND (${validFrom} IS NULL OR ${validFrom} <= ${now}) AND (${validTo} IS NULL OR ${validTo} > ${now})`;
|
|
291
|
+
}
|
|
292
|
+
case "asOf": {
|
|
293
|
+
if (asOf === void 0) {
|
|
294
|
+
throw new Error(
|
|
295
|
+
`asOf timestamp is required for temporal mode "asOf"`
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
const timestamp = asOf;
|
|
299
|
+
return sql`${deletedAt} IS NULL AND (${validFrom} IS NULL OR ${validFrom} <= ${timestamp}) AND (${validTo} IS NULL OR ${validTo} > ${timestamp})`;
|
|
300
|
+
}
|
|
301
|
+
case "includeEnded": {
|
|
302
|
+
return sql`${deletedAt} IS NULL`;
|
|
303
|
+
}
|
|
304
|
+
case "includeTombstones": {
|
|
305
|
+
return sql.raw("1=1");
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
})();
|
|
309
|
+
if (recordedAsOf === void 0) return validFilter;
|
|
310
|
+
const recordedFrom = sql`${prefix}recorded_from`;
|
|
311
|
+
const recordedTo = sql`${prefix}recorded_to`;
|
|
312
|
+
return sql`(${validFilter}) AND ${recordedFrom} <= ${recordedAsOf} AND ${recordedAsOf} < ${recordedTo}`;
|
|
313
|
+
}
|
|
314
|
+
function extractTemporalOptions(ast, tableAlias) {
|
|
315
|
+
return {
|
|
316
|
+
mode: ast.temporalMode.mode,
|
|
317
|
+
asOf: ast.temporalMode.asOf,
|
|
318
|
+
recordedAsOf: ast.recordedAsOf,
|
|
319
|
+
tableAlias
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// src/query/subquery-utils.ts
|
|
324
|
+
function normalizeValueType(valueType) {
|
|
325
|
+
if (valueType === void 0 || valueType === "unknown") {
|
|
326
|
+
return void 0;
|
|
327
|
+
}
|
|
328
|
+
return valueType;
|
|
329
|
+
}
|
|
330
|
+
function isUnsupportedInSubqueryValueType(valueType) {
|
|
331
|
+
const normalized = normalizeValueType(valueType);
|
|
332
|
+
return normalized === "array" || normalized === "object" || normalized === "embedding";
|
|
333
|
+
}
|
|
334
|
+
function isInSubqueryTypeCompatible(left, right) {
|
|
335
|
+
const normalizedLeft = normalizeValueType(left);
|
|
336
|
+
const normalizedRight = normalizeValueType(right);
|
|
337
|
+
if (normalizedLeft === void 0 || normalizedRight === void 0) {
|
|
338
|
+
return true;
|
|
339
|
+
}
|
|
340
|
+
return normalizedLeft === normalizedRight;
|
|
341
|
+
}
|
|
342
|
+
function getAggregateValueType(aggregate) {
|
|
343
|
+
switch (aggregate.function) {
|
|
344
|
+
case "count":
|
|
345
|
+
case "countDistinct":
|
|
346
|
+
case "sum":
|
|
347
|
+
case "avg": {
|
|
348
|
+
return "number";
|
|
349
|
+
}
|
|
350
|
+
case "min":
|
|
351
|
+
case "max": {
|
|
352
|
+
return normalizeValueType(aggregate.field.valueType);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
function getProjectedValueTypes(subquery) {
|
|
357
|
+
if (subquery.selectiveFields && subquery.selectiveFields.length > 0) {
|
|
358
|
+
return subquery.selectiveFields.map(
|
|
359
|
+
(field) => normalizeValueType(field.valueType)
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
return subquery.projection.fields.map((field) => {
|
|
363
|
+
if (field.source.__type === "aggregate") {
|
|
364
|
+
return getAggregateValueType(field.source);
|
|
365
|
+
}
|
|
366
|
+
return normalizeValueType(field.source.valueType);
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
function getSubqueryColumnCount(subquery) {
|
|
370
|
+
return getProjectedValueTypes(subquery).length;
|
|
371
|
+
}
|
|
372
|
+
function getSingleSubqueryColumnValueType(subquery) {
|
|
373
|
+
const valueTypes = getProjectedValueTypes(subquery);
|
|
374
|
+
if (valueTypes.length !== 1) {
|
|
375
|
+
return void 0;
|
|
376
|
+
}
|
|
377
|
+
return valueTypes[0];
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// src/query/predicates.ts
|
|
381
|
+
function predicate(expr) {
|
|
382
|
+
return {
|
|
383
|
+
__expr: expr,
|
|
384
|
+
and: (other) => predicate({
|
|
385
|
+
__type: "and",
|
|
386
|
+
predicates: [expr, other.__expr]
|
|
387
|
+
}),
|
|
388
|
+
or: (other) => predicate({
|
|
389
|
+
__type: "or",
|
|
390
|
+
predicates: [expr, other.__expr]
|
|
391
|
+
}),
|
|
392
|
+
not: () => predicate({
|
|
393
|
+
__type: "not",
|
|
394
|
+
predicate: expr
|
|
395
|
+
})
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
function param(name) {
|
|
399
|
+
if (name === CURRENT_READ_INSTANT_PLACEHOLDER) {
|
|
400
|
+
throw new ConfigurationError(
|
|
401
|
+
`Parameter name "${name}" is reserved for internal use`,
|
|
402
|
+
{ parameterName: name }
|
|
403
|
+
);
|
|
404
|
+
}
|
|
405
|
+
return { __type: "parameter", name };
|
|
406
|
+
}
|
|
407
|
+
function isParameterRef(value) {
|
|
408
|
+
if (typeof value !== "object" || value === null) return false;
|
|
409
|
+
return value.__type === "parameter";
|
|
410
|
+
}
|
|
411
|
+
function fieldRef(alias, path, options) {
|
|
412
|
+
return {
|
|
413
|
+
__type: "field_ref",
|
|
414
|
+
alias,
|
|
415
|
+
path,
|
|
416
|
+
...options?.jsonPointer !== void 0 && {
|
|
417
|
+
jsonPointer: options.jsonPointer
|
|
418
|
+
},
|
|
419
|
+
...options?.valueType !== void 0 && { valueType: options.valueType },
|
|
420
|
+
...options?.elementType !== void 0 && {
|
|
421
|
+
elementType: options.elementType
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
function coerceLiteralValue(value) {
|
|
426
|
+
if (value instanceof Date) {
|
|
427
|
+
return value;
|
|
428
|
+
}
|
|
429
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
430
|
+
return value;
|
|
431
|
+
}
|
|
432
|
+
throw new Error(`Unsupported literal value type: ${typeof value}`);
|
|
433
|
+
}
|
|
434
|
+
function inferLiteralValueType(value) {
|
|
435
|
+
if (typeof value === "string") {
|
|
436
|
+
return "string";
|
|
437
|
+
}
|
|
438
|
+
if (typeof value === "number") {
|
|
439
|
+
return "number";
|
|
440
|
+
}
|
|
441
|
+
return "boolean";
|
|
442
|
+
}
|
|
443
|
+
function literal(value) {
|
|
444
|
+
if (value instanceof Date) {
|
|
445
|
+
return { __type: "literal", value: value.toISOString(), valueType: "date" };
|
|
446
|
+
}
|
|
447
|
+
const valueType = inferLiteralValueType(value);
|
|
448
|
+
return {
|
|
449
|
+
__type: "literal",
|
|
450
|
+
value,
|
|
451
|
+
valueType
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
function comparison(op, field, value) {
|
|
455
|
+
if (isParameterRef(value)) {
|
|
456
|
+
const expr2 = {
|
|
457
|
+
__type: "comparison",
|
|
458
|
+
op,
|
|
459
|
+
left: field,
|
|
460
|
+
right: value
|
|
461
|
+
};
|
|
462
|
+
return predicate(expr2);
|
|
463
|
+
}
|
|
464
|
+
const coercedValue = coerceLiteralValue(value);
|
|
465
|
+
const expr = {
|
|
466
|
+
__type: "comparison",
|
|
467
|
+
op,
|
|
468
|
+
left: field,
|
|
469
|
+
right: literal(coercedValue)
|
|
470
|
+
};
|
|
471
|
+
return predicate(expr);
|
|
472
|
+
}
|
|
473
|
+
function inComparison(op, field, values) {
|
|
474
|
+
const literals = values.map((value) => literal(coerceLiteralValue(value)));
|
|
475
|
+
const expr = {
|
|
476
|
+
__type: "comparison",
|
|
477
|
+
op,
|
|
478
|
+
left: field,
|
|
479
|
+
right: literals
|
|
480
|
+
};
|
|
481
|
+
return predicate(expr);
|
|
482
|
+
}
|
|
483
|
+
function stringOp(op, field, pattern) {
|
|
484
|
+
if (isParameterRef(pattern)) {
|
|
485
|
+
const expr2 = {
|
|
486
|
+
__type: "string_op",
|
|
487
|
+
op,
|
|
488
|
+
field,
|
|
489
|
+
pattern
|
|
490
|
+
};
|
|
491
|
+
return predicate(expr2);
|
|
492
|
+
}
|
|
493
|
+
const expr = {
|
|
494
|
+
__type: "string_op",
|
|
495
|
+
op,
|
|
496
|
+
field,
|
|
497
|
+
pattern
|
|
498
|
+
};
|
|
499
|
+
return predicate(expr);
|
|
500
|
+
}
|
|
501
|
+
function nullCheck(op, field) {
|
|
502
|
+
const expr = {
|
|
503
|
+
__type: "null_check",
|
|
504
|
+
op,
|
|
505
|
+
field
|
|
506
|
+
};
|
|
507
|
+
return predicate(expr);
|
|
508
|
+
}
|
|
509
|
+
function between(field, lower, upper) {
|
|
510
|
+
const expr = {
|
|
511
|
+
__type: "between",
|
|
512
|
+
field,
|
|
513
|
+
lower: isParameterRef(lower) ? lower : literal(lower),
|
|
514
|
+
upper: isParameterRef(upper) ? upper : literal(upper)
|
|
515
|
+
};
|
|
516
|
+
return predicate(expr);
|
|
517
|
+
}
|
|
518
|
+
function baseFieldBuilder(field) {
|
|
519
|
+
return {
|
|
520
|
+
eq: (value) => comparison("eq", field, value),
|
|
521
|
+
neq: (value) => comparison("neq", field, value),
|
|
522
|
+
isNull: () => nullCheck("isNull", field),
|
|
523
|
+
isNotNull: () => nullCheck("isNotNull", field),
|
|
524
|
+
in: (values) => inComparison("in", field, values),
|
|
525
|
+
notIn: (values) => inComparison("notIn", field, values)
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
function stringField(field) {
|
|
529
|
+
return {
|
|
530
|
+
...baseFieldBuilder(field),
|
|
531
|
+
gt: (value) => comparison("gt", field, value),
|
|
532
|
+
gte: (value) => comparison("gte", field, value),
|
|
533
|
+
lt: (value) => comparison("lt", field, value),
|
|
534
|
+
lte: (value) => comparison("lte", field, value),
|
|
535
|
+
contains: (pattern) => stringOp("contains", field, pattern),
|
|
536
|
+
startsWith: (pattern) => stringOp("startsWith", field, pattern),
|
|
537
|
+
endsWith: (pattern) => stringOp("endsWith", field, pattern),
|
|
538
|
+
like: (pattern) => stringOp("like", field, pattern),
|
|
539
|
+
ilike: (pattern) => stringOp("ilike", field, pattern)
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
var DEFAULT_FULLTEXT_MATCH_K = 50;
|
|
543
|
+
function createFulltextAccessor(alias, hasSearchableField) {
|
|
544
|
+
return {
|
|
545
|
+
matches: (query, k, options) => {
|
|
546
|
+
if (!hasSearchableField()) {
|
|
547
|
+
throw new UnsupportedPredicateError(
|
|
548
|
+
`Cannot call .$fulltext.matches() on alias "${alias}" \u2014 its node kind has no fields declared with searchable(). Add at least one: \`title: searchable({ language: "english" })\`.`
|
|
549
|
+
);
|
|
550
|
+
}
|
|
551
|
+
return fulltextMatch(
|
|
552
|
+
fieldRef(alias, ["$fulltext"]),
|
|
553
|
+
query,
|
|
554
|
+
k ?? DEFAULT_FULLTEXT_MATCH_K,
|
|
555
|
+
options
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
function fulltextMatch(field, query, limit, options) {
|
|
561
|
+
if (!Number.isFinite(limit) || limit <= 0) {
|
|
562
|
+
throw new UnsupportedPredicateError(
|
|
563
|
+
`matches() limit must be a positive finite number, got ${String(limit)}`
|
|
564
|
+
);
|
|
565
|
+
}
|
|
566
|
+
const expr = {
|
|
567
|
+
__type: "fulltext_match",
|
|
568
|
+
field,
|
|
569
|
+
query,
|
|
570
|
+
mode: options?.mode ?? "websearch",
|
|
571
|
+
limit,
|
|
572
|
+
...options?.language === void 0 ? {} : { language: options.language },
|
|
573
|
+
...options?.minScore === void 0 ? {} : { minScore: options.minScore }
|
|
574
|
+
};
|
|
575
|
+
return predicate(expr);
|
|
576
|
+
}
|
|
577
|
+
function numberField(field) {
|
|
578
|
+
return {
|
|
579
|
+
...baseFieldBuilder(field),
|
|
580
|
+
gt: (value) => comparison("gt", field, value),
|
|
581
|
+
gte: (value) => comparison("gte", field, value),
|
|
582
|
+
lt: (value) => comparison("lt", field, value),
|
|
583
|
+
lte: (value) => comparison("lte", field, value),
|
|
584
|
+
between: (lower, upper) => between(field, lower, upper)
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
function dateField(field) {
|
|
588
|
+
return {
|
|
589
|
+
...baseFieldBuilder(field),
|
|
590
|
+
gt: (value) => comparison("gt", field, value),
|
|
591
|
+
gte: (value) => comparison("gte", field, value),
|
|
592
|
+
lt: (value) => comparison("lt", field, value),
|
|
593
|
+
lte: (value) => comparison("lte", field, value),
|
|
594
|
+
between: (lower, upper) => between(field, lower, upper)
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
function baseField(field) {
|
|
598
|
+
return baseFieldBuilder(field);
|
|
599
|
+
}
|
|
600
|
+
function arrayOp(op, field, values, length) {
|
|
601
|
+
const expr = {
|
|
602
|
+
__type: "array_op",
|
|
603
|
+
op,
|
|
604
|
+
field,
|
|
605
|
+
...values !== void 0 && {
|
|
606
|
+
values: values.map((value) => literal(coerceLiteralValue(value)))
|
|
607
|
+
},
|
|
608
|
+
...length !== void 0 && { length }
|
|
609
|
+
};
|
|
610
|
+
return predicate(expr);
|
|
611
|
+
}
|
|
612
|
+
function arrayField(field) {
|
|
613
|
+
return {
|
|
614
|
+
...baseFieldBuilder(field),
|
|
615
|
+
contains: (value) => arrayOp("contains", field, [value]),
|
|
616
|
+
containsAll: (values) => arrayOp("containsAll", field, values),
|
|
617
|
+
containsAny: (values) => arrayOp("containsAny", field, values),
|
|
618
|
+
isEmpty: () => arrayOp("isEmpty", field),
|
|
619
|
+
isNotEmpty: () => arrayOp("isNotEmpty", field),
|
|
620
|
+
lengthEq: (length) => arrayOp("lengthEq", field, void 0, length),
|
|
621
|
+
lengthGt: (length) => arrayOp("lengthGt", field, void 0, length),
|
|
622
|
+
lengthGte: (length) => arrayOp("lengthGte", field, void 0, length),
|
|
623
|
+
lengthLt: (length) => arrayOp("lengthLt", field, void 0, length),
|
|
624
|
+
lengthLte: (length) => arrayOp("lengthLte", field, void 0, length)
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
function vectorSimilarity(field, queryEmbedding, limit, options) {
|
|
628
|
+
const expr = {
|
|
629
|
+
__type: "vector_similarity",
|
|
630
|
+
field,
|
|
631
|
+
queryEmbedding,
|
|
632
|
+
// Leave metric unset when the caller didn't specify one, so the compiler
|
|
633
|
+
// resolves the field's declared metric per kind. Defaulting to "cosine"
|
|
634
|
+
// here would mis-rank l2/inner_product fields and bypass their ANN index.
|
|
635
|
+
...options?.metric !== void 0 && { metric: options.metric },
|
|
636
|
+
limit,
|
|
637
|
+
...options?.minScore !== void 0 && { minScore: options.minScore },
|
|
638
|
+
...options?.approximate !== void 0 && {
|
|
639
|
+
approximate: options.approximate
|
|
640
|
+
}
|
|
641
|
+
};
|
|
642
|
+
return predicate(expr);
|
|
643
|
+
}
|
|
644
|
+
function embeddingField(field) {
|
|
645
|
+
return {
|
|
646
|
+
...baseFieldBuilder(field),
|
|
647
|
+
similarTo: (queryEmbedding, k, options) => vectorSimilarity(field, queryEmbedding, k, options)
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
function buildFieldBuilderForTypeInfo(field, typeInfo) {
|
|
651
|
+
if (!typeInfo) {
|
|
652
|
+
return baseField(field);
|
|
653
|
+
}
|
|
654
|
+
switch (typeInfo.valueType) {
|
|
655
|
+
case "string": {
|
|
656
|
+
return stringField(field);
|
|
657
|
+
}
|
|
658
|
+
case "number": {
|
|
659
|
+
return numberField(field);
|
|
660
|
+
}
|
|
661
|
+
case "boolean": {
|
|
662
|
+
return baseField(field);
|
|
663
|
+
}
|
|
664
|
+
case "date": {
|
|
665
|
+
return dateField(field);
|
|
666
|
+
}
|
|
667
|
+
case "array": {
|
|
668
|
+
return arrayField(field);
|
|
669
|
+
}
|
|
670
|
+
case "object": {
|
|
671
|
+
return objectField(field, { typeInfo });
|
|
672
|
+
}
|
|
673
|
+
case "embedding": {
|
|
674
|
+
return embeddingField(field);
|
|
675
|
+
}
|
|
676
|
+
case "unknown": {
|
|
677
|
+
return baseField(field);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
function resolvePointerTypeInfo(typeInfo, pointer) {
|
|
682
|
+
return resolveFieldTypeInfoAtJsonPointer(typeInfo, pointer);
|
|
683
|
+
}
|
|
684
|
+
function objectOp(op, field, pointer, value, options) {
|
|
685
|
+
const expr = {
|
|
686
|
+
__type: "object_op",
|
|
687
|
+
op,
|
|
688
|
+
field,
|
|
689
|
+
pointer,
|
|
690
|
+
...value !== void 0 && {
|
|
691
|
+
value: literal(coerceLiteralValue(value))
|
|
692
|
+
},
|
|
693
|
+
...options?.valueType !== void 0 && { valueType: options.valueType },
|
|
694
|
+
...options?.elementType !== void 0 && {
|
|
695
|
+
elementType: options.elementType
|
|
696
|
+
}
|
|
697
|
+
};
|
|
698
|
+
return predicate(expr);
|
|
699
|
+
}
|
|
700
|
+
function objectField(field, options) {
|
|
701
|
+
const basePointer = field.jsonPointer;
|
|
702
|
+
return {
|
|
703
|
+
...baseFieldBuilder(field),
|
|
704
|
+
get: (key) => {
|
|
705
|
+
const pointer = jsonPointer([key]);
|
|
706
|
+
const nestedPointer = joinJsonPointers(basePointer, pointer);
|
|
707
|
+
const resolved = resolvePointerTypeInfo(options?.typeInfo, pointer);
|
|
708
|
+
const nestedRef = fieldRef(field.alias, field.path, {
|
|
709
|
+
jsonPointer: nestedPointer,
|
|
710
|
+
...resolved?.valueType !== void 0 && {
|
|
711
|
+
valueType: resolved.valueType
|
|
712
|
+
},
|
|
713
|
+
...resolved?.elementType !== void 0 && {
|
|
714
|
+
elementType: resolved.elementType
|
|
715
|
+
}
|
|
716
|
+
});
|
|
717
|
+
return buildFieldBuilderForTypeInfo(nestedRef, resolved);
|
|
718
|
+
},
|
|
719
|
+
hasKey: (key) => {
|
|
720
|
+
const pointer = jsonPointer([key]);
|
|
721
|
+
resolvePointerTypeInfo(options?.typeInfo, pointer);
|
|
722
|
+
return objectOp("hasKey", field, pointer);
|
|
723
|
+
},
|
|
724
|
+
hasPath: (pointer) => {
|
|
725
|
+
const normalized = normalizeJsonPointer(pointer);
|
|
726
|
+
resolvePointerTypeInfo(options?.typeInfo, normalized);
|
|
727
|
+
return objectOp("hasPath", field, normalized);
|
|
728
|
+
},
|
|
729
|
+
pathEquals: (pointer, value) => {
|
|
730
|
+
const normalized = normalizeJsonPointer(pointer);
|
|
731
|
+
const resolved = resolvePointerTypeInfo(options?.typeInfo, normalized);
|
|
732
|
+
if (resolved && (resolved.valueType === "array" || resolved.valueType === "object")) {
|
|
733
|
+
throw new Error("pathEquals is only supported for scalar JSON values");
|
|
734
|
+
}
|
|
735
|
+
const predicateOptions = resolved?.valueType === void 0 ? void 0 : { valueType: resolved.valueType };
|
|
736
|
+
return objectOp("pathEquals", field, normalized, value, predicateOptions);
|
|
737
|
+
},
|
|
738
|
+
pathContains: (pointer, value) => {
|
|
739
|
+
const normalized = normalizeJsonPointer(pointer);
|
|
740
|
+
const resolved = resolvePointerTypeInfo(options?.typeInfo, normalized);
|
|
741
|
+
if (resolved && resolved.valueType !== "array") {
|
|
742
|
+
throw new Error("pathContains is only supported for JSON array values");
|
|
743
|
+
}
|
|
744
|
+
const predicateOptions = resolved?.elementType === void 0 ? void 0 : { elementType: resolved.elementType };
|
|
745
|
+
return objectOp(
|
|
746
|
+
"pathContains",
|
|
747
|
+
field,
|
|
748
|
+
normalized,
|
|
749
|
+
value,
|
|
750
|
+
predicateOptions
|
|
751
|
+
);
|
|
752
|
+
},
|
|
753
|
+
pathIsNull: (pointer) => {
|
|
754
|
+
const normalized = normalizeJsonPointer(pointer);
|
|
755
|
+
const resolved = resolvePointerTypeInfo(options?.typeInfo, normalized);
|
|
756
|
+
const predicateOptions = resolved?.valueType === void 0 ? void 0 : { valueType: resolved.valueType };
|
|
757
|
+
return objectOp(
|
|
758
|
+
"pathIsNull",
|
|
759
|
+
field,
|
|
760
|
+
normalized,
|
|
761
|
+
void 0,
|
|
762
|
+
predicateOptions
|
|
763
|
+
);
|
|
764
|
+
},
|
|
765
|
+
pathIsNotNull: (pointer) => {
|
|
766
|
+
const normalized = normalizeJsonPointer(pointer);
|
|
767
|
+
const resolved = resolvePointerTypeInfo(options?.typeInfo, normalized);
|
|
768
|
+
const predicateOptions = resolved?.valueType === void 0 ? void 0 : { valueType: resolved.valueType };
|
|
769
|
+
return objectOp(
|
|
770
|
+
"pathIsNotNull",
|
|
771
|
+
field,
|
|
772
|
+
normalized,
|
|
773
|
+
void 0,
|
|
774
|
+
predicateOptions
|
|
775
|
+
);
|
|
776
|
+
},
|
|
777
|
+
field: (pointer) => {
|
|
778
|
+
const normalized = normalizeJsonPointer(pointer);
|
|
779
|
+
const nestedPointer = joinJsonPointers(basePointer, normalized);
|
|
780
|
+
const resolved = resolvePointerTypeInfo(options?.typeInfo, normalized);
|
|
781
|
+
const nestedRef = fieldRef(field.alias, field.path, {
|
|
782
|
+
jsonPointer: nestedPointer,
|
|
783
|
+
...resolved?.valueType !== void 0 && {
|
|
784
|
+
valueType: resolved.valueType
|
|
785
|
+
},
|
|
786
|
+
...resolved?.elementType !== void 0 && {
|
|
787
|
+
elementType: resolved.elementType
|
|
788
|
+
}
|
|
789
|
+
});
|
|
790
|
+
return buildFieldBuilderForTypeInfo(nestedRef, resolved);
|
|
791
|
+
}
|
|
792
|
+
};
|
|
793
|
+
}
|
|
794
|
+
function exists(subquery) {
|
|
795
|
+
const expr = {
|
|
796
|
+
__type: "exists",
|
|
797
|
+
subquery,
|
|
798
|
+
negated: false
|
|
799
|
+
};
|
|
800
|
+
return predicate(expr);
|
|
801
|
+
}
|
|
802
|
+
function notExists(subquery) {
|
|
803
|
+
const expr = {
|
|
804
|
+
__type: "exists",
|
|
805
|
+
subquery,
|
|
806
|
+
negated: true
|
|
807
|
+
};
|
|
808
|
+
return predicate(expr);
|
|
809
|
+
}
|
|
810
|
+
function inSubquery(field, subquery) {
|
|
811
|
+
assertSingleColumnSubquery(subquery);
|
|
812
|
+
assertCompatibleSubqueryValueTypes(field, subquery);
|
|
813
|
+
const expr = {
|
|
814
|
+
__type: "in_subquery",
|
|
815
|
+
field,
|
|
816
|
+
subquery,
|
|
817
|
+
negated: false
|
|
818
|
+
};
|
|
819
|
+
return predicate(expr);
|
|
820
|
+
}
|
|
821
|
+
function notInSubquery(field, subquery) {
|
|
822
|
+
assertSingleColumnSubquery(subquery);
|
|
823
|
+
assertCompatibleSubqueryValueTypes(field, subquery);
|
|
824
|
+
const expr = {
|
|
825
|
+
__type: "in_subquery",
|
|
826
|
+
field,
|
|
827
|
+
subquery,
|
|
828
|
+
negated: true
|
|
829
|
+
};
|
|
830
|
+
return predicate(expr);
|
|
831
|
+
}
|
|
832
|
+
function assertSingleColumnSubquery(subquery) {
|
|
833
|
+
const columnCount = getSubqueryColumnCount(subquery);
|
|
834
|
+
if (columnCount === 1) return;
|
|
835
|
+
throw new UnsupportedPredicateError(
|
|
836
|
+
`IN/NOT IN subquery must project exactly 1 column, but got ${columnCount}`,
|
|
837
|
+
{ subqueryColumnCount: columnCount },
|
|
838
|
+
{
|
|
839
|
+
suggestion: "Use aggregate() with exactly one projected field for scalar IN/NOT IN subqueries."
|
|
840
|
+
}
|
|
841
|
+
);
|
|
842
|
+
}
|
|
843
|
+
function assertCompatibleSubqueryValueTypes(field, subquery) {
|
|
844
|
+
const fieldValueType = field.valueType;
|
|
845
|
+
const subqueryValueType = getSingleSubqueryColumnValueType(subquery);
|
|
846
|
+
const resolvedValueType = fieldValueType ?? subqueryValueType;
|
|
847
|
+
if (isUnsupportedInSubqueryValueType(resolvedValueType)) {
|
|
848
|
+
throw new UnsupportedPredicateError(
|
|
849
|
+
`IN/NOT IN subquery does not support ${String(resolvedValueType)} values`,
|
|
850
|
+
{ valueType: resolvedValueType },
|
|
851
|
+
{
|
|
852
|
+
suggestion: "Use scalar fields (string/number/boolean/date) in IN/NOT IN predicates."
|
|
853
|
+
}
|
|
854
|
+
);
|
|
855
|
+
}
|
|
856
|
+
if (isInSubqueryTypeCompatible(fieldValueType, subqueryValueType)) {
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
throw new UnsupportedPredicateError(
|
|
860
|
+
`IN/NOT IN type mismatch: field type "${String(fieldValueType)}" does not match subquery column type "${String(subqueryValueType)}"`,
|
|
861
|
+
{
|
|
862
|
+
fieldValueType,
|
|
863
|
+
subqueryValueType
|
|
864
|
+
}
|
|
865
|
+
);
|
|
866
|
+
}
|
|
292
867
|
function generateId() {
|
|
293
868
|
return nanoid();
|
|
294
869
|
}
|
|
870
|
+
|
|
871
|
+
// src/store/recorded-capture/guards.ts
|
|
872
|
+
var RECORDED_ISOLATION_REQUIRES_POSTGRES_CHECK = {
|
|
873
|
+
postgres: true,
|
|
874
|
+
sqlite: false
|
|
875
|
+
};
|
|
295
876
|
function requireRecordedSchema(target) {
|
|
296
877
|
if (target.tableNames === void 0) {
|
|
297
878
|
throw new ConfigurationError(
|
|
@@ -332,7 +913,7 @@ function isSupportedRecordedIsolationLevel(isolationLevel) {
|
|
|
332
913
|
return isolationLevel === void 0 || isolationLevel === "read_committed" || isolationLevel === "read_uncommitted";
|
|
333
914
|
}
|
|
334
915
|
function assertRequestedRecordedIsolation(backend, options) {
|
|
335
|
-
if (backend.dialect
|
|
916
|
+
if (!RECORDED_ISOLATION_REQUIRES_POSTGRES_CHECK[backend.dialect]) return;
|
|
336
917
|
if (options?.accessMode === "read_only") return;
|
|
337
918
|
const isolationLevel = options?.isolationLevel;
|
|
338
919
|
if (isSupportedRecordedIsolationLevel(isolationLevel)) return;
|
|
@@ -343,7 +924,7 @@ function normalizeIsolationLevel(value) {
|
|
|
343
924
|
return value.replaceAll(" ", "_").toLowerCase();
|
|
344
925
|
}
|
|
345
926
|
async function assertRecordedCaptureTransactionIsolation(target, options) {
|
|
346
|
-
if (target.dialect
|
|
927
|
+
if (!RECORDED_ISOLATION_REQUIRES_POSTGRES_CHECK[target.dialect]) return;
|
|
347
928
|
if (options?.accessMode === "read_only") return;
|
|
348
929
|
const rows = await target.execute(
|
|
349
930
|
asCompiledRowsSql(sql`
|
|
@@ -390,57 +971,12 @@ function revisionTrackingUnsafeRawWriteError(surface) {
|
|
|
390
971
|
}
|
|
391
972
|
);
|
|
392
973
|
}
|
|
393
|
-
function
|
|
974
|
+
function throwHistoryUnsafeSqlAccess() {
|
|
394
975
|
throw historyUnsafeRawWriteError("tx.sql");
|
|
395
976
|
}
|
|
396
|
-
function
|
|
977
|
+
function throwRevisionTrackingUnsafeSqlAccess() {
|
|
397
978
|
throw revisionTrackingUnsafeRawWriteError("tx.sql");
|
|
398
979
|
}
|
|
399
|
-
function createHistoryUnsafeSqlRef() {
|
|
400
|
-
return createUnsafeSqlRef(failHistoryUnsafeSqlRef);
|
|
401
|
-
}
|
|
402
|
-
function createRevisionTrackingUnsafeSqlRef() {
|
|
403
|
-
return createUnsafeSqlRef(failRevisionTrackingUnsafeSqlRef);
|
|
404
|
-
}
|
|
405
|
-
function createUnsafeSqlRef(fail) {
|
|
406
|
-
return new Proxy(
|
|
407
|
-
function unsafeSqlRef() {
|
|
408
|
-
return fail();
|
|
409
|
-
},
|
|
410
|
-
{
|
|
411
|
-
get() {
|
|
412
|
-
return fail();
|
|
413
|
-
},
|
|
414
|
-
apply() {
|
|
415
|
-
return fail();
|
|
416
|
-
},
|
|
417
|
-
set() {
|
|
418
|
-
return fail();
|
|
419
|
-
},
|
|
420
|
-
defineProperty() {
|
|
421
|
-
return fail();
|
|
422
|
-
},
|
|
423
|
-
deleteProperty() {
|
|
424
|
-
return fail();
|
|
425
|
-
},
|
|
426
|
-
// Enumeration / inspection traps too, so spreading (`{...tx.sql}`),
|
|
427
|
-
// `Object.keys`, `in`, and prototype reads also fail loudly rather than
|
|
428
|
-
// silently yielding an empty object that reads as "no raw handle".
|
|
429
|
-
has() {
|
|
430
|
-
return fail();
|
|
431
|
-
},
|
|
432
|
-
ownKeys() {
|
|
433
|
-
return fail();
|
|
434
|
-
},
|
|
435
|
-
getOwnPropertyDescriptor() {
|
|
436
|
-
return fail();
|
|
437
|
-
},
|
|
438
|
-
getPrototypeOf() {
|
|
439
|
-
return fail();
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
);
|
|
443
|
-
}
|
|
444
980
|
function rawWriteGuards(target, prefix) {
|
|
445
981
|
return {
|
|
446
982
|
...target.executeStatement === void 0 ? {} : {
|
|
@@ -541,6 +1077,10 @@ var RECORDED_MIN = "1970-01-01T00:00:00.000Z";
|
|
|
541
1077
|
var RECORDED_MAX_TIME = new Date(RECORDED_MAX).getTime();
|
|
542
1078
|
var RECORDED_CLOCK_ADVISORY_LOCK_NAMESPACE = "typegraph:recorded-clock";
|
|
543
1079
|
var RECORDED_GRAPH_WRITE_ADVISORY_LOCK_NAMESPACE = "typegraph:recorded-graph-write";
|
|
1080
|
+
var USES_RECORDED_GRAPH_ADVISORY_LOCK = {
|
|
1081
|
+
postgres: true,
|
|
1082
|
+
sqlite: false
|
|
1083
|
+
};
|
|
544
1084
|
function graphAdvisoryLockSql(namespace, graphId) {
|
|
545
1085
|
return sql`
|
|
546
1086
|
SELECT pg_advisory_xact_lock(
|
|
@@ -578,7 +1118,9 @@ async function acquireRecordedGraphWriteLock(target, graphId) {
|
|
|
578
1118
|
);
|
|
579
1119
|
}
|
|
580
1120
|
async function lockRecordedGraphWrite(target, graphId, memo) {
|
|
581
|
-
if (target.dialect
|
|
1121
|
+
if (!USES_RECORDED_GRAPH_ADVISORY_LOCK[target.dialect]) {
|
|
1122
|
+
return graphWriteLockEvidence();
|
|
1123
|
+
}
|
|
582
1124
|
const effectiveMemo = memo ?? recordedGraphLockMemos.get(target);
|
|
583
1125
|
if (effectiveMemo === void 0) {
|
|
584
1126
|
await acquireRecordedGraphWriteLock(target, graphId);
|
|
@@ -620,7 +1162,9 @@ function clockTimestampMs(value) {
|
|
|
620
1162
|
const offsetMatch = OFFSET_DATETIME_PATTERN.exec(value);
|
|
621
1163
|
if (offsetMatch) {
|
|
622
1164
|
const [, date, time, offset] = offsetMatch;
|
|
623
|
-
return Date.parse(
|
|
1165
|
+
return Date.parse(
|
|
1166
|
+
`${date}T${time}${normalizeOffsetDesignator(requireDefined(offset))}`
|
|
1167
|
+
);
|
|
624
1168
|
}
|
|
625
1169
|
return Date.parse(value);
|
|
626
1170
|
}
|
|
@@ -709,21 +1253,29 @@ async function writeRecordedClock(target, schema, graphId, recordedAt) {
|
|
|
709
1253
|
);
|
|
710
1254
|
}
|
|
711
1255
|
async function lockRecordedClock(target, schema, graphId, ownsWriteLock) {
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
1256
|
+
switch (target.dialect) {
|
|
1257
|
+
case "postgres": {
|
|
1258
|
+
await target.execute(
|
|
1259
|
+
asCompiledRowsSql(recordedClockAdvisoryLockSql(graphId))
|
|
1260
|
+
);
|
|
1261
|
+
return;
|
|
1262
|
+
}
|
|
1263
|
+
case "sqlite": {
|
|
1264
|
+
if (ownsWriteLock) return;
|
|
1265
|
+
await executeStatement(
|
|
1266
|
+
target,
|
|
1267
|
+
sql`
|
|
1268
|
+
INSERT INTO ${schema.recordedClockTable} (graph_id, recorded_at)
|
|
1269
|
+
VALUES (${graphId}, ${RECORDED_MIN})
|
|
1270
|
+
ON CONFLICT (graph_id) DO UPDATE SET recorded_at = recorded_at
|
|
1271
|
+
`
|
|
1272
|
+
);
|
|
1273
|
+
return;
|
|
1274
|
+
}
|
|
1275
|
+
default: {
|
|
1276
|
+
target.dialect;
|
|
1277
|
+
}
|
|
717
1278
|
}
|
|
718
|
-
if (ownsWriteLock) return;
|
|
719
|
-
await executeStatement(
|
|
720
|
-
target,
|
|
721
|
-
sql`
|
|
722
|
-
INSERT INTO ${schema.recordedClockTable} (graph_id, recorded_at)
|
|
723
|
-
VALUES (${graphId}, ${RECORDED_MIN})
|
|
724
|
-
ON CONFLICT (graph_id) DO UPDATE SET recorded_at = recorded_at
|
|
725
|
-
`
|
|
726
|
-
);
|
|
727
1279
|
}
|
|
728
1280
|
async function allocateRecordedCommit(target, schema, graphId, ownsWriteLock, previousRevision) {
|
|
729
1281
|
await lockRecordedClock(target, schema, graphId, ownsWriteLock);
|
|
@@ -752,21 +1304,125 @@ async function advanceRevisionClock(target, schema, graphId, ownsWriteLock, prev
|
|
|
752
1304
|
);
|
|
753
1305
|
}
|
|
754
1306
|
|
|
1307
|
+
// src/backend/graph-backend-projection.ts
|
|
1308
|
+
var GRAPH_BACKEND_PROJECTION_KEYS = [
|
|
1309
|
+
"dialect",
|
|
1310
|
+
"capabilities",
|
|
1311
|
+
"tableNames",
|
|
1312
|
+
"fulltextStrategy",
|
|
1313
|
+
"vectorStrategy",
|
|
1314
|
+
"insertNode",
|
|
1315
|
+
"insertNodeNoReturn",
|
|
1316
|
+
"insertNodesBatch",
|
|
1317
|
+
"insertNodesBatchReturning",
|
|
1318
|
+
"updateNode",
|
|
1319
|
+
"deleteNode",
|
|
1320
|
+
"hardDeleteNode",
|
|
1321
|
+
"getNode",
|
|
1322
|
+
"getNodes",
|
|
1323
|
+
"insertEdge",
|
|
1324
|
+
"insertEdgeNoReturn",
|
|
1325
|
+
"insertEdgesBatch",
|
|
1326
|
+
"insertEdgesBatchReturning",
|
|
1327
|
+
"updateEdge",
|
|
1328
|
+
"deleteEdge",
|
|
1329
|
+
"hardDeleteEdge",
|
|
1330
|
+
"deleteEdgesBatch",
|
|
1331
|
+
"hardDeleteEdgesBatch",
|
|
1332
|
+
"getEdge",
|
|
1333
|
+
"getEdges",
|
|
1334
|
+
"countEdgesFrom",
|
|
1335
|
+
"edgeExistsBetween",
|
|
1336
|
+
"findEdgesConnectedTo",
|
|
1337
|
+
"findNodesByKind",
|
|
1338
|
+
"countNodesByKind",
|
|
1339
|
+
"findEdgesByKind",
|
|
1340
|
+
"countEdgesByKind",
|
|
1341
|
+
"insertUnique",
|
|
1342
|
+
"insertUniqueBatch",
|
|
1343
|
+
"deleteUnique",
|
|
1344
|
+
"checkUnique",
|
|
1345
|
+
"checkUniqueBatch",
|
|
1346
|
+
"getActiveSchema",
|
|
1347
|
+
"getSchemaVersion",
|
|
1348
|
+
"commitSchemaVersion",
|
|
1349
|
+
"setActiveVersion",
|
|
1350
|
+
"upsertEmbedding",
|
|
1351
|
+
"upsertEmbeddingBatch",
|
|
1352
|
+
"deleteEmbedding",
|
|
1353
|
+
"vectorSearch",
|
|
1354
|
+
"createVectorIndex",
|
|
1355
|
+
"dropVectorIndex",
|
|
1356
|
+
"hybridSearch",
|
|
1357
|
+
"upsertFulltext",
|
|
1358
|
+
"deleteFulltext",
|
|
1359
|
+
"upsertFulltextBatch",
|
|
1360
|
+
"deleteFulltextBatch",
|
|
1361
|
+
"fulltextSearch",
|
|
1362
|
+
"ensureIndexMaterializationsTable",
|
|
1363
|
+
"ensureRevisionOriginsTable",
|
|
1364
|
+
"getIndexMaterialization",
|
|
1365
|
+
"getIndexMaterializations",
|
|
1366
|
+
"recordIndexMaterialization",
|
|
1367
|
+
"claimIndexMaterialization",
|
|
1368
|
+
"releaseIndexMaterializationClaim",
|
|
1369
|
+
"ensureContributionMaterializationsTable",
|
|
1370
|
+
"getContributionMaterialization",
|
|
1371
|
+
"recordContributionMaterialization",
|
|
1372
|
+
"assertRuntimeContributionsInitialized",
|
|
1373
|
+
"ensureKindRemovalsTable",
|
|
1374
|
+
"getPendingKindRemovals",
|
|
1375
|
+
"getAllKindRemovals",
|
|
1376
|
+
"recordKindRemoval",
|
|
1377
|
+
"ensureReconciliationMarkersTable",
|
|
1378
|
+
"ensureRuntimeContributions",
|
|
1379
|
+
"ensureVectorSlotContribution",
|
|
1380
|
+
"ensureVectorSlotContributions",
|
|
1381
|
+
"assertVectorSlotInitialized",
|
|
1382
|
+
"assertVectorSlotsInitialized",
|
|
1383
|
+
"deleteVectorSlotContribution",
|
|
1384
|
+
"ensureFulltextTable",
|
|
1385
|
+
"getReconciliationMarker",
|
|
1386
|
+
"setReconciliationMarker",
|
|
1387
|
+
"clearGraph",
|
|
1388
|
+
"bootstrapTables",
|
|
1389
|
+
"refreshStatistics",
|
|
1390
|
+
"trustedImport",
|
|
1391
|
+
"execute",
|
|
1392
|
+
"executeStatement",
|
|
1393
|
+
"executeTemporaryStatement",
|
|
1394
|
+
"executeRaw",
|
|
1395
|
+
"compileSql",
|
|
1396
|
+
"executeDdl",
|
|
1397
|
+
"transaction",
|
|
1398
|
+
"close"
|
|
1399
|
+
];
|
|
1400
|
+
function projectBackendMembers(backend, keys) {
|
|
1401
|
+
const entries = keys.flatMap((key) => {
|
|
1402
|
+
if (!Reflect.has(backend, key)) return [];
|
|
1403
|
+
return [[key, Reflect.get(backend, key)]];
|
|
1404
|
+
});
|
|
1405
|
+
return Object.fromEntries(entries);
|
|
1406
|
+
}
|
|
1407
|
+
function createGraphBackendProjection(backend) {
|
|
1408
|
+
return projectBackendMembers(backend, GRAPH_BACKEND_PROJECTION_KEYS);
|
|
1409
|
+
}
|
|
1410
|
+
|
|
755
1411
|
// src/store/insert-dispatch.ts
|
|
756
1412
|
function nodeInsertDispatch(backend) {
|
|
757
1413
|
return {
|
|
758
1414
|
one: (params) => backend.insertNode(params),
|
|
759
|
-
oneNoReturn: backend.insertNodeNoReturn === void 0 ? void 0 : (params) => backend.insertNodeNoReturn(params),
|
|
760
|
-
batch: backend.insertNodesBatch === void 0 ? void 0 : (params) => backend.insertNodesBatch(params),
|
|
761
|
-
batchReturning: backend.insertNodesBatchReturning === void 0 ? void 0 : (params) => backend.insertNodesBatchReturning(params)
|
|
1415
|
+
oneNoReturn: backend.insertNodeNoReturn === void 0 ? void 0 : (params) => requireDefined(backend.insertNodeNoReturn)(params),
|
|
1416
|
+
batch: backend.insertNodesBatch === void 0 ? void 0 : (params) => requireDefined(backend.insertNodesBatch)(params),
|
|
1417
|
+
batchReturning: backend.insertNodesBatchReturning === void 0 ? void 0 : (params) => requireDefined(backend.insertNodesBatchReturning)(params)
|
|
762
1418
|
};
|
|
763
1419
|
}
|
|
764
1420
|
function edgeInsertDispatch(backend) {
|
|
765
1421
|
return {
|
|
766
1422
|
one: (params) => backend.insertEdge(params),
|
|
767
|
-
oneNoReturn: backend.insertEdgeNoReturn === void 0 ? void 0 : (params) => backend.insertEdgeNoReturn(params),
|
|
768
|
-
batch: backend.insertEdgesBatch === void 0 ? void 0 : (params) => backend.insertEdgesBatch(params),
|
|
769
|
-
batchReturning: backend.insertEdgesBatchReturning === void 0 ? void 0 : (params) => backend.insertEdgesBatchReturning(params)
|
|
1423
|
+
oneNoReturn: backend.insertEdgeNoReturn === void 0 ? void 0 : (params) => requireDefined(backend.insertEdgeNoReturn)(params),
|
|
1424
|
+
batch: backend.insertEdgesBatch === void 0 ? void 0 : (params) => requireDefined(backend.insertEdgesBatch)(params),
|
|
1425
|
+
batchReturning: backend.insertEdgesBatchReturning === void 0 ? void 0 : (params) => requireDefined(backend.insertEdgesBatchReturning)(params)
|
|
770
1426
|
};
|
|
771
1427
|
}
|
|
772
1428
|
async function runInsertNoReturn(dispatch, params) {
|
|
@@ -797,6 +1453,680 @@ async function runInsertBatchReturning(dispatch, params) {
|
|
|
797
1453
|
return rows;
|
|
798
1454
|
}
|
|
799
1455
|
|
|
1456
|
+
// src/query/compiler/predicates.ts
|
|
1457
|
+
var COMPARISON_OP_SQL = {
|
|
1458
|
+
eq: "=",
|
|
1459
|
+
neq: "!=",
|
|
1460
|
+
gt: ">",
|
|
1461
|
+
gte: ">=",
|
|
1462
|
+
lt: "<",
|
|
1463
|
+
lte: "<="
|
|
1464
|
+
};
|
|
1465
|
+
function compileFieldColumn(field, cteAlias, cteColumnPrefix) {
|
|
1466
|
+
if (cteColumnPrefix !== void 0) {
|
|
1467
|
+
const qualifier2 = cteColumnPrefix === "" ? "" : `${cteColumnPrefix}.`;
|
|
1468
|
+
if (field.path.length === 1 && field.path[0] === "id") {
|
|
1469
|
+
return sql.raw(`${qualifier2}id`);
|
|
1470
|
+
}
|
|
1471
|
+
if (field.path.length === 1 && field.path[0] === "kind") {
|
|
1472
|
+
return sql.raw(`${qualifier2}kind`);
|
|
1473
|
+
}
|
|
1474
|
+
if (field.path.length > 0 && field.path[0] === "props") {
|
|
1475
|
+
return sql.raw(`${qualifier2}props`);
|
|
1476
|
+
}
|
|
1477
|
+
return sql.raw(`${qualifier2}${field.path.join("_")}`);
|
|
1478
|
+
}
|
|
1479
|
+
const prefix = field.alias;
|
|
1480
|
+
const qualifier = cteAlias ? `${cteAlias}.` : "";
|
|
1481
|
+
if (field.path.length === 1 && field.path[0] === "id") {
|
|
1482
|
+
return sql.raw(`${qualifier}${prefix}_id`);
|
|
1483
|
+
}
|
|
1484
|
+
if (field.path.length === 1 && field.path[0] === "kind") {
|
|
1485
|
+
return sql.raw(`${qualifier}${prefix}_kind`);
|
|
1486
|
+
}
|
|
1487
|
+
if (field.path.length > 0 && field.path[0] === "props") {
|
|
1488
|
+
return sql.raw(`${qualifier}${prefix}_props`);
|
|
1489
|
+
}
|
|
1490
|
+
return sql.raw(`${qualifier}${prefix}_${field.path.join("_")}`);
|
|
1491
|
+
}
|
|
1492
|
+
function getFieldPointer(field) {
|
|
1493
|
+
if (field.jsonPointer !== void 0) {
|
|
1494
|
+
return field.jsonPointer;
|
|
1495
|
+
}
|
|
1496
|
+
if (field.path.length > 1 && field.path[0] === "props") {
|
|
1497
|
+
return jsonPointer(field.path.slice(1));
|
|
1498
|
+
}
|
|
1499
|
+
return void 0;
|
|
1500
|
+
}
|
|
1501
|
+
function isJsonField(field) {
|
|
1502
|
+
return field.path.length > 0 && field.path[0] === "props";
|
|
1503
|
+
}
|
|
1504
|
+
function normalizeValueType2(valueType) {
|
|
1505
|
+
if (!valueType || valueType === "unknown") {
|
|
1506
|
+
return void 0;
|
|
1507
|
+
}
|
|
1508
|
+
return valueType;
|
|
1509
|
+
}
|
|
1510
|
+
function compileFieldValue(field, dialect, valueType, cteAlias, pointerOverride, cteColumnPrefix) {
|
|
1511
|
+
const resolved = normalizeValueType2(valueType);
|
|
1512
|
+
const column = compileFieldColumn(field, cteAlias, cteColumnPrefix);
|
|
1513
|
+
if (!isJsonField(field)) {
|
|
1514
|
+
return column;
|
|
1515
|
+
}
|
|
1516
|
+
const pointer = pointerOverride ?? getFieldPointer(field);
|
|
1517
|
+
if (!pointer || pointer === "") {
|
|
1518
|
+
return column;
|
|
1519
|
+
}
|
|
1520
|
+
switch (resolved) {
|
|
1521
|
+
case "number": {
|
|
1522
|
+
return dialect.jsonExtractNumber(column, pointer);
|
|
1523
|
+
}
|
|
1524
|
+
case "boolean": {
|
|
1525
|
+
return dialect.jsonExtractBoolean(column, pointer);
|
|
1526
|
+
}
|
|
1527
|
+
case "date": {
|
|
1528
|
+
return dialect.jsonExtractDate(column, pointer);
|
|
1529
|
+
}
|
|
1530
|
+
case "array":
|
|
1531
|
+
case "object":
|
|
1532
|
+
case "embedding": {
|
|
1533
|
+
return dialect.jsonExtract(column, pointer);
|
|
1534
|
+
}
|
|
1535
|
+
case "string":
|
|
1536
|
+
case "unknown":
|
|
1537
|
+
case void 0: {
|
|
1538
|
+
return dialect.jsonExtractText(column, pointer);
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
}
|
|
1542
|
+
function compileFieldTextValue(field, dialect, cteAlias, pointerOverride, cteColumnPrefix) {
|
|
1543
|
+
const column = compileFieldColumn(field, cteAlias, cteColumnPrefix);
|
|
1544
|
+
if (!isJsonField(field)) {
|
|
1545
|
+
return column;
|
|
1546
|
+
}
|
|
1547
|
+
const pointer = getFieldPointer(field);
|
|
1548
|
+
if (!pointer || pointer === "") {
|
|
1549
|
+
return column;
|
|
1550
|
+
}
|
|
1551
|
+
return dialect.jsonExtractText(column, pointer);
|
|
1552
|
+
}
|
|
1553
|
+
function compileFieldJsonValue(field, dialect, cteAlias, pointerOverride, cteColumnPrefix) {
|
|
1554
|
+
const column = compileFieldColumn(field, cteAlias, cteColumnPrefix);
|
|
1555
|
+
if (!isJsonField(field)) {
|
|
1556
|
+
return column;
|
|
1557
|
+
}
|
|
1558
|
+
const pointer = pointerOverride ?? getFieldPointer(field);
|
|
1559
|
+
if (!pointer || pointer === "") {
|
|
1560
|
+
return column;
|
|
1561
|
+
}
|
|
1562
|
+
return dialect.jsonExtract(column, pointer);
|
|
1563
|
+
}
|
|
1564
|
+
function resolveLiteralValueTypes(literals) {
|
|
1565
|
+
const resolved = /* @__PURE__ */ new Set();
|
|
1566
|
+
for (const literal2 of literals) {
|
|
1567
|
+
const valueType = normalizeValueType2(literal2.valueType);
|
|
1568
|
+
if (valueType) {
|
|
1569
|
+
resolved.add(valueType);
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
if (resolved.size > 1) {
|
|
1573
|
+
throw new UnsupportedPredicateError(
|
|
1574
|
+
"Mixed literal value types are not supported in predicates",
|
|
1575
|
+
{ valueTypes: [...resolved] }
|
|
1576
|
+
);
|
|
1577
|
+
}
|
|
1578
|
+
return resolved.values().next().value;
|
|
1579
|
+
}
|
|
1580
|
+
function resolveComparisonValueType(field, right) {
|
|
1581
|
+
if (isParameterRef(right)) {
|
|
1582
|
+
return normalizeValueType2(right.valueType) ?? normalizeValueType2(field.valueType);
|
|
1583
|
+
}
|
|
1584
|
+
const literals = Array.isArray(right) ? right : [right];
|
|
1585
|
+
const literalType = resolveLiteralValueTypes(literals);
|
|
1586
|
+
const fieldType = normalizeValueType2(field.valueType);
|
|
1587
|
+
if (fieldType === "date" && literalType === "string") {
|
|
1588
|
+
return fieldType;
|
|
1589
|
+
}
|
|
1590
|
+
if (literalType) {
|
|
1591
|
+
return literalType;
|
|
1592
|
+
}
|
|
1593
|
+
return fieldType;
|
|
1594
|
+
}
|
|
1595
|
+
function resolvePredicateValueType(preferred, literal2) {
|
|
1596
|
+
const normalizedPreferred = normalizeValueType2(preferred);
|
|
1597
|
+
if (normalizedPreferred) {
|
|
1598
|
+
return normalizedPreferred;
|
|
1599
|
+
}
|
|
1600
|
+
return literal2 ? normalizeValueType2(literal2.valueType) : void 0;
|
|
1601
|
+
}
|
|
1602
|
+
function convertValueForSql(value, dialect) {
|
|
1603
|
+
return dialect.bindValue(value);
|
|
1604
|
+
}
|
|
1605
|
+
function compileStringPattern(op, pattern) {
|
|
1606
|
+
const escaped = pattern.replaceAll(
|
|
1607
|
+
LIKE_ESCAPE_CHARACTER,
|
|
1608
|
+
`${LIKE_ESCAPE_CHARACTER}${LIKE_ESCAPE_CHARACTER}`
|
|
1609
|
+
).replaceAll("%", `${LIKE_ESCAPE_CHARACTER}%`).replaceAll("_", `${LIKE_ESCAPE_CHARACTER}_`);
|
|
1610
|
+
switch (op) {
|
|
1611
|
+
case "contains": {
|
|
1612
|
+
return `%${escaped}%`;
|
|
1613
|
+
}
|
|
1614
|
+
case "startsWith": {
|
|
1615
|
+
return `${escaped}%`;
|
|
1616
|
+
}
|
|
1617
|
+
case "endsWith": {
|
|
1618
|
+
return `%${escaped}`;
|
|
1619
|
+
}
|
|
1620
|
+
case "like":
|
|
1621
|
+
case "ilike": {
|
|
1622
|
+
return pattern;
|
|
1623
|
+
}
|
|
1624
|
+
default: {
|
|
1625
|
+
return escaped;
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
function escapeLikePatternParameter(parameter) {
|
|
1630
|
+
const doubledEscape = `${LIKE_ESCAPE_CHARACTER}${LIKE_ESCAPE_CHARACTER}`;
|
|
1631
|
+
return sql`REPLACE(REPLACE(REPLACE(${parameter}, ${LIKE_ESCAPE_CHARACTER}, ${doubledEscape}), '%', ${`${LIKE_ESCAPE_CHARACTER}%`}), '_', ${`${LIKE_ESCAPE_CHARACTER}_`})`;
|
|
1632
|
+
}
|
|
1633
|
+
function compileParameterizedStringPattern(op, parameter) {
|
|
1634
|
+
switch (op) {
|
|
1635
|
+
case "contains": {
|
|
1636
|
+
const escaped = escapeLikePatternParameter(parameter);
|
|
1637
|
+
return sql`'%' || ${escaped} || '%'`;
|
|
1638
|
+
}
|
|
1639
|
+
case "startsWith": {
|
|
1640
|
+
const escaped = escapeLikePatternParameter(parameter);
|
|
1641
|
+
return sql`${escaped} || '%'`;
|
|
1642
|
+
}
|
|
1643
|
+
case "endsWith": {
|
|
1644
|
+
const escaped = escapeLikePatternParameter(parameter);
|
|
1645
|
+
return sql`'%' || ${escaped}`;
|
|
1646
|
+
}
|
|
1647
|
+
case "like":
|
|
1648
|
+
case "ilike": {
|
|
1649
|
+
return parameter;
|
|
1650
|
+
}
|
|
1651
|
+
default: {
|
|
1652
|
+
return escapeLikePatternParameter(parameter);
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
function compilePredicateExpression(expr, ctx) {
|
|
1657
|
+
const { dialect } = ctx;
|
|
1658
|
+
const cteColumnPrefix = ctx.cteColumnPrefix;
|
|
1659
|
+
switch (expr.__type) {
|
|
1660
|
+
case "comparison": {
|
|
1661
|
+
return compileComparisonPredicate(expr, dialect, cteColumnPrefix);
|
|
1662
|
+
}
|
|
1663
|
+
case "string_op": {
|
|
1664
|
+
const field = compileFieldTextValue(
|
|
1665
|
+
expr.field,
|
|
1666
|
+
dialect,
|
|
1667
|
+
void 0,
|
|
1668
|
+
void 0,
|
|
1669
|
+
cteColumnPrefix
|
|
1670
|
+
);
|
|
1671
|
+
if (isParameterRef(expr.pattern)) {
|
|
1672
|
+
const placeholder = sql`${sql.placeholder(expr.pattern.name)}`;
|
|
1673
|
+
const pattern2 = compileParameterizedStringPattern(expr.op, placeholder);
|
|
1674
|
+
if (expr.op === "ilike" || expr.op === "contains" || expr.op === "startsWith" || expr.op === "endsWith") {
|
|
1675
|
+
return dialect.ilike(field, pattern2);
|
|
1676
|
+
}
|
|
1677
|
+
return sql`${field} LIKE ${pattern2} ${likeEscapeClause}`;
|
|
1678
|
+
}
|
|
1679
|
+
const pattern = compileStringPattern(expr.op, expr.pattern);
|
|
1680
|
+
if (expr.op === "ilike" || expr.op === "contains" || expr.op === "startsWith" || expr.op === "endsWith") {
|
|
1681
|
+
return dialect.ilike(field, pattern);
|
|
1682
|
+
}
|
|
1683
|
+
return sql`${field} LIKE ${pattern} ${likeEscapeClause}`;
|
|
1684
|
+
}
|
|
1685
|
+
case "null_check": {
|
|
1686
|
+
const field = compileFieldTextValue(
|
|
1687
|
+
expr.field,
|
|
1688
|
+
dialect,
|
|
1689
|
+
void 0,
|
|
1690
|
+
void 0,
|
|
1691
|
+
cteColumnPrefix
|
|
1692
|
+
);
|
|
1693
|
+
return expr.op === "isNull" ? sql`${field} IS NULL` : sql`${field} IS NOT NULL`;
|
|
1694
|
+
}
|
|
1695
|
+
case "between": {
|
|
1696
|
+
const lowerIsParam = isParameterRef(expr.lower);
|
|
1697
|
+
const upperIsParam = isParameterRef(expr.upper);
|
|
1698
|
+
const boundsForType = [];
|
|
1699
|
+
if (!lowerIsParam) boundsForType.push(expr.lower);
|
|
1700
|
+
if (!upperIsParam) boundsForType.push(expr.upper);
|
|
1701
|
+
const valueType = boundsForType.length > 0 ? resolveComparisonValueType(expr.field, boundsForType) : normalizeValueType2(expr.field.valueType);
|
|
1702
|
+
if (valueType === "array" || valueType === "object") {
|
|
1703
|
+
throw new UnsupportedPredicateError(
|
|
1704
|
+
"Between comparisons are not supported for JSON arrays or objects"
|
|
1705
|
+
);
|
|
1706
|
+
}
|
|
1707
|
+
const field = compileFieldValue(
|
|
1708
|
+
expr.field,
|
|
1709
|
+
dialect,
|
|
1710
|
+
valueType,
|
|
1711
|
+
void 0,
|
|
1712
|
+
void 0,
|
|
1713
|
+
cteColumnPrefix
|
|
1714
|
+
);
|
|
1715
|
+
const lower = lowerIsParam ? sql.placeholder(expr.lower.name) : convertValueForSql(expr.lower.value, dialect);
|
|
1716
|
+
const upper = upperIsParam ? sql.placeholder(expr.upper.name) : convertValueForSql(expr.upper.value, dialect);
|
|
1717
|
+
return sql`${field} BETWEEN ${lower} AND ${upper}`;
|
|
1718
|
+
}
|
|
1719
|
+
case "and": {
|
|
1720
|
+
const parts = expr.predicates.map(
|
|
1721
|
+
(p) => compilePredicateExpression(p, ctx)
|
|
1722
|
+
);
|
|
1723
|
+
return sql`(${sql.join(parts, sql` AND `)})`;
|
|
1724
|
+
}
|
|
1725
|
+
case "or": {
|
|
1726
|
+
const parts = expr.predicates.map(
|
|
1727
|
+
(p) => compilePredicateExpression(p, ctx)
|
|
1728
|
+
);
|
|
1729
|
+
return sql`(${sql.join(parts, sql` OR `)})`;
|
|
1730
|
+
}
|
|
1731
|
+
case "not": {
|
|
1732
|
+
const inner = compilePredicateExpression(expr.predicate, ctx);
|
|
1733
|
+
return sql`NOT (${inner})`;
|
|
1734
|
+
}
|
|
1735
|
+
case "array_op": {
|
|
1736
|
+
return compileArrayPredicate(expr, dialect, cteColumnPrefix);
|
|
1737
|
+
}
|
|
1738
|
+
case "object_op": {
|
|
1739
|
+
return compileObjectPredicate(expr, dialect, cteColumnPrefix);
|
|
1740
|
+
}
|
|
1741
|
+
case "aggregate_comparison": {
|
|
1742
|
+
return compileAggregatePredicate(expr, dialect);
|
|
1743
|
+
}
|
|
1744
|
+
case "exists": {
|
|
1745
|
+
return compileExistsSubquery(expr, ctx);
|
|
1746
|
+
}
|
|
1747
|
+
case "in_subquery": {
|
|
1748
|
+
return compileInSubquery(expr, ctx);
|
|
1749
|
+
}
|
|
1750
|
+
case "vector_similarity":
|
|
1751
|
+
case "fulltext_match": {
|
|
1752
|
+
return STRUCTURAL_PREDICATE_NOOP;
|
|
1753
|
+
}
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
var STRUCTURAL_PREDICATE_NOOP = sql.raw("1=1");
|
|
1757
|
+
function compileComparisonPredicate(expr, dialect, cteColumnPrefix) {
|
|
1758
|
+
if (isParameterRef(expr.right)) {
|
|
1759
|
+
const parameterValueType = normalizeValueType2(expr.right.valueType) ?? normalizeValueType2(expr.left.valueType);
|
|
1760
|
+
const left2 = compileFieldValue(
|
|
1761
|
+
expr.left,
|
|
1762
|
+
dialect,
|
|
1763
|
+
parameterValueType,
|
|
1764
|
+
void 0,
|
|
1765
|
+
void 0,
|
|
1766
|
+
cteColumnPrefix
|
|
1767
|
+
);
|
|
1768
|
+
const opSql2 = COMPARISON_OP_SQL[expr.op];
|
|
1769
|
+
if (!opSql2) {
|
|
1770
|
+
throw new UnsupportedPredicateError(
|
|
1771
|
+
`Comparison operation "${expr.op}" is not supported for parameterized predicates`
|
|
1772
|
+
);
|
|
1773
|
+
}
|
|
1774
|
+
return sql`${left2} ${sql.raw(opSql2)} ${sql.placeholder(expr.right.name)}`;
|
|
1775
|
+
}
|
|
1776
|
+
const valueType = resolveComparisonValueType(expr.left, expr.right);
|
|
1777
|
+
if (valueType === "array" || valueType === "object") {
|
|
1778
|
+
throw new UnsupportedPredicateError(
|
|
1779
|
+
`Comparison operation "${expr.op}" is not supported for ${valueType} values`
|
|
1780
|
+
);
|
|
1781
|
+
}
|
|
1782
|
+
const left = compileFieldValue(
|
|
1783
|
+
expr.left,
|
|
1784
|
+
dialect,
|
|
1785
|
+
valueType,
|
|
1786
|
+
void 0,
|
|
1787
|
+
void 0,
|
|
1788
|
+
cteColumnPrefix
|
|
1789
|
+
);
|
|
1790
|
+
if (expr.op === "in" || expr.op === "notIn") {
|
|
1791
|
+
const values = Array.isArray(expr.right) ? expr.right : [expr.right];
|
|
1792
|
+
if (values.length === 0) {
|
|
1793
|
+
return expr.op === "in" ? sql.raw("1=0") : sql.raw("1=1");
|
|
1794
|
+
}
|
|
1795
|
+
const convertedValues = values.map(
|
|
1796
|
+
(value) => convertValueForSql(value.value, dialect)
|
|
1797
|
+
);
|
|
1798
|
+
return dialect.inList(left, convertedValues, expr.op === "notIn");
|
|
1799
|
+
}
|
|
1800
|
+
const right = expr.right;
|
|
1801
|
+
const rightValue = Array.isArray(right) ? requireDefined(right[0]) : right;
|
|
1802
|
+
const convertedRight = convertValueForSql(rightValue.value, dialect);
|
|
1803
|
+
const opSql = COMPARISON_OP_SQL[expr.op];
|
|
1804
|
+
if (!opSql) {
|
|
1805
|
+
throw new UnsupportedPredicateError(
|
|
1806
|
+
`Comparison operation "${expr.op}" is not supported`
|
|
1807
|
+
);
|
|
1808
|
+
}
|
|
1809
|
+
return sql`${left} ${sql.raw(opSql)} ${convertedRight}`;
|
|
1810
|
+
}
|
|
1811
|
+
function compileArrayPredicate(expr, dialect, cteColumnPrefix) {
|
|
1812
|
+
const field = compileFieldJsonValue(
|
|
1813
|
+
expr.field,
|
|
1814
|
+
dialect,
|
|
1815
|
+
void 0,
|
|
1816
|
+
void 0,
|
|
1817
|
+
cteColumnPrefix
|
|
1818
|
+
);
|
|
1819
|
+
const values = expr.values?.map((v) => convertValueForSql(v.value, dialect)) ?? [];
|
|
1820
|
+
switch (expr.op) {
|
|
1821
|
+
case "isEmpty": {
|
|
1822
|
+
return sql`(${field} IS NULL OR ${dialect.jsonArrayLength(field)} = 0)`;
|
|
1823
|
+
}
|
|
1824
|
+
case "isNotEmpty": {
|
|
1825
|
+
return sql`(${field} IS NOT NULL AND ${dialect.jsonArrayLength(field)} > 0)`;
|
|
1826
|
+
}
|
|
1827
|
+
case "lengthEq": {
|
|
1828
|
+
return sql`${dialect.jsonArrayLength(field)} = ${expr.length}`;
|
|
1829
|
+
}
|
|
1830
|
+
case "lengthGt": {
|
|
1831
|
+
return sql`${dialect.jsonArrayLength(field)} > ${expr.length}`;
|
|
1832
|
+
}
|
|
1833
|
+
case "lengthGte": {
|
|
1834
|
+
return sql`${dialect.jsonArrayLength(field)} >= ${expr.length}`;
|
|
1835
|
+
}
|
|
1836
|
+
case "lengthLt": {
|
|
1837
|
+
return sql`${dialect.jsonArrayLength(field)} < ${expr.length}`;
|
|
1838
|
+
}
|
|
1839
|
+
case "lengthLte": {
|
|
1840
|
+
return sql`${dialect.jsonArrayLength(field)} <= ${expr.length}`;
|
|
1841
|
+
}
|
|
1842
|
+
case "contains": {
|
|
1843
|
+
const value = values[0];
|
|
1844
|
+
if (value === void 0) {
|
|
1845
|
+
return sql.raw("1=0");
|
|
1846
|
+
}
|
|
1847
|
+
return dialect.jsonArrayContains(field, value);
|
|
1848
|
+
}
|
|
1849
|
+
case "containsAll": {
|
|
1850
|
+
return dialect.jsonArrayContainsAll(field, values);
|
|
1851
|
+
}
|
|
1852
|
+
case "containsAny": {
|
|
1853
|
+
return dialect.jsonArrayContainsAny(field, values);
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
function compileObjectPredicate(expr, dialect, cteColumnPrefix) {
|
|
1858
|
+
const basePointer = getFieldPointer(expr.field);
|
|
1859
|
+
const pointer = joinJsonPointers(basePointer, expr.pointer);
|
|
1860
|
+
const column = compileFieldColumn(expr.field, void 0, cteColumnPrefix);
|
|
1861
|
+
switch (expr.op) {
|
|
1862
|
+
case "hasKey":
|
|
1863
|
+
case "hasPath": {
|
|
1864
|
+
return dialect.jsonHasPath(column, pointer);
|
|
1865
|
+
}
|
|
1866
|
+
case "pathEquals": {
|
|
1867
|
+
if (!expr.value) {
|
|
1868
|
+
throw new UnsupportedPredicateError(
|
|
1869
|
+
"pathEquals requires a comparison value"
|
|
1870
|
+
);
|
|
1871
|
+
}
|
|
1872
|
+
const valueType = resolvePredicateValueType(expr.valueType, expr.value);
|
|
1873
|
+
if (valueType === "array" || valueType === "object") {
|
|
1874
|
+
throw new UnsupportedPredicateError(
|
|
1875
|
+
"pathEquals is not supported for JSON arrays or objects"
|
|
1876
|
+
);
|
|
1877
|
+
}
|
|
1878
|
+
const left = compileFieldValue(
|
|
1879
|
+
expr.field,
|
|
1880
|
+
dialect,
|
|
1881
|
+
valueType,
|
|
1882
|
+
void 0,
|
|
1883
|
+
pointer,
|
|
1884
|
+
cteColumnPrefix
|
|
1885
|
+
);
|
|
1886
|
+
return sql`${left} = ${convertValueForSql(expr.value.value, dialect)}`;
|
|
1887
|
+
}
|
|
1888
|
+
case "pathContains": {
|
|
1889
|
+
if (!expr.value) {
|
|
1890
|
+
throw new UnsupportedPredicateError(
|
|
1891
|
+
"pathContains requires a comparison value"
|
|
1892
|
+
);
|
|
1893
|
+
}
|
|
1894
|
+
const arrayField2 = compileFieldJsonValue(
|
|
1895
|
+
expr.field,
|
|
1896
|
+
dialect,
|
|
1897
|
+
void 0,
|
|
1898
|
+
pointer,
|
|
1899
|
+
cteColumnPrefix
|
|
1900
|
+
);
|
|
1901
|
+
return dialect.jsonArrayContains(
|
|
1902
|
+
arrayField2,
|
|
1903
|
+
convertValueForSql(expr.value.value, dialect)
|
|
1904
|
+
);
|
|
1905
|
+
}
|
|
1906
|
+
case "pathIsNull": {
|
|
1907
|
+
return dialect.jsonPathIsNull(column, pointer);
|
|
1908
|
+
}
|
|
1909
|
+
case "pathIsNotNull": {
|
|
1910
|
+
return dialect.jsonPathIsNotNull(column, pointer);
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
function compileAggregatePredicate(expr, dialect) {
|
|
1915
|
+
const aggregate = compileAggregateExpr(expr.aggregate, dialect);
|
|
1916
|
+
const op = COMPARISON_OP_SQL[expr.op];
|
|
1917
|
+
if (!op) {
|
|
1918
|
+
throw new UnsupportedPredicateError(
|
|
1919
|
+
`Comparison operation "${expr.op}" is not supported for aggregate predicates`
|
|
1920
|
+
);
|
|
1921
|
+
}
|
|
1922
|
+
const convertedValue = convertValueForSql(expr.value.value, dialect);
|
|
1923
|
+
return sql`${aggregate} ${sql.raw(op)} ${convertedValue}`;
|
|
1924
|
+
}
|
|
1925
|
+
function compileAggregateExpr(expr, dialect) {
|
|
1926
|
+
const cteAlias = `cte_${expr.field.alias}`;
|
|
1927
|
+
const field = compileFieldValue(
|
|
1928
|
+
expr.field,
|
|
1929
|
+
dialect,
|
|
1930
|
+
expr.field.valueType,
|
|
1931
|
+
cteAlias
|
|
1932
|
+
);
|
|
1933
|
+
switch (expr.function) {
|
|
1934
|
+
case "count": {
|
|
1935
|
+
return sql`COUNT(${field})`;
|
|
1936
|
+
}
|
|
1937
|
+
case "countDistinct": {
|
|
1938
|
+
return sql`COUNT(DISTINCT ${field})`;
|
|
1939
|
+
}
|
|
1940
|
+
case "sum": {
|
|
1941
|
+
return sql`SUM(${field})`;
|
|
1942
|
+
}
|
|
1943
|
+
case "avg": {
|
|
1944
|
+
return sql`AVG(${field})`;
|
|
1945
|
+
}
|
|
1946
|
+
case "min": {
|
|
1947
|
+
return sql`MIN(${field})`;
|
|
1948
|
+
}
|
|
1949
|
+
case "max": {
|
|
1950
|
+
return sql`MAX(${field})`;
|
|
1951
|
+
}
|
|
1952
|
+
default: {
|
|
1953
|
+
throw new UnsupportedPredicateError(
|
|
1954
|
+
`Unknown aggregate function: ${expr.function}`
|
|
1955
|
+
);
|
|
1956
|
+
}
|
|
1957
|
+
}
|
|
1958
|
+
}
|
|
1959
|
+
function compileExistsSubquery(expr, ctx) {
|
|
1960
|
+
if (expr.subquery.graphId === void 0) {
|
|
1961
|
+
throw new UnsupportedPredicateError("EXISTS subquery must have a graphId");
|
|
1962
|
+
}
|
|
1963
|
+
const subSql = ctx.compileQuery(expr.subquery, expr.subquery.graphId);
|
|
1964
|
+
return expr.negated ? sql`NOT EXISTS (${subSql})` : sql`EXISTS (${subSql})`;
|
|
1965
|
+
}
|
|
1966
|
+
function compileInSubquery(expr, ctx) {
|
|
1967
|
+
const subqueryColumnCount = getSubqueryColumnCount(expr.subquery);
|
|
1968
|
+
if (subqueryColumnCount !== 1) {
|
|
1969
|
+
throw new UnsupportedPredicateError(
|
|
1970
|
+
`IN/NOT IN subquery must project exactly 1 column, but got ${subqueryColumnCount}`,
|
|
1971
|
+
{ subqueryColumnCount }
|
|
1972
|
+
);
|
|
1973
|
+
}
|
|
1974
|
+
const fieldValueType = normalizeValueType2(expr.field.valueType);
|
|
1975
|
+
const subqueryValueType = getSingleSubqueryColumnValueType(expr.subquery);
|
|
1976
|
+
const resolvedValueType = fieldValueType ?? subqueryValueType;
|
|
1977
|
+
if (isUnsupportedInSubqueryValueType(resolvedValueType)) {
|
|
1978
|
+
throw new UnsupportedPredicateError(
|
|
1979
|
+
`IN/NOT IN subquery does not support ${String(resolvedValueType)} values`,
|
|
1980
|
+
{ valueType: resolvedValueType }
|
|
1981
|
+
);
|
|
1982
|
+
}
|
|
1983
|
+
if (!isInSubqueryTypeCompatible(fieldValueType, subqueryValueType)) {
|
|
1984
|
+
throw new UnsupportedPredicateError(
|
|
1985
|
+
`IN/NOT IN type mismatch: field type "${String(fieldValueType)}" does not match subquery column type "${String(subqueryValueType)}"`,
|
|
1986
|
+
{
|
|
1987
|
+
fieldValueType,
|
|
1988
|
+
subqueryValueType
|
|
1989
|
+
}
|
|
1990
|
+
);
|
|
1991
|
+
}
|
|
1992
|
+
const valueType = fieldValueType ?? subqueryValueType;
|
|
1993
|
+
if (expr.subquery.graphId === void 0) {
|
|
1994
|
+
throw new UnsupportedPredicateError(
|
|
1995
|
+
"IN/NOT IN subquery must have a graphId"
|
|
1996
|
+
);
|
|
1997
|
+
}
|
|
1998
|
+
const fieldSql = compileFieldValue(
|
|
1999
|
+
expr.field,
|
|
2000
|
+
ctx.dialect,
|
|
2001
|
+
valueType,
|
|
2002
|
+
void 0,
|
|
2003
|
+
void 0,
|
|
2004
|
+
ctx.cteColumnPrefix
|
|
2005
|
+
);
|
|
2006
|
+
const subSql = ctx.compileQuery(expr.subquery, expr.subquery.graphId);
|
|
2007
|
+
return expr.negated ? sql`${fieldSql} NOT IN (${subSql})` : sql`${fieldSql} IN (${subSql})`;
|
|
2008
|
+
}
|
|
2009
|
+
function extractStructuralPredicates(predicates, isMatch, rejectionMessage) {
|
|
2010
|
+
const results = [];
|
|
2011
|
+
function visit(expr, inDisallowedBranch) {
|
|
2012
|
+
if (isMatch(expr)) {
|
|
2013
|
+
if (inDisallowedBranch) {
|
|
2014
|
+
throw new UnsupportedPredicateError(rejectionMessage);
|
|
2015
|
+
}
|
|
2016
|
+
results.push(expr);
|
|
2017
|
+
return;
|
|
2018
|
+
}
|
|
2019
|
+
switch (expr.__type) {
|
|
2020
|
+
case "and": {
|
|
2021
|
+
for (const child of expr.predicates) visit(child, inDisallowedBranch);
|
|
2022
|
+
return;
|
|
2023
|
+
}
|
|
2024
|
+
case "or": {
|
|
2025
|
+
for (const child of expr.predicates) visit(child, true);
|
|
2026
|
+
return;
|
|
2027
|
+
}
|
|
2028
|
+
case "not": {
|
|
2029
|
+
visit(expr.predicate, true);
|
|
2030
|
+
return;
|
|
2031
|
+
}
|
|
2032
|
+
case "comparison":
|
|
2033
|
+
case "string_op":
|
|
2034
|
+
case "null_check":
|
|
2035
|
+
case "between":
|
|
2036
|
+
case "array_op":
|
|
2037
|
+
case "object_op":
|
|
2038
|
+
case "aggregate_comparison":
|
|
2039
|
+
case "exists":
|
|
2040
|
+
case "in_subquery":
|
|
2041
|
+
case "vector_similarity":
|
|
2042
|
+
case "fulltext_match": {
|
|
2043
|
+
return;
|
|
2044
|
+
}
|
|
2045
|
+
}
|
|
2046
|
+
}
|
|
2047
|
+
for (const pred of predicates) visit(pred.expression, false);
|
|
2048
|
+
return results;
|
|
2049
|
+
}
|
|
2050
|
+
function extractVectorSimilarityPredicates(predicates) {
|
|
2051
|
+
return extractStructuralPredicates(
|
|
2052
|
+
predicates,
|
|
2053
|
+
(expr) => expr.__type === "vector_similarity",
|
|
2054
|
+
"Vector similarity predicates cannot be nested under OR or NOT. Use top-level AND combinations instead."
|
|
2055
|
+
);
|
|
2056
|
+
}
|
|
2057
|
+
function extractFulltextMatchPredicates(predicates) {
|
|
2058
|
+
return extractStructuralPredicates(
|
|
2059
|
+
predicates,
|
|
2060
|
+
(expr) => expr.__type === "fulltext_match",
|
|
2061
|
+
"Fulltext match predicates cannot be nested under OR or NOT. Use top-level AND combinations instead."
|
|
2062
|
+
);
|
|
2063
|
+
}
|
|
2064
|
+
|
|
2065
|
+
// src/query/compiler/predicate-utils.ts
|
|
2066
|
+
var EMPTY_PREDICATES = [];
|
|
2067
|
+
function sqlValueList(values) {
|
|
2068
|
+
return sql.join(
|
|
2069
|
+
values.map((value) => sql`${value}`),
|
|
2070
|
+
sql`, `
|
|
2071
|
+
);
|
|
2072
|
+
}
|
|
2073
|
+
function buildPredicateIndexKey(alias, targetType) {
|
|
2074
|
+
return `${alias}\0${targetType}`;
|
|
2075
|
+
}
|
|
2076
|
+
function resolvePredicateTargetType(predicate2) {
|
|
2077
|
+
return predicate2.targetType === "edge" ? "edge" : "node";
|
|
2078
|
+
}
|
|
2079
|
+
function buildPredicateIndex(ast) {
|
|
2080
|
+
const byAliasAndType = /* @__PURE__ */ new Map();
|
|
2081
|
+
for (const predicate2 of ast.predicates) {
|
|
2082
|
+
const key = buildPredicateIndexKey(
|
|
2083
|
+
predicate2.targetAlias,
|
|
2084
|
+
resolvePredicateTargetType(predicate2)
|
|
2085
|
+
);
|
|
2086
|
+
const existing = byAliasAndType.get(key);
|
|
2087
|
+
if (existing === void 0) {
|
|
2088
|
+
byAliasAndType.set(key, [predicate2]);
|
|
2089
|
+
} else {
|
|
2090
|
+
existing.push(predicate2);
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
return { byAliasAndType };
|
|
2094
|
+
}
|
|
2095
|
+
function getPredicatesForAlias(predicateIndex, alias, targetType) {
|
|
2096
|
+
return predicateIndex.byAliasAndType.get(
|
|
2097
|
+
buildPredicateIndexKey(alias, targetType)
|
|
2098
|
+
) ?? EMPTY_PREDICATES;
|
|
2099
|
+
}
|
|
2100
|
+
function compilePredicateClauses(predicates, predicateContext) {
|
|
2101
|
+
return predicates.map(
|
|
2102
|
+
(predicate2) => compilePredicateExpression(predicate2.expression, predicateContext)
|
|
2103
|
+
);
|
|
2104
|
+
}
|
|
2105
|
+
function compileKindFilter(column, kinds) {
|
|
2106
|
+
if (kinds.length === 0) {
|
|
2107
|
+
return sql`1 = 0`;
|
|
2108
|
+
}
|
|
2109
|
+
if (kinds.length === 1) {
|
|
2110
|
+
return sql`${column} = ${kinds[0]}`;
|
|
2111
|
+
}
|
|
2112
|
+
return sql`${column} IN (${sqlValueList(kinds)})`;
|
|
2113
|
+
}
|
|
2114
|
+
function getNodeKindsForAlias(ast, alias) {
|
|
2115
|
+
if (alias === ast.start.alias) {
|
|
2116
|
+
return ast.start.kinds;
|
|
2117
|
+
}
|
|
2118
|
+
for (const traversal of ast.traversals) {
|
|
2119
|
+
if (traversal.nodeAlias === alias) {
|
|
2120
|
+
return traversal.nodeKinds;
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
throw new CompilerInvariantError(`Unknown traversal source alias: ${alias}`);
|
|
2124
|
+
}
|
|
2125
|
+
function getHybridTargetAlias(vectorPredicate, fulltextPredicate) {
|
|
2126
|
+
if (!vectorPredicate || !fulltextPredicate) return void 0;
|
|
2127
|
+
return vectorPredicate.field.alias === fulltextPredicate.field.alias ? vectorPredicate.field.alias : void 0;
|
|
2128
|
+
}
|
|
2129
|
+
|
|
800
2130
|
// src/store/row-fetch.ts
|
|
801
2131
|
async function getRowsByIds(ids, policy) {
|
|
802
2132
|
const rowsById = /* @__PURE__ */ new Map();
|
|
@@ -819,7 +2149,7 @@ async function getRowsByIds(ids, policy) {
|
|
|
819
2149
|
// src/store/edge-fetch.ts
|
|
820
2150
|
async function getEdgeRowsByIds(backend, graphId, ids) {
|
|
821
2151
|
return getRowsByIds(ids, {
|
|
822
|
-
batch: backend.getEdges === void 0 ? void 0 : (batchIds) => backend.getEdges(graphId, batchIds),
|
|
2152
|
+
batch: backend.getEdges === void 0 ? void 0 : (batchIds) => requireDefined(backend.getEdges)(graphId, batchIds),
|
|
823
2153
|
one: (id) => backend.getEdge(graphId, id)
|
|
824
2154
|
});
|
|
825
2155
|
}
|
|
@@ -827,10 +2157,12 @@ async function getEdgeRowsByIds(backend, graphId, ids) {
|
|
|
827
2157
|
// src/store/node-fetch.ts
|
|
828
2158
|
async function getNodeRowsByIds(backend, graphId, kind, ids) {
|
|
829
2159
|
return getRowsByIds(ids, {
|
|
830
|
-
batch: backend.getNodes === void 0 ? void 0 : (batchIds) => backend.getNodes(graphId, kind, batchIds),
|
|
2160
|
+
batch: backend.getNodes === void 0 ? void 0 : (batchIds) => requireDefined(backend.getNodes)(graphId, kind, batchIds),
|
|
831
2161
|
one: (id) => backend.getNode(graphId, kind, id)
|
|
832
2162
|
});
|
|
833
2163
|
}
|
|
2164
|
+
|
|
2165
|
+
// src/store/recorded-capture/relations.ts
|
|
834
2166
|
var RECORDED_HISTORY_META = "{}";
|
|
835
2167
|
var RECORDED_NODE_COLUMNS = [
|
|
836
2168
|
"history_id",
|
|
@@ -894,6 +2226,9 @@ function recordedChunkSize(target, columnCount) {
|
|
|
894
2226
|
const budget = recordedBindParamBudget(target);
|
|
895
2227
|
return Math.max(1, Math.floor(budget / columnCount));
|
|
896
2228
|
}
|
|
2229
|
+
function sqlNull(value) {
|
|
2230
|
+
return value === void 0 ? sql.raw("NULL") : sql`${value}`;
|
|
2231
|
+
}
|
|
897
2232
|
function recordedCommonCells() {
|
|
898
2233
|
return {
|
|
899
2234
|
history_id: () => sql`${generateId()}`,
|
|
@@ -1416,7 +2751,7 @@ function createRecordedTransactionBackend(target, session, schema) {
|
|
|
1416
2751
|
async deleteEdgesBatch(params) {
|
|
1417
2752
|
session.assertOpen();
|
|
1418
2753
|
await lockGraph(params.graphId);
|
|
1419
|
-
await target.deleteEdgesBatch(params);
|
|
2754
|
+
await requireDefined(target.deleteEdgesBatch)(params);
|
|
1420
2755
|
for (const id of params.ids) {
|
|
1421
2756
|
session.touchEdge(params.graphId, id);
|
|
1422
2757
|
}
|
|
@@ -1426,7 +2761,7 @@ function createRecordedTransactionBackend(target, session, schema) {
|
|
|
1426
2761
|
async hardDeleteEdgesBatch(params) {
|
|
1427
2762
|
session.assertOpen();
|
|
1428
2763
|
await lockGraph(params.graphId);
|
|
1429
|
-
await target.hardDeleteEdgesBatch(params);
|
|
2764
|
+
await requireDefined(target.hardDeleteEdgesBatch)(params);
|
|
1430
2765
|
for (const id of params.ids) {
|
|
1431
2766
|
session.touchEdge(params.graphId, id);
|
|
1432
2767
|
}
|
|
@@ -1463,7 +2798,8 @@ async function runCapturedAutocommit(backend, schema, fn, options) {
|
|
|
1463
2798
|
function createRecordedBackend(backend, schema) {
|
|
1464
2799
|
assertCapturableBackend(backend);
|
|
1465
2800
|
const capture = (fn) => runCapturedAutocommit(backend, schema, fn);
|
|
1466
|
-
|
|
2801
|
+
const projectedBackend = createGraphBackendProjection(backend);
|
|
2802
|
+
return createBackendOverlay(projectedBackend, {
|
|
1467
2803
|
...rawWriteGuards(backend, "backend"),
|
|
1468
2804
|
async insertNode(params) {
|
|
1469
2805
|
return capture((target) => target.insertNode(params));
|
|
@@ -1533,12 +2869,16 @@ function createRecordedBackend(backend, schema) {
|
|
|
1533
2869
|
},
|
|
1534
2870
|
...backend.deleteEdgesBatch === void 0 ? {} : {
|
|
1535
2871
|
async deleteEdgesBatch(params) {
|
|
1536
|
-
await capture(
|
|
2872
|
+
await capture(
|
|
2873
|
+
(target) => requireDefined(target.deleteEdgesBatch)(params)
|
|
2874
|
+
);
|
|
1537
2875
|
}
|
|
1538
2876
|
},
|
|
1539
2877
|
...backend.hardDeleteEdgesBatch === void 0 ? {} : {
|
|
1540
2878
|
async hardDeleteEdgesBatch(params) {
|
|
1541
|
-
await capture(
|
|
2879
|
+
await capture(
|
|
2880
|
+
(target) => requireDefined(target.hardDeleteEdgesBatch)(params)
|
|
2881
|
+
);
|
|
1542
2882
|
}
|
|
1543
2883
|
},
|
|
1544
2884
|
async transaction(fn, options) {
|
|
@@ -1549,18 +2889,11 @@ function createRecordedBackend(backend, schema) {
|
|
|
1549
2889
|
await assertRecordedCaptureTransactionIsolation(target, backendOptions);
|
|
1550
2890
|
const readOnly = backendOptions?.accessMode === "read_only";
|
|
1551
2891
|
const scope = createRecordedTransactionScope(target, schema, !readOnly);
|
|
1552
|
-
const result = await fn(scope.backend
|
|
2892
|
+
const result = await fn(scope.backend);
|
|
1553
2893
|
const instants = await scope.flush();
|
|
1554
2894
|
observer?.(instants);
|
|
1555
2895
|
return result;
|
|
1556
2896
|
}, backendOptions);
|
|
1557
|
-
},
|
|
1558
|
-
...backend.adoptTransaction === void 0 ? {} : {
|
|
1559
|
-
adoptTransaction(externalTx) {
|
|
1560
|
-
throw recordedCaptureRequiresCallbackTransactionError({
|
|
1561
|
-
externalTxType: typeof externalTx
|
|
1562
|
-
});
|
|
1563
|
-
}
|
|
1564
2897
|
}
|
|
1565
2898
|
});
|
|
1566
2899
|
}
|
|
@@ -1823,8 +3156,8 @@ function checkWherePredicate(constraint, props) {
|
|
|
1823
3156
|
return true;
|
|
1824
3157
|
}
|
|
1825
3158
|
const predicateBuilder = buildPredicateContext(props);
|
|
1826
|
-
const
|
|
1827
|
-
return evaluatePredicate(
|
|
3159
|
+
const predicate2 = constraint.where(predicateBuilder);
|
|
3160
|
+
return evaluatePredicate(predicate2, props);
|
|
1828
3161
|
}
|
|
1829
3162
|
function buildPredicateContext(props) {
|
|
1830
3163
|
const context = {};
|
|
@@ -1844,11 +3177,11 @@ function buildPredicateContext(props) {
|
|
|
1844
3177
|
}
|
|
1845
3178
|
return context;
|
|
1846
3179
|
}
|
|
1847
|
-
function evaluatePredicate(
|
|
1848
|
-
if (typeof
|
|
3180
|
+
function evaluatePredicate(predicate2, props) {
|
|
3181
|
+
if (typeof predicate2 !== "object" || predicate2 === null || !("__type" in predicate2)) {
|
|
1849
3182
|
return true;
|
|
1850
3183
|
}
|
|
1851
|
-
const pred =
|
|
3184
|
+
const pred = predicate2;
|
|
1852
3185
|
if (pred.__type !== "unique_predicate") {
|
|
1853
3186
|
return true;
|
|
1854
3187
|
}
|
|
@@ -2159,7 +3492,7 @@ async function enforceNodeDeleteBehavior(ctx, args, backend, policy) {
|
|
|
2159
3492
|
case "disconnect": {
|
|
2160
3493
|
const batchDelete = args.mode === "hard" ? backend.hardDeleteEdgesBatch : backend.deleteEdgesBatch;
|
|
2161
3494
|
if (batchDelete !== void 0) {
|
|
2162
|
-
await batchDelete
|
|
3495
|
+
await batchDelete({
|
|
2163
3496
|
graphId: ctx.graphId,
|
|
2164
3497
|
ids: connectedEdges.map((edge) => edge.id)
|
|
2165
3498
|
});
|
|
@@ -2350,6 +3683,6 @@ async function applyNodeResurrect(ctx, args, backend) {
|
|
|
2350
3683
|
return row;
|
|
2351
3684
|
}
|
|
2352
3685
|
|
|
2353
|
-
export { ALIAS_CTE_PREFIX, DEFAULT_SQL_SCHEMA, EMBEDDINGS_CTE_ALIAS, FULLTEXT_CTE_ALIAS, HYBRID_CANDIDATES_CTE_ALIAS, advanceRevisionClock, applyNodeHardDelete, applyNodeInsertSideEffects, applyNodeInsertSideEffectsBatch, applyNodeResurrect, applyNodeSoftDelete, applyNodeUpdate,
|
|
2354
|
-
//# sourceMappingURL=chunk-
|
|
2355
|
-
//# sourceMappingURL=chunk-
|
|
3686
|
+
export { ALIAS_CTE_PREFIX, AUTO_REFRESH_STATISTICS_ROW_THRESHOLD, CURRENT_READ_INSTANT_PLACEHOLDER, DEFAULT_SQL_SCHEMA, EMBEDDINGS_CTE_ALIAS, FULLTEXT_CTE_ALIAS, HYBRID_CANDIDATES_CTE_ALIAS, STORE_RUNTIME, TRANSACTION_RUNTIME, advanceRevisionClock, applyNodeHardDelete, applyNodeInsertSideEffects, applyNodeInsertSideEffectsBatch, applyNodeResurrect, applyNodeSoftDelete, applyNodeUpdate, arrayField, assertRecordedCaptureTransactionIsolation, assertRevisionTrackableBackend, baseField, buildFieldBuilderForTypeInfo, buildPredicateIndex, checkCardinality, checkDisjointness, checkUniqueEdge, checkUniquenessConstraints, checkWherePredicate, closeRecordedHardDeletedKind, compileFieldValue, compileKindFilter, compilePredicateClauses, compilePredicateExpression, compileTemporalFilter, computeFulltextContent, computeUniqueKey, createFulltextAccessor, createGraphBackendProjection, createNodeWriteContext, createRecordedBackend, createRecordedReadBinding, createRecordedTransactionScope, createSqlSchema, createUniquenessContext, currentReadInstant, currentReadInstantFor, dateField, edgeInsertDispatch, ensureRevisionOrigin, exists, extractFulltextMatchPredicates, extractTemporalOptions, extractVectorSimilarityPredicates, fieldRef, generateId, getEdgeRowsByIds, getEmbeddingFields, getFieldPointer, getHybridTargetAlias, getKindsForUniquenessCheck, getNodeKindsForAlias, getNodeRowsByIds, getPredicatesForAlias, inSubquery, isParameterRef, lockRecordedGraphWrite, nodeInsertDispatch, notExists, notInSubquery, numberField, objectField, param, projectBackendMembers, readRecordedClock, readRevisionOrigin, recordedBindParamBudget, recordedCaptureRequiresCallbackTransactionError, recordedReadSchemaFor, recordedReadSqlSchema, recordedRelation, requireExternalRecordedReadSource, requireRecordedReadBinding, requireSqlSchema, runInsertBatch, runInsertBatchReturning, runInsertNoReturn, sqlValueList, storeBackend, storeRuntime, stringField, throwHistoryUnsafeSqlAccess, throwRevisionTrackingUnsafeSqlAccess, transactionBackend, transactionNodeOperationHookRunner, uncapturedGraphWriteLock, validateEdgeEndpoints, vectorSlotKey, withPinnedReadInstant, withRecordedFlushObserver };
|
|
3687
|
+
//# sourceMappingURL=chunk-IFDXG2YJ.js.map
|
|
3688
|
+
//# sourceMappingURL=chunk-IFDXG2YJ.js.map
|