okmodel 0.6.0 → 0.8.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 +100 -1131
- package/dist/adapters/capabilities.d.ts +35 -0
- package/dist/adapters/failure.d.ts +13 -2
- package/dist/adapters/lazy-errors.d.ts +22 -0
- package/dist/adapters/pg/bun-sql.d.ts +53 -0
- package/dist/adapters/pg/bunsql-extra.d.ts +54 -3
- package/dist/adapters/pg/bunsql.d.ts +15 -2
- package/dist/adapters/pg/cursor.d.ts +17 -0
- package/dist/adapters/pg/neon-extra.d.ts +18 -0
- package/dist/adapters/pg/neon.d.ts +104 -0
- package/dist/adapters/pg/no-inflight-timeout.d.ts +11 -8
- package/dist/adapters/pg/nodepostgres-extra.d.ts +22 -1
- package/dist/adapters/pg/nodepostgres.d.ts +12 -0
- package/dist/adapters/pg/pglite-wire.d.ts +24 -0
- package/dist/adapters/pg/pglite.d.ts +10 -0
- package/dist/adapters/pg/postgres-extra.d.ts +27 -11
- package/dist/adapters/pg/reserved.d.ts +42 -0
- package/dist/adapters/pg/session.d.ts +0 -18
- package/dist/contracts/connection.d.ts +7 -6
- package/dist/contracts/error.d.ts +1 -1
- package/dist/dialects/pg/floor.d.ts +68 -0
- package/dist/dialects/pg/fn/index.d.ts +39 -1
- package/dist/dialects/pg/fn/index.js +118 -26
- package/dist/dialects/pg/index.d.ts +8 -1
- package/dist/dialects/pg/index.js +435 -170
- package/dist/dialects/pg/introspect.d.ts +11 -0
- package/dist/dialects/pg/keys.d.ts +11 -8
- package/dist/dialects/pg/model.d.ts +40 -0
- package/dist/dialects/pg/morph.d.ts +43 -0
- package/dist/dialects/pg/operator-fit.d.ts +2 -2
- package/dist/dialects/pg/operators.d.ts +14 -7
- package/dist/dialects/pg/ops/bucket.d.ts +65 -0
- package/dist/dialects/pg/ops/fragment.d.ts +119 -0
- package/dist/dialects/pg/ops/inc.d.ts +2 -2
- package/dist/dialects/pg/ops/lane.d.ts +49 -0
- package/dist/dialects/pg/ops/matches.d.ts +9 -12
- package/dist/dialects/pg/ops/relevance.d.ts +13 -0
- package/dist/dialects/pg/ops/search-query.d.ts +22 -0
- package/dist/dialects/pg/ops/window.d.ts +103 -0
- package/dist/dialects/pg/preset.d.ts +1 -1
- package/dist/dialects/pg/relations.d.ts +100 -3
- package/dist/dialects/pg/schema.d.ts +31 -3
- package/dist/dialects/pg/view/client.d.ts +14 -6
- package/dist/dialects/pg/view/index.d.ts +73 -1
- package/dist/dialects/pg/view/index.js +156 -5
- package/dist/dialects/pg/view/scratch.d.ts +8 -5
- package/dist/runtime/aggregate.d.ts +8 -2
- package/dist/runtime/bucket-group.d.ts +70 -0
- package/dist/runtime/conflict.d.ts +22 -4
- package/dist/runtime/include.d.ts +0 -8
- package/dist/runtime/inflight.d.ts +1 -1
- package/dist/runtime/otel.d.ts +105 -0
- package/dist/runtime/otel.js +97 -0
- package/dist/runtime/page.d.ts +4 -1
- package/dist/runtime/pg/bun.js +12 -6
- package/dist/runtime/pg/neon.d.ts +38 -0
- package/dist/runtime/pg/neon.js +64 -0
- package/dist/runtime/pg/pg.js +5 -5
- package/dist/runtime/pg/pglite.d.ts +1 -0
- package/dist/runtime/pg/pglite.js +9 -9
- package/dist/runtime/pg/postgresjs.js +5 -5
- package/dist/runtime/plan.d.ts +95 -5
- package/dist/runtime/read-stream.d.ts +13 -16
- package/dist/runtime/result-name.d.ts +17 -0
- package/dist/runtime/server-check.d.ts +3 -3
- package/dist/runtime/sort-bind.d.ts +21 -0
- package/dist/runtime/sort.d.ts +56 -0
- package/dist/runtime/sql-fragment.d.ts +43 -0
- package/dist/runtime/sync.d.ts +70 -0
- package/dist/runtime/tenancy/index.js +15 -13
- package/dist/runtime/text-search.d.ts +20 -0
- package/dist/runtime/topology.d.ts +1 -1
- package/dist/runtime/traits/index.d.ts +80 -0
- package/dist/runtime/traits/index.js +184 -21
- package/dist/runtime/tree.d.ts +38 -0
- package/dist/runtime/types.d.ts +232 -22
- package/dist/runtime/validate/index.js +4 -4
- package/dist/runtime/version.d.ts +39 -0
- package/dist/runtime/window.d.ts +21 -0
- package/dist/runtime/write.d.ts +54 -2
- package/dist/shared/{929h19xp.js → 0wrea3jq.js} +141 -13
- package/dist/shared/{qq3899ht.js → 12z7aznj.js} +243 -14
- package/dist/shared/{1z04fa85.js → 14x60fbf.js} +12 -57
- package/dist/shared/{ek2wt2dz.js → 16kvjebh.js} +4 -4
- package/dist/shared/{wynzeggs.js → 195pzzzz.js} +8 -8
- package/dist/shared/1d9q9cv2.js +312 -0
- package/dist/shared/2c13q96h.js +18 -0
- package/dist/shared/{b4v57v3x.js → 2d3xq4ps.js} +2 -2
- package/dist/shared/{1f0xa3cb.js → 3449rcae.js} +5 -5
- package/dist/shared/{wkme6tep.js → 35q0n9tz.js} +8 -16
- package/dist/shared/3bb7wsqt.js +99 -0
- package/dist/shared/3t6kw83m.js +249 -0
- package/dist/shared/{5j36z8dn.js → 4m6hskg8.js} +39 -70
- package/dist/shared/{n076ydsc.js → 4vbf83xx.js} +69 -28
- package/dist/shared/{vmfkhszw.js → 63f4ksbz.js} +33 -26
- package/dist/shared/{c58secgj.js → 63qtkrca.js} +38 -4
- package/dist/shared/6m78c8ss.js +6 -0
- package/dist/shared/{x3jc53kg.js → 760ppr76.js} +15 -7
- package/dist/shared/7ghwamrf.js +40 -0
- package/dist/shared/7kms6fvj.js +20 -0
- package/dist/shared/7n7ddwt4.js +6 -0
- package/dist/shared/9a4ae4p8.js +31 -0
- package/dist/shared/{hazqqecq.js → 9dr2qnx7.js} +63 -34
- package/dist/shared/{h15jx9bc.js → 9dvh1dr6.js} +1 -1
- package/dist/shared/a62rb2da.js +13 -0
- package/dist/shared/{cgbamx3e.js → ae4j5f42.js} +23 -4
- package/dist/shared/agsfb86s.js +233 -0
- package/dist/shared/{8x72s86k.js → b6d6p0zc.js} +13 -7
- package/dist/shared/{ag4c7516.js → b76b8d95.js} +2 -2
- package/dist/shared/{j60w0dvr.js → bah9nbg3.js} +58 -38
- package/dist/shared/bnby0esn.js +10 -0
- package/dist/shared/bsek72fg.js +225 -0
- package/dist/shared/{2cg3wnxc.js → bxas03mq.js} +608 -141
- package/dist/shared/{31vm914h.js → cm3w0ywp.js} +15 -16
- package/dist/shared/{gwn6v667.js → cnkky55j.js} +25 -14
- package/dist/shared/{dk8v79p3.js → d5nmj7vv.js} +1 -1
- package/dist/shared/{ttmg09vd.js → dpc2r7rb.js} +8 -8
- package/dist/shared/dzj09cye.js +10 -0
- package/dist/shared/{sbdme3vy.js → e8zyaqvj.js} +60 -10
- package/dist/shared/{2jd1sn0e.js → ecn8mfdq.js} +6 -6
- package/dist/shared/exn3sd90.js +359 -0
- package/dist/shared/{t3g0k88x.js → f4jy1j7x.js} +39 -22
- package/dist/shared/{y2t3jktd.js → fjpnhqan.js} +20 -13
- package/dist/shared/g5yc06ka.js +272 -0
- package/dist/shared/ga9j92qj.js +25 -0
- package/dist/shared/{3fqwmr09.js → hfqmpasr.js} +6 -6
- package/dist/shared/{wt5rzv1h.js → hm5f8jby.js} +7 -7
- package/dist/shared/{ys0xzyaj.js → hqpxf4a4.js} +224 -19
- package/dist/shared/jebgrkeq.js +179 -0
- package/dist/shared/{09p049xa.js → jp36k7dp.js} +44 -16
- package/dist/shared/jx2m62cs.js +96 -0
- package/dist/shared/{r11n8grd.js → k86n8vq3.js} +7 -4
- package/dist/shared/{2z7wv5tj.js → kgwp4jdd.js} +56 -35
- package/dist/shared/{knmes2kh.js → kj9d8maq.js} +1 -1
- package/dist/shared/{g90m9b0g.js → m4xff2a6.js} +6 -5
- package/dist/shared/{r6nwkxnt.js → m7n9h2a5.js} +4 -4
- package/dist/shared/mfedzr74.js +145 -0
- package/dist/shared/{f0f1n281.js → mkrn359n.js} +60 -11
- package/dist/shared/{p248q79y.js → mnvjvqyp.js} +10 -10
- package/dist/shared/{672t5vym.js → mss6ctgv.js} +2 -2
- package/dist/shared/{4az561fn.js → mtw6jz76.js} +8 -23
- package/dist/shared/n05z9nwz.js +313 -0
- package/dist/shared/{pjr6xrm5.js → n0jmpgj1.js} +20 -17
- package/dist/shared/{p6bjzq9q.js → n41w4fbz.js} +14 -6
- package/dist/shared/{b3awxn7h.js → n454kcnw.js} +1 -1
- package/dist/shared/n7kg8mmx.js +61 -0
- package/dist/shared/nbw1z4yd.js +18 -0
- package/dist/shared/needfe47.js +66 -0
- package/dist/shared/{1nw1f3vs.js → njga14v4.js} +9 -9
- package/dist/shared/{5yv4k6a6.js → nmnsgj7x.js} +145 -3
- package/dist/shared/{vjpnzwjz.js → p3xbdcvt.js} +14 -18
- package/dist/shared/p5nh3r8q.js +622 -0
- package/dist/shared/{nx9hh281.js → pan0370z.js} +13 -12
- package/dist/shared/q0cqt2sp.js +12 -0
- package/dist/shared/qd9hhd8f.js +37 -0
- package/dist/shared/{mb2ycs1p.js → qfw14tna.js} +15 -15
- package/dist/shared/{9s0ypp87.js → sjk86yrx.js} +1 -1
- package/dist/shared/th3be82n.js +208 -0
- package/dist/shared/{ed0b8k4s.js → typ3vy7t.js} +1 -1
- package/dist/shared/{5d8t84hg.js → v1wad97q.js} +14 -14
- package/dist/shared/{x72jb7ad.js → v8g1vgv8.js} +1 -1
- package/dist/shared/{9628a9xt.js → vk7rag46.js} +1 -1
- package/dist/shared/{ze4hxsmy.js → w9ejzaqf.js} +1 -1
- package/dist/shared/{q3j1tq7a.js → wcrheftc.js} +148 -23
- package/dist/shared/wvdjznah.js +213 -0
- package/dist/shared/wz2a78mp.js +8 -0
- package/dist/shared/xfhe73sb.js +436 -0
- package/dist/shared/{r1fdd0f6.js → z581d7ny.js} +5 -2
- package/dist/shared/{8etn7d8w.js → z7s6fpxv.js} +1 -1
- package/dist/shared/{32cnm7kn.js → zbqbmmrp.js} +76 -40
- package/dist/shared/{n7mcc1gk.js → zchaghkf.js} +4 -3
- package/dist/shared/{xq0mvhts.js → zgex00fd.js} +6 -6
- package/dist/shared/{nsva2a6b.js → znm0bpp5.js} +3 -0
- package/dist/shared/zq1he88x.js +155 -0
- package/dist/tooling/cli.js +26 -13
- package/dist/tooling/driver-run.js +4971 -0
- package/dist/tooling/driver-test.d.ts +36 -0
- package/dist/tooling/migrate/commands.d.ts +2 -2
- package/dist/tooling/migrate/engine.d.ts +3 -2
- package/dist/tooling/migrate/index.js +9 -9
- package/dist/tooling/migrate/project.d.ts +3 -0
- package/dist/tooling/shared/03k6res6.js +210 -0
- package/dist/tooling/shared/08kemxjd.js +10 -0
- package/dist/tooling/shared/2revefqt.js +209 -0
- package/dist/tooling/shared/2wtvc7rw.js +1425 -0
- package/dist/tooling/shared/345tbc2k.js +16 -0
- package/dist/tooling/shared/3m1hkg7z.js +344 -0
- package/dist/tooling/shared/3rrw5w8f.js +81 -0
- package/dist/tooling/shared/3tq8pnb8.js +131 -0
- package/dist/tooling/shared/417zdsk7.js +194 -0
- package/dist/tooling/shared/4d2w25vw.js +40 -0
- package/dist/tooling/shared/54tqkxja.js +51 -0
- package/dist/tooling/shared/5bvw2nev.js +12 -0
- package/dist/tooling/shared/6nyfyw70.js +231 -0
- package/dist/tooling/shared/72fyg4zv.js +160 -0
- package/dist/tooling/shared/733a1tq3.js +38 -0
- package/dist/tooling/shared/7ae7rjmn.js +20 -0
- package/dist/tooling/shared/7kms6fvj.js +20 -0
- package/dist/tooling/shared/8sqrsw3s.js +49 -0
- package/dist/tooling/shared/96ps4g1z.js +32 -0
- package/dist/tooling/shared/9kazs5p6.js +195 -0
- package/dist/tooling/shared/9xzm7hjg.js +38 -0
- package/dist/tooling/shared/a6pp9d12.js +49 -0
- package/dist/tooling/shared/a7q7t4n3.js +22 -0
- package/dist/tooling/shared/aftb2mwr.js +18 -0
- package/dist/tooling/shared/bz2dqhab.js +311 -0
- package/dist/tooling/shared/cmptmb4f.js +12 -0
- package/dist/tooling/shared/ddjtfgnx.js +177 -0
- package/dist/tooling/shared/djydjpqt.js +261 -0
- package/dist/tooling/shared/dw08f3m8.js +9 -0
- package/dist/tooling/shared/dy672fz6.js +16 -0
- package/dist/tooling/shared/dzx85q70.js +66 -0
- package/dist/tooling/shared/ec71zqgt.js +270 -0
- package/dist/{shared/d5azex6s.js → tooling/shared/ep8zh3bk.js} +1 -1
- package/dist/tooling/shared/f9mphxej.js +3789 -0
- package/dist/tooling/shared/fb9k2qwd.js +89 -0
- package/dist/tooling/shared/g9ad4n80.js +211 -0
- package/dist/tooling/shared/gfvtj6d0.js +94 -0
- package/dist/tooling/shared/gmcf9cxf.js +294 -0
- package/dist/tooling/shared/htnaj77v.js +17 -0
- package/dist/tooling/shared/j9t5s12a.js +7 -0
- package/dist/tooling/shared/jne7b93p.js +42 -0
- package/dist/tooling/shared/ma2340rx.js +118 -0
- package/dist/tooling/shared/mtrqn2hn.js +505 -0
- package/dist/tooling/shared/n4jqhpqz.js +27 -0
- package/dist/tooling/shared/nf7jmhfa.js +20 -0
- package/dist/tooling/shared/p7f08ktn.js +332 -0
- package/dist/tooling/shared/ppnnnvj8.js +13 -0
- package/dist/tooling/shared/pqy21k24.js +312 -0
- package/dist/tooling/shared/pw8fgahx.js +69 -0
- package/dist/tooling/shared/pwsytxm5.js +17 -0
- package/dist/tooling/shared/rf83gr2d.js +94 -0
- package/dist/tooling/shared/rq5kk8j6.js +401 -0
- package/dist/tooling/shared/rs1jb051.js +12 -0
- package/dist/tooling/shared/smn6kz1p.js +157 -0
- package/dist/tooling/shared/spk1jg3r.js +1696 -0
- package/dist/tooling/shared/tn8gay14.js +143 -0
- package/dist/tooling/shared/vraj6d74.js +42 -0
- package/dist/tooling/shared/vs0t6qt8.js +64 -0
- package/dist/tooling/shared/vx86qjv8.js +150 -0
- package/dist/tooling/shared/w7qe8sj1.js +140 -0
- package/dist/tooling/shared/wt7j7nf6.js +15 -0
- package/dist/tooling/shared/wwnekq5n.js +6 -0
- package/dist/tooling/shared/xhrnjch9.js +185 -0
- package/dist/tooling/shared/xjs6zqtc.js +190 -0
- package/dist/tooling/shared/y031jct9.js +16 -0
- package/dist/tooling/shared/y5656f0e.js +233 -0
- package/dist/tooling/shared/yfr8hzhm.js +604 -0
- package/dist/tooling/shared/yk9mp7vb.js +250 -0
- package/dist/tooling/shared/yw30vnq2.js +139 -0
- package/dist/tooling/shared/z8d7ptht.js +618 -0
- package/dist/tooling/shared/zhwnfyb2.js +9 -0
- package/dist/tooling/shared/zvnhh1n0.js +198 -0
- package/dist/tooling/testing/index.js +3 -3
- package/package.json +17 -3
- package/dist/shared/3qnhc7w5.js +0 -38
- package/dist/shared/7m88x3e9.js +0 -45
- package/dist/shared/8dqhth8c.js +0 -12
- package/dist/shared/j3rkk835.js +0 -99
- package/dist/shared/k68eedmy.js +0 -85
- package/dist/shared/venqrjna.js +0 -216
- package/dist/shared/wxr8cwns.js +0 -6
- package/dist/shared/y34a8714.js +0 -150
- package/dist/shared/zm0mafk4.js +0 -92
- package/dist/shared/zy8r7qvz.js +0 -116
- package/dist/shared/{ywr8hmey.js → 606g0nbf.js} +3 -3
- package/dist/shared/{rpycarcr.js → gcefca6p.js} +4 -4
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import {
|
|
2
|
+
stack2
|
|
3
|
+
} from "./mss6ctgv.js";
|
|
4
|
+
import {
|
|
5
|
+
updateSliceBody2,
|
|
6
|
+
rejectDuplicateTargets2,
|
|
7
|
+
emitSet2,
|
|
8
|
+
Sql2,
|
|
9
|
+
writeSet2,
|
|
10
|
+
rejectMixedSets2,
|
|
11
|
+
readClaim2,
|
|
12
|
+
rejectUpdateKeys2,
|
|
13
|
+
requireFilter2,
|
|
14
|
+
returningOption2,
|
|
15
|
+
expectOf2,
|
|
16
|
+
allowSet2,
|
|
17
|
+
noteGuarded2
|
|
18
|
+
} from "./bxas03mq.js";
|
|
19
|
+
import {
|
|
20
|
+
emitWhere,
|
|
21
|
+
projectExpr,
|
|
22
|
+
quote,
|
|
23
|
+
isRecord,
|
|
24
|
+
fail2
|
|
25
|
+
} from "./kgwp4jdd.js";
|
|
26
|
+
|
|
27
|
+
// src/runtime/version.ts
|
|
28
|
+
function planVersioned(schema, table, input, options, mods) {
|
|
29
|
+
if (mods.all !== undefined) {
|
|
30
|
+
fail2("OKM1120", `update on ${table.model.name} cannot use .all() with versioned().`, "Pass a per-row list with the version you read for each row.");
|
|
31
|
+
}
|
|
32
|
+
const allow = allowSet2(table, options.allow);
|
|
33
|
+
noteGuarded2(table, allow, "update");
|
|
34
|
+
const column = versionColumn(table);
|
|
35
|
+
const returning = returningOption2(table, options.returning);
|
|
36
|
+
const expect = expectOf2(options, mods);
|
|
37
|
+
if (Array.isArray(input) && input.length === 0) {
|
|
38
|
+
return {
|
|
39
|
+
statements: [],
|
|
40
|
+
outputs: outputsOf(undefined),
|
|
41
|
+
shape: "count",
|
|
42
|
+
expect,
|
|
43
|
+
versioned: { fields: [], sent: [] }
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const rows = readRows(schema, table, input, allow, mods, column);
|
|
47
|
+
const fields = writtenFields(rows);
|
|
48
|
+
const sent = rows.map((row) => row.version);
|
|
49
|
+
const claim = Array.isArray(input) ? undefined : isRecord(input) ? readClaim2(input) : undefined;
|
|
50
|
+
const statement = claim !== undefined ? claimStatement(schema, table, rows[0], claim, column, returning) : targetStatement(schema, table, rows, column, returning);
|
|
51
|
+
const width = statement.params?.length ?? 0;
|
|
52
|
+
if (width > 30000) {
|
|
53
|
+
fail2("OKM1120", `update on ${table.model.name} is too large to check version in one statement.`, "Split the list.");
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
statements: [statement],
|
|
57
|
+
outputs: outputsOf(returning),
|
|
58
|
+
shape: returning === undefined ? "count" : "rows",
|
|
59
|
+
expect,
|
|
60
|
+
versioned: { fields, sent }
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function versionColumn(table) {
|
|
64
|
+
const column = table.columns.get("version");
|
|
65
|
+
if (column === undefined) {
|
|
66
|
+
fail2("OKM1120", `Table ${table.model.name} is versioned and has no version column.`);
|
|
67
|
+
}
|
|
68
|
+
return column;
|
|
69
|
+
}
|
|
70
|
+
function readRows(schema, table, input, allow, mods, column) {
|
|
71
|
+
if (Array.isArray(input)) {
|
|
72
|
+
if (input.length === 0)
|
|
73
|
+
fail2("OKM1120", "update set is empty.");
|
|
74
|
+
const rows = input.map((item) => readRow(schema, table, item, allow, mods, column, true));
|
|
75
|
+
rejectDuplicateTargets2(table, rows);
|
|
76
|
+
rejectMixedSets2(rows);
|
|
77
|
+
return rows;
|
|
78
|
+
}
|
|
79
|
+
return [readRow(schema, table, input, allow, mods, column, false)];
|
|
80
|
+
}
|
|
81
|
+
function readRow(schema, table, input, allow, mods, column, row) {
|
|
82
|
+
if (!isRecord(input))
|
|
83
|
+
fail2("OKM1121", "update expects { where, set, version } or a list of rows.");
|
|
84
|
+
rejectUpdateKeys2(input, row);
|
|
85
|
+
if (!Object.hasOwn(input, "version")) {
|
|
86
|
+
fail2("OKM1120", `update on ${table.model.name} needs the version you read.`, "Pass version from the row you read. If this write conflicts, reread and retry.");
|
|
87
|
+
}
|
|
88
|
+
const version = readVersion(input.version, table.model.name, column);
|
|
89
|
+
const set = writeSet2(table, input.set, allow, schema.tenancy);
|
|
90
|
+
if (Object.keys(set).length === 0)
|
|
91
|
+
fail2("OKM1120", "update set is empty.");
|
|
92
|
+
refusePath(schema, table, set);
|
|
93
|
+
const where = input.where !== undefined ? input.where : input.id !== undefined ? { id: input.id } : undefined;
|
|
94
|
+
requireFilter2(table, where, mods, "update");
|
|
95
|
+
return { where: stack2(where, mods.presets), set, version };
|
|
96
|
+
}
|
|
97
|
+
function readVersion(value, table, column) {
|
|
98
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value)) {
|
|
99
|
+
fail2("OKM1121", `version on ${table} must be an integer.`, "Pass the version you read.");
|
|
100
|
+
}
|
|
101
|
+
column.encode(value);
|
|
102
|
+
return value;
|
|
103
|
+
}
|
|
104
|
+
function refusePath(schema, table, set) {
|
|
105
|
+
if (schema.tenancy?.isPath?.(table.model.name) !== true)
|
|
106
|
+
return;
|
|
107
|
+
const field = schema.tenancy.pathOf?.(table.model.name)?.[0]?.localField;
|
|
108
|
+
if (field === undefined || !Object.hasOwn(set, field))
|
|
109
|
+
return;
|
|
110
|
+
fail2("OKM1120", `update on ${table.model.name} cannot change ${field} and check version in one write.`, "Point it at a parent in a later update.");
|
|
111
|
+
}
|
|
112
|
+
function writtenFields(rows) {
|
|
113
|
+
const names = [];
|
|
114
|
+
for (const row of rows) {
|
|
115
|
+
for (const key of Object.keys(row.set))
|
|
116
|
+
if (!names.includes(key))
|
|
117
|
+
names.push(key);
|
|
118
|
+
}
|
|
119
|
+
return names;
|
|
120
|
+
}
|
|
121
|
+
function targetStatement(schema, table, rows, column, returning) {
|
|
122
|
+
const sql = new Sql2;
|
|
123
|
+
sql.text("with ");
|
|
124
|
+
for (let index = 0;index < rows.length; index += 1) {
|
|
125
|
+
const row = rows[index];
|
|
126
|
+
if (row === undefined)
|
|
127
|
+
continue;
|
|
128
|
+
if (index > 0)
|
|
129
|
+
sql.text(", ");
|
|
130
|
+
sql.text("m");
|
|
131
|
+
sql.text(String(index));
|
|
132
|
+
sql.text(" as (select s.ctid as tid, s.tableoid as toid, s.");
|
|
133
|
+
sql.text(quote(column.sql));
|
|
134
|
+
sql.text(" as okm_version from ");
|
|
135
|
+
sql.text(quote(table.model.sql));
|
|
136
|
+
sql.text(" as s");
|
|
137
|
+
emitWhere(schema, table, row.where, sql.sink(), "s", 0);
|
|
138
|
+
sql.text(" for update of s)");
|
|
139
|
+
}
|
|
140
|
+
sql.text(", gate as (select count(*)::int as n from (");
|
|
141
|
+
for (let index = 0;index < rows.length; index += 1) {
|
|
142
|
+
const row = rows[index];
|
|
143
|
+
if (row === undefined)
|
|
144
|
+
continue;
|
|
145
|
+
if (index > 0)
|
|
146
|
+
sql.text(" union all ");
|
|
147
|
+
sql.text("select 1 from m");
|
|
148
|
+
sql.text(String(index));
|
|
149
|
+
sql.text(" where okm_version is distinct from ");
|
|
150
|
+
sql.param(column.encode(row.version), column.dataType);
|
|
151
|
+
}
|
|
152
|
+
sql.text(") as okm_diff), updated as (");
|
|
153
|
+
updateSliceBody2(schema, table, rows, sql, true, {
|
|
154
|
+
afterWhere(body, index) {
|
|
155
|
+
const row = rows[index];
|
|
156
|
+
if (row === undefined)
|
|
157
|
+
return;
|
|
158
|
+
body.text(" and t.");
|
|
159
|
+
body.text(quote(column.sql));
|
|
160
|
+
body.text(" = ");
|
|
161
|
+
body.param(column.encode(row.version), column.dataType);
|
|
162
|
+
},
|
|
163
|
+
afterSet(body) {
|
|
164
|
+
bump(body, column);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
sql.text(" and (select n from gate) = 0");
|
|
168
|
+
closeUpdated(sql, returning, "gate");
|
|
169
|
+
return sql.statement();
|
|
170
|
+
}
|
|
171
|
+
function claimStatement(schema, table, row, limit, column, returning) {
|
|
172
|
+
if (row === undefined)
|
|
173
|
+
fail2("OKM1120", "update set is empty.");
|
|
174
|
+
const sql = new Sql2;
|
|
175
|
+
sql.text("with claimed as (select s.tableoid as toid, s.ctid as tid from ");
|
|
176
|
+
sql.text(quote(table.model.sql));
|
|
177
|
+
sql.text(" as s");
|
|
178
|
+
emitWhere(schema, table, row.where, sql.sink(), "s", 0);
|
|
179
|
+
sql.text(" and s.");
|
|
180
|
+
sql.text(quote(column.sql));
|
|
181
|
+
sql.text(" = ");
|
|
182
|
+
sql.param(column.encode(row.version), column.dataType);
|
|
183
|
+
sql.text(" for update of s skip locked limit ");
|
|
184
|
+
sql.param(String(limit), "integer");
|
|
185
|
+
sql.text("), stale_free as (select 1 as hit from ");
|
|
186
|
+
sql.text(quote(table.model.sql));
|
|
187
|
+
sql.text(" as s");
|
|
188
|
+
emitWhere(schema, table, row.where, sql.sink(), "s", 0);
|
|
189
|
+
sql.text(" and s.");
|
|
190
|
+
sql.text(quote(column.sql));
|
|
191
|
+
sql.text(" is distinct from ");
|
|
192
|
+
sql.param(column.encode(row.version), column.dataType);
|
|
193
|
+
sql.text(" for update of s skip locked limit 1), updated as (update ");
|
|
194
|
+
sql.text(quote(table.model.sql));
|
|
195
|
+
sql.text(" as t set ");
|
|
196
|
+
emitSet2(sql, table, row.set, "t");
|
|
197
|
+
bump(sql, column);
|
|
198
|
+
sql.text(" where (t.tableoid, t.ctid) in (select toid, tid from claimed)");
|
|
199
|
+
closeUpdated(sql, returning, "claim");
|
|
200
|
+
return sql.statement();
|
|
201
|
+
}
|
|
202
|
+
function bump(sql, column) {
|
|
203
|
+
sql.text(", ");
|
|
204
|
+
sql.text(quote(column.sql));
|
|
205
|
+
sql.text(" = t.");
|
|
206
|
+
sql.text(quote(column.sql));
|
|
207
|
+
sql.text(" + 1");
|
|
208
|
+
}
|
|
209
|
+
function closeUpdated(sql, returning, source) {
|
|
210
|
+
const stale = source === "gate" ? "(select n from gate)" : "(case when (select count(*) from updated) > 0 then 0 else (select count(*)::int from stale_free) end)";
|
|
211
|
+
if (returning === undefined || returning.length === 0) {
|
|
212
|
+
sql.text(" returning 1) select ");
|
|
213
|
+
sql.text(stale);
|
|
214
|
+
sql.text(", (select count(*)::int from updated)");
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
sql.text(" returning t.ctid as okm_tid");
|
|
218
|
+
for (let index = 0;index < returning.length; index += 1) {
|
|
219
|
+
const column = returning[index];
|
|
220
|
+
if (column === undefined)
|
|
221
|
+
continue;
|
|
222
|
+
sql.text(", ");
|
|
223
|
+
sql.text(projectExpr(`t.${quote(column.sql)}`, column.dataType));
|
|
224
|
+
sql.text(" as okm_");
|
|
225
|
+
sql.text(String(index));
|
|
226
|
+
}
|
|
227
|
+
sql.text(") select ");
|
|
228
|
+
sql.text(stale);
|
|
229
|
+
sql.text(", case when u.okm_tid is null then 0 else 1 end");
|
|
230
|
+
for (let index = 0;index < returning.length; index += 1) {
|
|
231
|
+
sql.text(", u.okm_");
|
|
232
|
+
sql.text(String(index));
|
|
233
|
+
}
|
|
234
|
+
sql.text(" from (select 1) as okm_one left join updated u on true");
|
|
235
|
+
}
|
|
236
|
+
function outputsOf(columns) {
|
|
237
|
+
const list = columns ?? [];
|
|
238
|
+
return {
|
|
239
|
+
fields: list.map((column, index) => ({
|
|
240
|
+
key: column.field,
|
|
241
|
+
at: index + 2,
|
|
242
|
+
decode: column.decode
|
|
243
|
+
})),
|
|
244
|
+
includes: []
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
export {
|
|
248
|
+
planVersioned
|
|
249
|
+
};
|
|
@@ -1,28 +1,26 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "./
|
|
2
|
+
noTimeout
|
|
3
|
+
} from "./q0cqt2sp.js";
|
|
4
4
|
import {
|
|
5
5
|
PGLITE_CAPABILITIES,
|
|
6
6
|
driverErrors,
|
|
7
7
|
rejectClosed,
|
|
8
8
|
rejectCancelled,
|
|
9
9
|
rejectTimedOut,
|
|
10
|
-
mapFailure,
|
|
11
10
|
nextTransactionDepth,
|
|
12
11
|
runCall,
|
|
13
12
|
EMPTY_NOTICES,
|
|
14
13
|
resultFrom
|
|
15
|
-
} from "./
|
|
14
|
+
} from "./ae4j5f42.js";
|
|
16
15
|
|
|
17
16
|
// src/adapters/pg/pglite.ts
|
|
18
17
|
import { PGlite } from "@electric-sql/pglite";
|
|
19
|
-
var RESET_ALL = "RESET ALL";
|
|
20
|
-
var UNLOCK = "SELECT pg_advisory_unlock_all()";
|
|
21
18
|
async function open3(config = {}) {
|
|
19
|
+
const wire = await import("./needfe47.js");
|
|
22
20
|
const db = new PGlite({
|
|
23
21
|
dataDir: config.dataDir ?? "memory://",
|
|
24
|
-
parsers:
|
|
25
|
-
serializers:
|
|
22
|
+
parsers: wire.parsers,
|
|
23
|
+
serializers: wire.serializers
|
|
26
24
|
});
|
|
27
25
|
await db.waitReady;
|
|
28
26
|
const acquireMs = config.timeouts?.acquire;
|
|
@@ -30,8 +28,8 @@ async function open3(config = {}) {
|
|
|
30
28
|
const notices = noticeBuffer();
|
|
31
29
|
const queryOptions = {
|
|
32
30
|
rowMode: "array",
|
|
33
|
-
parsers:
|
|
34
|
-
serializers:
|
|
31
|
+
parsers: wire.parsers,
|
|
32
|
+
serializers: wire.serializers,
|
|
35
33
|
onNotice(notice) {
|
|
36
34
|
notices.push(notice);
|
|
37
35
|
}
|
|
@@ -42,7 +40,7 @@ async function open3(config = {}) {
|
|
|
42
40
|
inflight += 1;
|
|
43
41
|
}, () => {
|
|
44
42
|
inflight = Math.max(0, inflight - 1);
|
|
45
|
-
});
|
|
43
|
+
}, (error) => wire.fail(error));
|
|
46
44
|
async function lease() {
|
|
47
45
|
if (closed)
|
|
48
46
|
return rejectClosed();
|
|
@@ -50,13 +48,17 @@ async function open3(config = {}) {
|
|
|
50
48
|
let released = false;
|
|
51
49
|
return {
|
|
52
50
|
execute: (text, params, options) => {
|
|
53
|
-
|
|
51
|
+
const refused = noTimeout(options);
|
|
52
|
+
if (refused !== undefined)
|
|
53
|
+
return refused;
|
|
54
54
|
return runCall(closed, options, (watch) => session.query(text, params, watch));
|
|
55
55
|
},
|
|
56
56
|
batch: (statements, options) => {
|
|
57
|
-
|
|
57
|
+
const refused = noTimeout(options);
|
|
58
|
+
if (refused !== undefined)
|
|
59
|
+
return refused;
|
|
58
60
|
return runCall(closed, options, async (watch) => {
|
|
59
|
-
const { runAtomicBatch } = await import("./
|
|
61
|
+
const { runAtomicBatch } = await import("./b76b8d95.js");
|
|
60
62
|
return runAtomicBatch(session, statements, watch);
|
|
61
63
|
});
|
|
62
64
|
},
|
|
@@ -65,7 +67,8 @@ async function open3(config = {}) {
|
|
|
65
67
|
return;
|
|
66
68
|
released = true;
|
|
67
69
|
try {
|
|
68
|
-
await
|
|
70
|
+
const { resetQueried } = await import("./bnby0esn.js");
|
|
71
|
+
await resetQueried(session);
|
|
69
72
|
} finally {
|
|
70
73
|
slot.release();
|
|
71
74
|
}
|
|
@@ -75,7 +78,9 @@ async function open3(config = {}) {
|
|
|
75
78
|
return {
|
|
76
79
|
capabilities: PGLITE_CAPABILITIES,
|
|
77
80
|
execute(text, params, options) {
|
|
78
|
-
|
|
81
|
+
const refused = noTimeout(options);
|
|
82
|
+
if (refused !== undefined)
|
|
83
|
+
return refused;
|
|
79
84
|
return runCall(closed, options, async (watch) => {
|
|
80
85
|
await slot.acquire(acquireMs);
|
|
81
86
|
try {
|
|
@@ -86,7 +91,9 @@ async function open3(config = {}) {
|
|
|
86
91
|
});
|
|
87
92
|
},
|
|
88
93
|
async batch(statements, options) {
|
|
89
|
-
|
|
94
|
+
const refused = noTimeout(options);
|
|
95
|
+
if (refused !== undefined)
|
|
96
|
+
return refused;
|
|
90
97
|
const connection = await lease();
|
|
91
98
|
try {
|
|
92
99
|
return await connection.batch(statements, options);
|
|
@@ -122,6 +129,12 @@ async function open3(config = {}) {
|
|
|
122
129
|
}
|
|
123
130
|
};
|
|
124
131
|
}
|
|
132
|
+
function seal2(pool) {
|
|
133
|
+
let closed = 0;
|
|
134
|
+
return new Proxy(pool, {
|
|
135
|
+
get: (inner, key) => key === "close" ? () => Promise.resolve(closed = 1) : (inner = inner[key], closed && inner?.call ? () => rejectClosed() : inner)
|
|
136
|
+
});
|
|
137
|
+
}
|
|
125
138
|
|
|
126
139
|
class PgliteSession {
|
|
127
140
|
canCancel = false;
|
|
@@ -131,12 +144,14 @@ class PgliteSession {
|
|
|
131
144
|
notices;
|
|
132
145
|
enter;
|
|
133
146
|
leave;
|
|
134
|
-
|
|
147
|
+
fail;
|
|
148
|
+
constructor(db, options, notices, enter, leave, fail) {
|
|
135
149
|
this.db = db;
|
|
136
150
|
this.options = options;
|
|
137
151
|
this.notices = notices;
|
|
138
152
|
this.enter = enter;
|
|
139
153
|
this.leave = leave;
|
|
154
|
+
this.fail = fail;
|
|
140
155
|
}
|
|
141
156
|
query(text, params, watch) {
|
|
142
157
|
const why = watch?.reason();
|
|
@@ -153,7 +168,7 @@ class PgliteSession {
|
|
|
153
168
|
}, (error) => {
|
|
154
169
|
this.leave();
|
|
155
170
|
this.notices.take();
|
|
156
|
-
return
|
|
171
|
+
return this.fail(stampQuery(error, text)).then((mapped) => {
|
|
157
172
|
throw mapped;
|
|
158
173
|
});
|
|
159
174
|
});
|
|
@@ -237,56 +252,10 @@ class Slot {
|
|
|
237
252
|
return this.waiters.length;
|
|
238
253
|
}
|
|
239
254
|
}
|
|
240
|
-
|
|
241
|
-
if (
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
});
|
|
245
|
-
try {
|
|
246
|
-
await session.query(RESET_ALL, undefined, undefined);
|
|
247
|
-
await session.query(UNLOCK, undefined, undefined);
|
|
248
|
-
} catch {
|
|
249
|
-
await session.rollback().catch(() => {
|
|
250
|
-
return;
|
|
251
|
-
});
|
|
252
|
-
await session.query(RESET_ALL, undefined, undefined);
|
|
253
|
-
await session.query(UNLOCK, undefined, undefined);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
function wireMap(oids) {
|
|
257
|
-
const parsers = {};
|
|
258
|
-
for (const oid of oids)
|
|
259
|
-
parsers[oid] = (value) => value;
|
|
260
|
-
return parsers;
|
|
255
|
+
function stampQuery(error, text) {
|
|
256
|
+
if (typeof error === "object" && error !== null && !("query" in error))
|
|
257
|
+
Reflect.set(error, "query", text);
|
|
258
|
+
return error;
|
|
261
259
|
}
|
|
262
|
-
var WIRE = wireMap([
|
|
263
|
-
16,
|
|
264
|
-
17,
|
|
265
|
-
20,
|
|
266
|
-
21,
|
|
267
|
-
23,
|
|
268
|
-
25,
|
|
269
|
-
114,
|
|
270
|
-
700,
|
|
271
|
-
701,
|
|
272
|
-
1043,
|
|
273
|
-
1082,
|
|
274
|
-
1114,
|
|
275
|
-
1184,
|
|
276
|
-
1700,
|
|
277
|
-
2950,
|
|
278
|
-
3802,
|
|
279
|
-
1000,
|
|
280
|
-
1005,
|
|
281
|
-
1007,
|
|
282
|
-
1009,
|
|
283
|
-
1016,
|
|
284
|
-
1115,
|
|
285
|
-
1182,
|
|
286
|
-
1185,
|
|
287
|
-
1231,
|
|
288
|
-
199,
|
|
289
|
-
3807
|
|
290
|
-
]);
|
|
291
260
|
|
|
292
|
-
export { open3 };
|
|
261
|
+
export { open3, seal2 };
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
emitSqlValue
|
|
3
|
+
} from "./3bb7wsqt.js";
|
|
1
4
|
import {
|
|
2
5
|
assertOperatorFits,
|
|
3
6
|
sqlType,
|
|
@@ -5,13 +8,13 @@ import {
|
|
|
5
8
|
assertBoundText,
|
|
6
9
|
assertRegconfig,
|
|
7
10
|
textArray
|
|
8
|
-
} from "./
|
|
11
|
+
} from "./zchaghkf.js";
|
|
9
12
|
import {
|
|
10
13
|
installOperatorSql,
|
|
11
14
|
quote,
|
|
12
15
|
isRecord,
|
|
13
|
-
|
|
14
|
-
} from "./
|
|
16
|
+
fail2
|
|
17
|
+
} from "./kgwp4jdd.js";
|
|
15
18
|
import {
|
|
16
19
|
isOperator,
|
|
17
20
|
operatorName,
|
|
@@ -19,7 +22,11 @@ import {
|
|
|
19
22
|
} from "./cn0n68ft.js";
|
|
20
23
|
|
|
21
24
|
// src/runtime/operator-sql.ts
|
|
22
|
-
function emitStructured(column, ref, name, value, sink) {
|
|
25
|
+
function emitStructured(table, column, ref, name, value, sink, order) {
|
|
26
|
+
if (name === "sql") {
|
|
27
|
+
emitSqlValue(table, ref, value, sink);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
23
30
|
if (name === "contains" || name === "containedBy" || name === "overlaps") {
|
|
24
31
|
emitContainment(column, ref, name, value, sink);
|
|
25
32
|
return;
|
|
@@ -36,12 +43,20 @@ function emitStructured(column, ref, name, value, sink) {
|
|
|
36
43
|
emitMatches(column, ref, value, sink);
|
|
37
44
|
return;
|
|
38
45
|
}
|
|
46
|
+
if (name === "relevance") {
|
|
47
|
+
if (order !== true)
|
|
48
|
+
fail2("OKM1121", `relevance on ${column.field} belongs in orderBy.`);
|
|
49
|
+
emitRelevance(column, ref, value, sink);
|
|
50
|
+
sink.text(" desc");
|
|
51
|
+
sink.mark(`o:${column.field}:relevance`);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
39
54
|
if (name === "similar" || name === "wordSimilar") {
|
|
40
55
|
emitTrigram(column, ref, name, value, sink);
|
|
41
56
|
return;
|
|
42
57
|
}
|
|
43
58
|
assertOperatorFits(column, name);
|
|
44
|
-
|
|
59
|
+
fail2("OKM1121", `${name} is not a value operator on ${column.field}. Use has, none, or every on a relation.`);
|
|
45
60
|
}
|
|
46
61
|
function emitContainment(column, ref, name, value, sink) {
|
|
47
62
|
assertOperatorFits(column, name);
|
|
@@ -56,7 +71,7 @@ function emitJsonKey(column, ref, name, value, sink) {
|
|
|
56
71
|
assertOperatorFits(column, name);
|
|
57
72
|
if (name === "hasKey") {
|
|
58
73
|
if (typeof value !== "string")
|
|
59
|
-
|
|
74
|
+
fail2("OKM1121", `hasKey on ${column.field} needs a key.`);
|
|
60
75
|
assertBoundText(value, `key on ${column.field}`);
|
|
61
76
|
sink.text("jsonb_exists(");
|
|
62
77
|
sink.text(ref);
|
|
@@ -66,7 +81,7 @@ function emitJsonKey(column, ref, name, value, sink) {
|
|
|
66
81
|
return;
|
|
67
82
|
}
|
|
68
83
|
if (!Array.isArray(value) || value.some((item) => typeof item !== "string")) {
|
|
69
|
-
|
|
84
|
+
fail2("OKM1121", `hasAnyKey on ${column.field} needs a list of keys.`);
|
|
70
85
|
}
|
|
71
86
|
sink.text("jsonb_exists_any(");
|
|
72
87
|
sink.text(ref);
|
|
@@ -77,15 +92,15 @@ function emitJsonKey(column, ref, name, value, sink) {
|
|
|
77
92
|
function emitPath(column, ref, value, sink) {
|
|
78
93
|
assertOperatorFits(column, "path");
|
|
79
94
|
if (!isRecord(value) || !Array.isArray(value.segments) || !isOperator(value.op)) {
|
|
80
|
-
|
|
95
|
+
fail2("OKM1121", `path on ${column.field} needs segments and a comparison.`);
|
|
81
96
|
}
|
|
82
97
|
const segments = value.segments;
|
|
83
98
|
if (segments.length === 0 || segments.some((item) => typeof item !== "string")) {
|
|
84
|
-
|
|
99
|
+
fail2("OKM1121", `path on ${column.field} needs a list of segments.`);
|
|
85
100
|
}
|
|
86
101
|
const opName = operatorName(value.op);
|
|
87
102
|
if (opName !== "eq" && opName !== "lt" && opName !== "lte" && opName !== "gt" && opName !== "gte") {
|
|
88
|
-
|
|
103
|
+
fail2("OKM1121", `path on ${column.field} compares with eq, lt, lte, gt, or gte.`);
|
|
89
104
|
}
|
|
90
105
|
const operand = operatorValue(value.op);
|
|
91
106
|
const cast = pathCast(column, operand);
|
|
@@ -106,7 +121,7 @@ function pathCast(column, operand) {
|
|
|
106
121
|
return "boolean";
|
|
107
122
|
if (typeof operand === "string")
|
|
108
123
|
return "text";
|
|
109
|
-
|
|
124
|
+
fail2("OKM1121", `path on ${column.field} compares a string, number, or boolean.`);
|
|
110
125
|
}
|
|
111
126
|
function pathParam(operand) {
|
|
112
127
|
if (typeof operand === "number")
|
|
@@ -117,35 +132,61 @@ function pathParam(operand) {
|
|
|
117
132
|
return operand;
|
|
118
133
|
return "";
|
|
119
134
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
135
|
+
var MATCH_FN = {
|
|
136
|
+
natural: "websearch_to_tsquery",
|
|
137
|
+
"all-words": "plainto_tsquery",
|
|
138
|
+
phrase: "phraseto_tsquery",
|
|
139
|
+
advanced: "to_tsquery"
|
|
140
|
+
};
|
|
141
|
+
function readMatch(column, value, label) {
|
|
142
|
+
if (!isRecord(value) || typeof value.query !== "string" || value.query.length === 0) {
|
|
143
|
+
fail2("OKM1121", `${label} on ${column.field} needs text to look for.`);
|
|
124
144
|
}
|
|
125
|
-
assertNoControl(value.query,
|
|
126
|
-
const
|
|
127
|
-
const fn =
|
|
145
|
+
assertNoControl(value.query, `${label} on ${column.field}`);
|
|
146
|
+
const match = value.match ?? "natural";
|
|
147
|
+
const fn = typeof match === "string" ? MATCH_FN[match] : undefined;
|
|
128
148
|
if (fn === undefined) {
|
|
129
|
-
|
|
149
|
+
fail2("OKM1121", `${label} on ${column.field} match must be natural, all-words, phrase, or advanced.`);
|
|
130
150
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
151
|
+
if (value.language === undefined)
|
|
152
|
+
return { fn, language: undefined, query: value.query };
|
|
153
|
+
if (typeof value.language !== "string") {
|
|
154
|
+
fail2("OKM1121", `${label} on ${column.field} language must be a name such as english.`);
|
|
155
|
+
}
|
|
156
|
+
assertRegconfig(value.language);
|
|
157
|
+
return { fn, language: value.language, query: value.query };
|
|
158
|
+
}
|
|
159
|
+
function emitTsquery(sink, query) {
|
|
160
|
+
sink.mark(query.language === undefined ? `:${query.fn}` : `:${query.fn}:lang`);
|
|
161
|
+
sink.text(query.fn);
|
|
134
162
|
sink.text("(");
|
|
135
|
-
if (
|
|
136
|
-
|
|
137
|
-
sink.param(value.config);
|
|
163
|
+
if (query.language !== undefined) {
|
|
164
|
+
sink.param(query.language);
|
|
138
165
|
sink.text("::regconfig, ");
|
|
139
166
|
}
|
|
140
|
-
sink.param(
|
|
167
|
+
sink.param(query.query);
|
|
168
|
+
sink.text(")");
|
|
169
|
+
}
|
|
170
|
+
function emitMatches(column, ref, value, sink) {
|
|
171
|
+
assertOperatorFits(column, "matches");
|
|
172
|
+
sink.text(ref);
|
|
173
|
+
sink.text(" @@ ");
|
|
174
|
+
emitTsquery(sink, readMatch(column, value, "matches"));
|
|
175
|
+
}
|
|
176
|
+
function emitRelevance(column, ref, value, sink) {
|
|
177
|
+
assertOperatorFits(column, "relevance");
|
|
178
|
+
sink.text("ts_rank(");
|
|
179
|
+
sink.text(ref);
|
|
180
|
+
sink.text(", ");
|
|
181
|
+
emitTsquery(sink, readMatch(column, value, "relevance"));
|
|
141
182
|
sink.text(")");
|
|
142
183
|
}
|
|
143
184
|
function emitTrigram(column, ref, name, value, sink) {
|
|
144
185
|
if (!isRecord(value) || typeof value.query !== "string" || typeof value.schema !== "string") {
|
|
145
|
-
|
|
186
|
+
fail2("OKM1121", `${name} on ${column.field} needs query text.`);
|
|
146
187
|
}
|
|
147
188
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(value.schema)) {
|
|
148
|
-
|
|
189
|
+
fail2("OKM1121", `${name} on ${column.field} needs an extension schema name.`);
|
|
149
190
|
}
|
|
150
191
|
sink.text(ref);
|
|
151
192
|
sink.text(" operator(");
|