pgkiln 0.74.0 → 0.76.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/db/migrations/142_json_sources.sql +426 -0
- package/docs/apex-feature-parity.md +7 -6
- package/docs/guide/03-builder.md +15 -0
- package/docs/guide/04-pages-and-regions.md +24 -2
- package/docs/guide/12-development.md +11 -0
- package/docs/guide/19-rest-data-sources.md +108 -1
- package/examples/hr/hr_77_json_sources.sql +174 -0
- package/package.json +1 -1
- package/public/app.css +18 -0
- package/public/app.js +141 -0
- package/src/app.ts +5 -0
- package/src/builder/document-view.ts +117 -0
- package/src/builder/i18n/de.ts +1 -0
- package/src/builder/i18n/en.ts +1 -0
- package/src/builder/i18n/es.ts +1 -0
- package/src/builder/i18n/fr.ts +1 -0
- package/src/builder/i18n/it.ts +1 -0
- package/src/builder/i18n/ja.ts +1 -0
- package/src/builder/i18n/ko.ts +1 -0
- package/src/builder/i18n/nl.ts +1 -0
- package/src/builder/i18n/pt.ts +1 -0
- package/src/builder/i18n/zh-cn.ts +1 -0
- package/src/builder/i18n/zh-tw.ts +1 -0
- package/src/builder/json-sources.ts +395 -0
- package/src/builder/object-actions.ts +1 -0
- package/src/builder/report-settings.ts +9 -0
- package/src/builder/shared.ts +1 -1
- package/src/builder/table-editor.ts +1 -0
- package/src/builder/websources.ts +6 -3
- package/src/i18n/ar.ts +24 -0
- package/src/i18n/cs.ts +24 -0
- package/src/i18n/da.ts +24 -0
- package/src/i18n/de.ts +24 -0
- package/src/i18n/el.ts +24 -0
- package/src/i18n/es.ts +24 -0
- package/src/i18n/fi.ts +24 -0
- package/src/i18n/fr.ts +24 -0
- package/src/i18n/he.ts +24 -0
- package/src/i18n/it.ts +24 -0
- package/src/i18n/ja.ts +24 -0
- package/src/i18n/ko.ts +24 -0
- package/src/i18n/nb.ts +24 -0
- package/src/i18n/pl.ts +24 -0
- package/src/i18n/pt.ts +24 -0
- package/src/i18n/ru.ts +24 -0
- package/src/i18n/sv.ts +24 -0
- package/src/i18n/tr.ts +24 -0
- package/src/i18n/uk.ts +24 -0
- package/src/i18n/zh.ts +24 -0
- package/src/i18n.ts +48 -0
- package/src/json-sources.ts +365 -0
- package/src/runtime/ai-filter.ts +11 -6
- package/src/runtime/ir-plan.ts +3 -3
- package/src/runtime/pdf.ts +6 -6
- package/src/runtime/render.ts +1 -1
- package/src/runtime/report.ts +211 -26
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { FastifyInstance, FastifyReply } from 'fastify';
|
|
2
|
+
import { joinStatements, recordChanges } from '../changelog.ts';
|
|
3
|
+
import { html, raw, type Raw } from '../html.ts';
|
|
4
|
+
import { icon } from '../icons.ts';
|
|
5
|
+
import { childTables, documentViewDdl, ident, NAME, primaryKey, tableGrants } from '../json-sources.ts';
|
|
6
|
+
import { clientIp, logActivity } from '../session.ts';
|
|
7
|
+
import { readTable } from '../tabledef.ts';
|
|
8
|
+
import { clearCompletions } from './code-editor.ts';
|
|
9
|
+
import { tr } from './i18n.ts';
|
|
10
|
+
import { SYSTEM_SCHEMAS } from './object-browser.ts';
|
|
11
|
+
import { back, BASE, csrf, developer, flash, send, shell, workshopTabs, type Body, type Req } from './ui.ts';
|
|
12
|
+
import { currentWorkspace, usableSchemas, workshopDb } from './workspaces.ts';
|
|
13
|
+
|
|
14
|
+
// (sprint 142, AP-8; APEX: JSON Relational Duality Views) SQL Workshop › Table Properties › Document view: a view
|
|
15
|
+
// with the table's key and a jsonb document of each row with lists of its child rows (tables whose foreign keys
|
|
16
|
+
// reference it, the developer picks them). The view is security_invoker; its INSTEAD OF trigger
|
|
17
|
+
// (meta.json_document_write, migration 142) writes a document back: the row's columns it names, the children it lists
|
|
18
|
+
// (updated by key, or inserted), and deletes the children it leaves out. REST (AutoREST on the view) and MCP read and
|
|
19
|
+
// write whole documents. Preview, Apply (one transaction with the workshop's connection, in the Change Log) and Open
|
|
20
|
+
// in the worksheet, as Add full-text search. Names come from the catalog.
|
|
21
|
+
|
|
22
|
+
async function page(req: Req, reply: FastifyReply) {
|
|
23
|
+
const s = await developer(req, reply);
|
|
24
|
+
if (!s) return;
|
|
25
|
+
const tx = tr(s);
|
|
26
|
+
const db = await workshopDb(s);
|
|
27
|
+
const isPost = req.method === 'POST';
|
|
28
|
+
const b: Body = (isPost ? req.body : req.query) ?? {};
|
|
29
|
+
const ref = String(b.o ?? '');
|
|
30
|
+
const t = ref ? await readTable(db, ref) : null;
|
|
31
|
+
const schemas = (await usableSchemas(db)).filter((n) => !SYSTEM_SCHEMAS.includes(n));
|
|
32
|
+
if (!t || !schemas.includes(t.schema)) return reply.code(404).send('Not found');
|
|
33
|
+
const table = `${ident(t.schema)}.${ident(t.name)}`;
|
|
34
|
+
const key = await primaryKey(db, t.schema, t.name);
|
|
35
|
+
const children = (await childTables(db, t.schema, t.name)).filter((c) => schemas.includes(c.schema));
|
|
36
|
+
// columns a document leaves out: full-text and vector columns (generated or kept by triggers)
|
|
37
|
+
const omitOf = async (schema: string, name: string) => (await db.query<{ n: string }>(
|
|
38
|
+
`select a.attname as n from pg_attribute a join pg_class c on c.oid = a.attrelid join pg_namespace s on s.oid = c.relnamespace join pg_type ty on ty.oid = a.atttypid
|
|
39
|
+
where s.nspname = $1 and c.relname = $2 and a.attnum > 0 and not a.attisdropped and ty.typname in ('tsvector', 'vector', 'halfvec', 'sparsevec')`, [schema, name])).rows.map((r) => r.n);
|
|
40
|
+
const view = isPost ? String(b.view ?? '').trim() : `${t.name}_doc`.toLowerCase().replace(/[^a-z0-9_]+/g, '_').slice(0, 63);
|
|
41
|
+
const document = isPost ? String(b.document ?? '').trim() : 'doc';
|
|
42
|
+
const picked = new Set<number>();
|
|
43
|
+
if (isPost) children.forEach((c, i) => b[`c.${i}.use`] === 'on' && b[`c.${i}.name`] === `${c.schema}.${c.table}` && picked.add(i));
|
|
44
|
+
else children.forEach((_, i) => picked.add(i));
|
|
45
|
+
|
|
46
|
+
const errors: string[] = [];
|
|
47
|
+
let ddl: string[] = [];
|
|
48
|
+
if (!key.length) errors.push(`${table} has no primary key: a document view finds its rows by it.`);
|
|
49
|
+
if (isPost && !errors.length) {
|
|
50
|
+
for (const n of [view, document]) if (!NAME.test(n)) errors.push(tx('fts.bad_name', { name: n }));
|
|
51
|
+
if (key.includes(document)) errors.push(`The document column may not have the name of a key column (${document}).`);
|
|
52
|
+
if (NAME.test(view) && (await db.one('select 1 as x from pg_class where relnamespace = $1::regnamespace and relname = $2', [ident(t.schema), view]))) errors.push(tx('fts.exists', { name: view }));
|
|
53
|
+
if (!errors.length) {
|
|
54
|
+
const kids = [];
|
|
55
|
+
for (const i of picked) kids.push({ ...children[i], omit: await omitOf(children[i].schema, children[i].table) });
|
|
56
|
+
ddl = documentViewDdl({ schema: t.schema, table: t.name, key, view, document, children: kids, omit: await omitOf(t.schema, t.name), grants: await tableGrants(db, t.schema, t.name) });
|
|
57
|
+
}
|
|
58
|
+
if (ddl.length && b.mode === 'worksheet') {
|
|
59
|
+
s.state.__SQLDRAFT = `${ddl.join(';\n\n')};`;
|
|
60
|
+
flash(s, tx('te.review'));
|
|
61
|
+
return back(reply, s, `${BASE}/sql/worksheet`);
|
|
62
|
+
}
|
|
63
|
+
if (ddl.length && b.mode === 'apply') {
|
|
64
|
+
const c = await db.pool.connect();
|
|
65
|
+
let failed = '';
|
|
66
|
+
try {
|
|
67
|
+
await c.query('begin');
|
|
68
|
+
for (const x of ddl) await c.query(x);
|
|
69
|
+
await c.query('commit');
|
|
70
|
+
} catch (e) {
|
|
71
|
+
failed = (e as Error).message;
|
|
72
|
+
await c.query('rollback').catch(() => {});
|
|
73
|
+
} finally {
|
|
74
|
+
c.release(true);
|
|
75
|
+
}
|
|
76
|
+
await logActivity({ username: s.username, event: 'sql_command', ip: clientIp(req), detail: ddl.join(';\n').slice(0, 2000) });
|
|
77
|
+
clearCompletions();
|
|
78
|
+
if (!failed) {
|
|
79
|
+
await recordChanges({ workspaceId: currentWorkspace(s), author: s.username ?? '?', source: 'table', defaultSchema: t.schema, statements: [joinStatements(ddl)] });
|
|
80
|
+
flash(s, `The document view ${t.schema}.${view} is made.`);
|
|
81
|
+
return back(reply, s, `${BASE}/sql/objects/table?${new URLSearchParams({ o: `${ident(t.schema)}.${ident(view)}` })}`);
|
|
82
|
+
}
|
|
83
|
+
errors.push(`${tx('te.nothing_changed')}: ${failed}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const title = `${tx('docv.add')}: ${table}`;
|
|
88
|
+
const form: Raw = key.length ? html`<form method="post" action="${BASE}/sql/objects/document" class="fts-form">${csrf(s)}
|
|
89
|
+
<input type="hidden" name="o" value="${table}">
|
|
90
|
+
<fieldset class="prop-group"><legend>Child tables in the document</legend>
|
|
91
|
+
${children.length ? html`<div class="table-wrap"><table class="report"><thead><tr><th scope="col">${tx('fts.include')}</th><th scope="col">Table</th><th scope="col">List in the document</th><th scope="col">Foreign key</th></tr></thead><tbody>
|
|
92
|
+
${children.map((c, i) => html`<tr><td class="te-c"><input type="hidden" name="c.${i}.name" value="${c.schema}.${c.table}"><input type="checkbox" id="dv-c${i}" name="c.${i}.use"${picked.has(i) ? raw(' checked') : ''}></td>
|
|
93
|
+
<td><label for="dv-c${i}">${c.schema}.${c.table}</label></td><td><code>${c.name}</code></td><td><code>${c.fk.map(([col, p]) => `${col} → ${p}`).join(', ')}</code></td></tr>`)}
|
|
94
|
+
</tbody></table></div>` : html`<p class="muted">No other table references ${table}: the document is the row alone.</p>`}
|
|
95
|
+
<small class="help">Each child row is an object in its list, without the foreign key columns. Writing a document updates the children it lists by their key, inserts the ones without a key, and deletes the ones it leaves out; a document without the list leaves the children alone.</small></fieldset>
|
|
96
|
+
<div class="form-grid u-mt1">
|
|
97
|
+
<div class="field"><label class="label" for="dv-view">View</label><input id="dv-view" name="view" value="${view}" required autocomplete="off" spellcheck="false" class="code"></div>
|
|
98
|
+
<div class="field"><label class="label" for="dv-doc">Document column</label><input id="dv-doc" name="document" value="${document}" required autocomplete="off" spellcheck="false" class="code"></div>
|
|
99
|
+
</div>
|
|
100
|
+
${ddl.length ? html`<h2>DDL</h2><pre class="source te-ddl" data-code-view="sql" tabindex="0" aria-label="DDL">${ddl.map((x) => `${x};`).join('\n\n')}</pre>` : ''}
|
|
101
|
+
<div class="buttons te-buttons">
|
|
102
|
+
<button class="btn" name="mode" value="preview">${icon('eye')} ${tx('te.preview')}</button>
|
|
103
|
+
<button class="btn btn-hot" name="mode" value="apply">${icon('check')} ${tx('te.apply')}</button>
|
|
104
|
+
<button class="btn" name="mode" value="worksheet">${icon('code')} ${tx('te.open_ws')}</button>
|
|
105
|
+
<a class="btn" href="${BASE}/sql/objects/table?${new URLSearchParams({ o: table })}">${tx('common.cancel')}</a>
|
|
106
|
+
</div></form>` : html``;
|
|
107
|
+
const main = html`<h1 class="u-mb1">${title}</h1>${workshopTabs('objects', s)}
|
|
108
|
+
<p class="muted">A document view shows each row of ${table} with its child rows as one JSON document, like an Oracle JSON Relational Duality View. Reports, REST (AutoREST on the view) and MCP read whole documents; an update of the document column writes the row and its children back in one statement. The table's row level security and grants apply (the view is security_invoker and gets the table's grants).</p>
|
|
109
|
+
${errors.length ? html`<div class="alert alert-error" role="alert"><ul>${errors.map((e) => html`<li>${e}</li>`)}</ul></div>` : ''}
|
|
110
|
+
${form}`;
|
|
111
|
+
return send(reply, s, shell(s, title, [['SQL Workshop', `${BASE}/sql`], [tx('ob.title'), `${BASE}/sql/objects`], [tx('te.title_table', { table }), `${BASE}/sql/objects/table?${new URLSearchParams({ o: table })}`], [tx('docv.add')]], main, 'sql'));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export async function documentViewRoutes(app: FastifyInstance) {
|
|
115
|
+
app.get(`${BASE}/sql/objects/document`, page);
|
|
116
|
+
app.post(`${BASE}/sql/objects/document`, page);
|
|
117
|
+
}
|
package/src/builder/i18n/de.ts
CHANGED
|
@@ -1077,6 +1077,7 @@ export const de: BuilderMessages = {
|
|
|
1077
1077
|
'fts.added': "Volltextsuche zu {table} hinzugefügt: Spalte {column} mit Index {index}.",
|
|
1078
1078
|
// (sprint 136, AP-1) Table Properties › Add vector column
|
|
1079
1079
|
'vec.add': "Vektorspalte hinzufügen",
|
|
1080
|
+
'docv.add': "Dokumentansicht",
|
|
1080
1081
|
'vec.title': "Vektorspalte für {table}",
|
|
1081
1082
|
'vec.intro': "Fügt eine Embedding-Spalte vector(n) hinzu (n: die Dimensionen des Vektoranbieters), einen HNSW-Index für die Distanz und einen Trigger, der eine Zeile neu einbettet, wenn sich ihre Quellspalten ändern. Eine Suchkonfiguration vom Typ vector oder hybrid oder das Retrieve-Werkzeug eines KI-Agenten findet Zeilen dann nach Bedeutung. Die vorhandenen Zeilen werden sofort für ihre Embeddings eingereiht.",
|
|
1082
1083
|
'vec.existing': "Vektorspalten jetzt",
|
package/src/builder/i18n/en.ts
CHANGED
|
@@ -1081,6 +1081,7 @@ export const en = {
|
|
|
1081
1081
|
'fts.added': "Added full-text search to {table}: column {column} with index {index}.",
|
|
1082
1082
|
// (sprint 136, AP-1) Table Properties › Add vector column
|
|
1083
1083
|
'vec.add': "Add vector column",
|
|
1084
|
+
'docv.add': "Document view",
|
|
1084
1085
|
'vec.title': "Vector column on {table}",
|
|
1085
1086
|
'vec.intro': "Adds an embedding column vector(n) (n: the vector provider's dimensions), an HNSW index for the distance, and a trigger that re-embeds a row when its source columns change. A search configuration of type vector or hybrid, or an AI agent's Retrieve tool, then finds rows by meaning. The rows there are now are queued for their embeddings at once.",
|
|
1086
1087
|
'vec.existing': "Vector columns now",
|
package/src/builder/i18n/es.ts
CHANGED
|
@@ -1077,6 +1077,7 @@ export const es: BuilderMessages = {
|
|
|
1077
1077
|
'fts.added': "Búsqueda de texto completo añadida a {table}: columna {column} con el índice {index}.",
|
|
1078
1078
|
// (sprint 136, AP-1) Table Properties › Add vector column
|
|
1079
1079
|
'vec.add': "Añadir columna vectorial",
|
|
1080
|
+
'docv.add': "Vista de documento",
|
|
1080
1081
|
'vec.title': "Columna vectorial en {table}",
|
|
1081
1082
|
'vec.intro': "Añade una columna de embedding vector(n) (n: las dimensiones del proveedor de vectores), un índice HNSW para la distancia y un disparador que vuelve a calcular el embedding de una fila cuando cambian sus columnas de origen. Una configuración de búsqueda de tipo vector o hybrid, o la herramienta Retrieve de un agente de IA, encuentra entonces las filas por su significado. Las filas que ya existen se ponen en cola enseguida para sus embeddings.",
|
|
1082
1083
|
'vec.existing': "Columnas vectoriales actuales",
|
package/src/builder/i18n/fr.ts
CHANGED
|
@@ -1077,6 +1077,7 @@ export const fr: BuilderMessages = {
|
|
|
1077
1077
|
'fts.added': "Recherche plein texte ajoutée à {table} : colonne {column} avec l'index {index}.",
|
|
1078
1078
|
// (sprint 136, AP-1) Table Properties › Add vector column
|
|
1079
1079
|
'vec.add': "Ajouter une colonne vectorielle",
|
|
1080
|
+
'docv.add': "Vue document",
|
|
1080
1081
|
'vec.title': "Colonne vectorielle sur {table}",
|
|
1081
1082
|
'vec.intro': "Ajoute une colonne d'embedding vector(n) (n : les dimensions du fournisseur de vecteurs), un index HNSW pour la distance et un déclencheur qui recalcule l'embedding d'une ligne quand ses colonnes sources changent. Une configuration de recherche de type vector ou hybrid, ou l'outil Retrieve d'un agent IA, trouve alors les lignes par leur sens. Les lignes existantes sont mises en file d'attente tout de suite pour leurs embeddings.",
|
|
1082
1083
|
'vec.existing': "Colonnes vectorielles actuelles",
|
package/src/builder/i18n/it.ts
CHANGED
|
@@ -1077,6 +1077,7 @@ export const it: BuilderMessages = {
|
|
|
1077
1077
|
'fts.added': "Ricerca full-text aggiunta a {table}: colonna {column} con l'indice {index}.",
|
|
1078
1078
|
// (sprint 136, AP-1) Table Properties › Add vector column
|
|
1079
1079
|
'vec.add': "Aggiungi colonna vettoriale",
|
|
1080
|
+
'docv.add': "Vista documento",
|
|
1080
1081
|
'vec.title': "Colonna vettoriale su {table}",
|
|
1081
1082
|
'vec.intro': "Aggiunge una colonna di embedding vector(n) (n: le dimensioni del provider di vettori), un indice HNSW per la distanza e un trigger che ricalcola l'embedding di una riga quando cambiano le sue colonne di origine. Una configurazione di ricerca di tipo vector o hybrid, o lo strumento Retrieve di un agente IA, trova allora le righe per significato. Le righe già presenti vengono messe subito in coda per i loro embedding.",
|
|
1082
1083
|
'vec.existing': "Colonne vettoriali attuali",
|
package/src/builder/i18n/ja.ts
CHANGED
|
@@ -1077,6 +1077,7 @@ export const ja: BuilderMessages = {
|
|
|
1077
1077
|
'fts.added': "{table} に全文検索を追加しました:列 {column}、索引 {index}。",
|
|
1078
1078
|
// (sprint 136, AP-1) Table Properties › Add vector column
|
|
1079
1079
|
'vec.add': "ベクトル列を追加",
|
|
1080
|
+
'docv.add': "ドキュメント・ビュー",
|
|
1080
1081
|
'vec.title': "{table} のベクトル列",
|
|
1081
1082
|
'vec.intro': "埋め込み列 vector(n)(n はベクトル・プロバイダの次元数)、距離用の HNSW 索引、およびソース列が変わったときに行を再埋め込みするトリガーを追加します。その後、検索タイプ vector または hybrid の検索構成や AI エージェントの Retrieve ツールで、意味によって行を検索できます。既存の行はすぐに埋め込みのキューに入れられます。",
|
|
1082
1083
|
'vec.existing': "現在のベクトル列",
|
package/src/builder/i18n/ko.ts
CHANGED
|
@@ -1077,6 +1077,7 @@ export const ko: BuilderMessages = {
|
|
|
1077
1077
|
'fts.added': "{table}에 전체 텍스트 검색을 추가했습니다: 열 {column}, 인덱스 {index}.",
|
|
1078
1078
|
// (sprint 136, AP-1) Table Properties › Add vector column
|
|
1079
1079
|
'vec.add': "벡터 열 추가",
|
|
1080
|
+
'docv.add': "문서 뷰",
|
|
1080
1081
|
'vec.title': "{table}의 벡터 열",
|
|
1081
1082
|
'vec.intro': "임베딩 열 vector(n)(n: 벡터 공급자의 차원 수), 거리용 HNSW 인덱스, 그리고 소스 열이 바뀌면 행을 다시 임베딩하는 트리거를 추가합니다. 그러면 검색 유형 vector 또는 hybrid의 검색 구성이나 AI 에이전트의 Retrieve 도구가 의미로 행을 찾습니다. 지금 있는 행은 바로 임베딩 대기열에 들어갑니다.",
|
|
1082
1083
|
'vec.existing': "현재 벡터 열",
|
package/src/builder/i18n/nl.ts
CHANGED
|
@@ -1077,6 +1077,7 @@ export const nl: BuilderMessages = {
|
|
|
1077
1077
|
'fts.added': "Volledige-tekstzoeken toegevoegd aan {table}: kolom {column} met index {index}.",
|
|
1078
1078
|
// (sprint 136, AP-1) Table Properties › Add vector column
|
|
1079
1079
|
'vec.add': "Vectorkolom toevoegen",
|
|
1080
|
+
'docv.add': "Documentview",
|
|
1080
1081
|
'vec.title': "Vectorkolom op {table}",
|
|
1081
1082
|
'vec.intro': "Voegt een embeddingkolom vector(n) toe (n: de dimensies van de vectorprovider), een HNSW-index voor de afstand, en een trigger die een rij opnieuw embedt als de bronkolommen veranderen. Een zoekconfiguratie van het type vector of hybrid, of de Retrieve-tool van een AI-agent, vindt rijen dan op betekenis. De rijen die er nu zijn, komen meteen in de wachtrij voor hun embeddings.",
|
|
1082
1083
|
'vec.existing': "Vectorkolommen nu",
|
package/src/builder/i18n/pt.ts
CHANGED
|
@@ -1077,6 +1077,7 @@ export const pt: BuilderMessages = {
|
|
|
1077
1077
|
'fts.added': "Pesquisa de texto integral adicionada a {table}: coluna {column} com o índice {index}.",
|
|
1078
1078
|
// (sprint 136, AP-1) Table Properties › Add vector column
|
|
1079
1079
|
'vec.add': "Adicionar coluna vetorial",
|
|
1080
|
+
'docv.add': "Vista de documento",
|
|
1080
1081
|
'vec.title': "Coluna vetorial em {table}",
|
|
1081
1082
|
'vec.intro': "Adiciona uma coluna de embedding vector(n) (n: as dimensões do fornecedor de vetores), um índice HNSW para a distância e um gatilho que recalcula o embedding de uma linha quando as colunas de origem mudam. Uma configuração de pesquisa do tipo vector ou hybrid, ou a ferramenta Retrieve de um agente de IA, encontra então as linhas pelo significado. As linhas que já existem entram logo na fila para os seus embeddings.",
|
|
1082
1083
|
'vec.existing': "Colunas vetoriais atuais",
|
|
@@ -1077,6 +1077,7 @@ export const zhCN: BuilderMessages = {
|
|
|
1077
1077
|
'fts.added': "已为 {table} 添加全文搜索:列 {column},索引 {index}。",
|
|
1078
1078
|
// (sprint 136, AP-1) Table Properties › Add vector column
|
|
1079
1079
|
'vec.add': "添加向量列",
|
|
1080
|
+
'docv.add': "文档视图",
|
|
1080
1081
|
'vec.title': "{table} 的向量列",
|
|
1081
1082
|
'vec.intro': "添加一个嵌入列 vector(n)(n:向量提供者的维数)、一个用于该距离的 HNSW 索引,以及在源列变化时重新嵌入该行的触发器。之后,搜索类型为 vector 或 hybrid 的搜索配置,或 AI 代理的 Retrieve 工具,就能按含义找到行。现有的行会立即进入嵌入队列。",
|
|
1082
1083
|
'vec.existing': "当前的向量列",
|
|
@@ -1077,6 +1077,7 @@ export const zhTW: BuilderMessages = {
|
|
|
1077
1077
|
'fts.added': "已為 {table} 新增全文檢索:欄位 {column},索引 {index}。",
|
|
1078
1078
|
// (sprint 136, AP-1) Table Properties › Add vector column
|
|
1079
1079
|
'vec.add': "新增向量欄位",
|
|
1080
|
+
'docv.add': "文件檢視",
|
|
1080
1081
|
'vec.title': "{table} 的向量欄位",
|
|
1081
1082
|
'vec.intro': "新增一個嵌入欄位 vector(n)(n:向量提供者的維度數)、一個用於該距離的 HNSW 索引,以及在來源欄位變更時重新嵌入該列的觸發程序。之後,搜尋類型為 vector 或 hybrid 的搜尋組態,或 AI 代理的 Retrieve 工具,就能依含意找到資料列。現有的資料列會立即進入嵌入佇列。",
|
|
1082
1083
|
'vec.existing': "目前的向量欄位",
|