@deepagents/text2sql 0.10.1 → 0.11.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 +32 -41
- package/dist/index.d.ts +1 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2338 -2395
- package/dist/index.js.map +4 -4
- package/dist/lib/adapters/adapter.d.ts +13 -1
- package/dist/lib/adapters/adapter.d.ts.map +1 -1
- package/dist/lib/adapters/groundings/abstract.grounding.d.ts +19 -3
- package/dist/lib/adapters/groundings/abstract.grounding.d.ts.map +1 -1
- package/dist/lib/adapters/groundings/column-stats.grounding.d.ts +1 -2
- package/dist/lib/adapters/groundings/column-stats.grounding.d.ts.map +1 -1
- package/dist/lib/adapters/groundings/column-values.grounding.d.ts +1 -2
- package/dist/lib/adapters/groundings/column-values.grounding.d.ts.map +1 -1
- package/dist/lib/adapters/groundings/constraint.grounding.d.ts +1 -1
- package/dist/lib/adapters/groundings/constraint.grounding.d.ts.map +1 -1
- package/dist/lib/adapters/groundings/index.js +15 -222
- package/dist/lib/adapters/groundings/index.js.map +3 -3
- package/dist/lib/adapters/groundings/indexes.grounding.d.ts +1 -1
- package/dist/lib/adapters/groundings/indexes.grounding.d.ts.map +1 -1
- package/dist/lib/adapters/groundings/info.grounding.d.ts +1 -1
- package/dist/lib/adapters/groundings/info.grounding.d.ts.map +1 -1
- package/dist/lib/adapters/groundings/report.grounding.d.ts +1 -1
- package/dist/lib/adapters/groundings/report.grounding.d.ts.map +1 -1
- package/dist/lib/adapters/groundings/row-count.grounding.d.ts +1 -1
- package/dist/lib/adapters/groundings/row-count.grounding.d.ts.map +1 -1
- package/dist/lib/adapters/groundings/table.grounding.d.ts +3 -3
- package/dist/lib/adapters/groundings/table.grounding.d.ts.map +1 -1
- package/dist/lib/adapters/groundings/view.grounding.d.ts +1 -1
- package/dist/lib/adapters/groundings/view.grounding.d.ts.map +1 -1
- package/dist/lib/adapters/mysql/index.js +343 -315
- package/dist/lib/adapters/mysql/index.js.map +4 -4
- package/dist/lib/adapters/postgres/index.js +385 -357
- package/dist/lib/adapters/postgres/index.js.map +4 -4
- package/dist/lib/adapters/spreadsheet/index.js +290 -223
- package/dist/lib/adapters/spreadsheet/index.js.map +4 -4
- package/dist/lib/adapters/sqlite/index.js +307 -279
- package/dist/lib/adapters/sqlite/index.js.map +4 -4
- package/dist/lib/adapters/sqlserver/index.js +383 -355
- package/dist/lib/adapters/sqlserver/index.js.map +4 -4
- package/dist/lib/agents/developer.agent.d.ts +33 -23
- package/dist/lib/agents/developer.agent.d.ts.map +1 -1
- package/dist/lib/agents/sql.agent.d.ts +4 -4
- package/dist/lib/agents/sql.agent.d.ts.map +1 -1
- package/dist/lib/agents/teachables.agent.d.ts +2 -2
- package/dist/lib/agents/teachables.agent.d.ts.map +1 -1
- package/dist/lib/agents/text2sql.agent.d.ts +18 -71
- package/dist/lib/agents/text2sql.agent.d.ts.map +1 -1
- package/dist/lib/fragments/schema.d.ts +214 -0
- package/dist/lib/fragments/schema.d.ts.map +1 -0
- package/dist/lib/instructions.d.ts +29 -2
- package/dist/lib/instructions.d.ts.map +1 -1
- package/dist/lib/instructions.js +336 -319
- package/dist/lib/instructions.js.map +4 -4
- package/dist/lib/sql.d.ts +13 -103
- package/dist/lib/sql.d.ts.map +1 -1
- package/dist/lib/synthesis/extractors/base-contextual-extractor.d.ts +2 -2
- package/dist/lib/synthesis/extractors/base-contextual-extractor.d.ts.map +1 -1
- package/dist/lib/synthesis/extractors/message-extractor.d.ts +1 -2
- package/dist/lib/synthesis/extractors/message-extractor.d.ts.map +1 -1
- package/dist/lib/synthesis/extractors/sql-extractor.d.ts.map +1 -1
- package/dist/lib/synthesis/index.js +1794 -572
- package/dist/lib/synthesis/index.js.map +4 -4
- package/dist/lib/synthesis/synthesizers/depth-evolver.d.ts.map +1 -1
- package/dist/lib/synthesis/synthesizers/persona-generator.d.ts +7 -17
- package/dist/lib/synthesis/synthesizers/persona-generator.d.ts.map +1 -1
- package/dist/lib/synthesis/synthesizers/schema-synthesizer.d.ts +2 -2
- package/dist/lib/synthesis/synthesizers/schema-synthesizer.d.ts.map +1 -1
- package/dist/lib/synthesis/synthesizers/teachings-generator.d.ts +8 -20
- package/dist/lib/synthesis/synthesizers/teachings-generator.d.ts.map +1 -1
- package/dist/lib/teach/teachings.d.ts +2 -2
- package/dist/lib/teach/teachings.d.ts.map +1 -1
- package/package.json +4 -3
- package/dist/lib/agents/chat1.agent.d.ts +0 -50
- package/dist/lib/agents/chat1.agent.d.ts.map +0 -1
- package/dist/lib/agents/chat2.agent.d.ts +0 -68
- package/dist/lib/agents/chat2.agent.d.ts.map +0 -1
- package/dist/lib/agents/chat3.agent.d.ts +0 -80
- package/dist/lib/agents/chat3.agent.d.ts.map +0 -1
- package/dist/lib/agents/chat4.agent.d.ts +0 -88
- package/dist/lib/agents/chat4.agent.d.ts.map +0 -1
- package/dist/lib/history/history.d.ts +0 -41
- package/dist/lib/history/history.d.ts.map +0 -1
- package/dist/lib/history/memory.history.d.ts +0 -5
- package/dist/lib/history/memory.history.d.ts.map +0 -1
- package/dist/lib/history/sqlite.history.d.ts +0 -15
- package/dist/lib/history/sqlite.history.d.ts.map +0 -1
- package/dist/lib/memory/memory.prompt.d.ts +0 -3
- package/dist/lib/memory/memory.prompt.d.ts.map +0 -1
- package/dist/lib/memory/memory.store.d.ts +0 -5
- package/dist/lib/memory/memory.store.d.ts.map +0 -1
- package/dist/lib/memory/sqlite.store.d.ts +0 -14
- package/dist/lib/memory/sqlite.store.d.ts.map +0 -1
- package/dist/lib/memory/store.d.ts +0 -40
- package/dist/lib/memory/store.d.ts.map +0 -1
- package/dist/lib/teach/teachables.d.ts +0 -648
- package/dist/lib/teach/teachables.d.ts.map +0 -1
- package/dist/lib/teach/xml.d.ts +0 -6
- package/dist/lib/teach/xml.d.ts.map +0 -1
|
@@ -1,3 +1,94 @@
|
|
|
1
|
+
// packages/text2sql/src/lib/fragments/schema.ts
|
|
2
|
+
function dialectInfo(input) {
|
|
3
|
+
return {
|
|
4
|
+
name: "dialectInfo",
|
|
5
|
+
data: {
|
|
6
|
+
dialect: input.dialect,
|
|
7
|
+
...input.version && { version: input.version },
|
|
8
|
+
...input.database && { database: input.database }
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function table(input) {
|
|
13
|
+
return {
|
|
14
|
+
name: "table",
|
|
15
|
+
data: {
|
|
16
|
+
name: input.name,
|
|
17
|
+
...input.schema && { schema: input.schema },
|
|
18
|
+
...input.rowCount != null && { rowCount: input.rowCount },
|
|
19
|
+
...input.sizeHint && { sizeHint: input.sizeHint },
|
|
20
|
+
columns: input.columns,
|
|
21
|
+
...input.indexes?.length && { indexes: input.indexes },
|
|
22
|
+
...input.constraints?.length && { constraints: input.constraints }
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function column(input) {
|
|
27
|
+
return {
|
|
28
|
+
name: "column",
|
|
29
|
+
data: {
|
|
30
|
+
name: input.name,
|
|
31
|
+
type: input.type,
|
|
32
|
+
...input.pk && { pk: true },
|
|
33
|
+
...input.fk && { fk: input.fk },
|
|
34
|
+
...input.unique && { unique: true },
|
|
35
|
+
...input.notNull && { notNull: true },
|
|
36
|
+
...input.default && { default: input.default },
|
|
37
|
+
...input.indexed && { indexed: true },
|
|
38
|
+
...input.values?.length && { values: input.values },
|
|
39
|
+
...input.stats && { stats: input.stats }
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function index(input) {
|
|
44
|
+
return {
|
|
45
|
+
name: "index",
|
|
46
|
+
data: {
|
|
47
|
+
name: input.name,
|
|
48
|
+
columns: input.columns,
|
|
49
|
+
...input.unique && { unique: true },
|
|
50
|
+
...input.type && { type: input.type }
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function constraint(input) {
|
|
55
|
+
return {
|
|
56
|
+
name: "constraint",
|
|
57
|
+
data: {
|
|
58
|
+
name: input.name,
|
|
59
|
+
type: input.type,
|
|
60
|
+
...input.columns?.length && { columns: input.columns },
|
|
61
|
+
...input.definition && { definition: input.definition },
|
|
62
|
+
...input.defaultValue && { defaultValue: input.defaultValue },
|
|
63
|
+
...input.referencedTable && { referencedTable: input.referencedTable },
|
|
64
|
+
...input.referencedColumns?.length && {
|
|
65
|
+
referencedColumns: input.referencedColumns
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function view(input) {
|
|
71
|
+
return {
|
|
72
|
+
name: "view",
|
|
73
|
+
data: {
|
|
74
|
+
name: input.name,
|
|
75
|
+
...input.schema && { schema: input.schema },
|
|
76
|
+
columns: input.columns,
|
|
77
|
+
...input.definition && { definition: input.definition }
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function relationship(input) {
|
|
82
|
+
return {
|
|
83
|
+
name: "relationship",
|
|
84
|
+
data: {
|
|
85
|
+
from: input.from,
|
|
86
|
+
to: input.to,
|
|
87
|
+
...input.cardinality && { cardinality: input.cardinality }
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
1
92
|
// packages/text2sql/src/lib/adapters/groundings/context.ts
|
|
2
93
|
function createGroundingContext() {
|
|
3
94
|
return {
|
|
@@ -10,24 +101,169 @@ function createGroundingContext() {
|
|
|
10
101
|
|
|
11
102
|
// packages/text2sql/src/lib/adapters/adapter.ts
|
|
12
103
|
var Adapter = class {
|
|
104
|
+
/**
|
|
105
|
+
* Introspect the database schema and return context fragments.
|
|
106
|
+
*
|
|
107
|
+
* Executes all configured groundings to populate the context, then
|
|
108
|
+
* generates fragments from the complete context data.
|
|
109
|
+
*
|
|
110
|
+
* @param ctx - Optional grounding context for sharing state between groundings
|
|
111
|
+
* @returns Array of context fragments representing the database schema
|
|
112
|
+
*/
|
|
13
113
|
async introspect(ctx = createGroundingContext()) {
|
|
14
|
-
const lines = [];
|
|
15
114
|
for (const fn of this.grounding) {
|
|
16
115
|
const grounding = fn(this);
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
116
|
+
await grounding.execute(ctx);
|
|
117
|
+
}
|
|
118
|
+
return this.#toSchemaFragments(ctx);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Convert complete grounding context to schema fragments.
|
|
122
|
+
* Called after all groundings have populated ctx with data.
|
|
123
|
+
*/
|
|
124
|
+
#toSchemaFragments(ctx) {
|
|
125
|
+
const fragments = [];
|
|
126
|
+
if (ctx.info) {
|
|
127
|
+
fragments.push(
|
|
128
|
+
dialectInfo({
|
|
129
|
+
dialect: ctx.info.dialect,
|
|
130
|
+
version: ctx.info.version,
|
|
131
|
+
database: ctx.info.database
|
|
132
|
+
})
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
for (const t of ctx.tables) {
|
|
136
|
+
fragments.push(this.#tableToFragment(t));
|
|
137
|
+
}
|
|
138
|
+
for (const v of ctx.views) {
|
|
139
|
+
fragments.push(this.#viewToFragment(v));
|
|
140
|
+
}
|
|
141
|
+
const tableMap = new Map(ctx.tables.map((t) => [t.name, t]));
|
|
142
|
+
for (const rel of ctx.relationships) {
|
|
143
|
+
const sourceTable = tableMap.get(rel.table);
|
|
144
|
+
const targetTable = tableMap.get(rel.referenced_table);
|
|
145
|
+
fragments.push(
|
|
146
|
+
this.#relationshipToFragment(rel, sourceTable, targetTable)
|
|
147
|
+
);
|
|
21
148
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
149
|
+
if (ctx.report) {
|
|
150
|
+
fragments.push({ name: "businessContext", data: ctx.report });
|
|
151
|
+
}
|
|
152
|
+
return fragments;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Convert a Table to a table fragment with nested column, index, and constraint fragments.
|
|
156
|
+
*/
|
|
157
|
+
#tableToFragment(t) {
|
|
158
|
+
const pkConstraint = t.constraints?.find((c) => c.type === "PRIMARY_KEY");
|
|
159
|
+
const pkColumns = new Set(pkConstraint?.columns ?? []);
|
|
160
|
+
const notNullColumns = new Set(
|
|
161
|
+
t.constraints?.filter((c) => c.type === "NOT_NULL").flatMap((c) => c.columns ?? []) ?? []
|
|
162
|
+
);
|
|
163
|
+
const defaultByColumn = /* @__PURE__ */ new Map();
|
|
164
|
+
for (const c of t.constraints?.filter((c2) => c2.type === "DEFAULT") ?? []) {
|
|
165
|
+
for (const col of c.columns ?? []) {
|
|
166
|
+
if (c.defaultValue != null) {
|
|
167
|
+
defaultByColumn.set(col, c.defaultValue);
|
|
168
|
+
}
|
|
26
169
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
170
|
+
}
|
|
171
|
+
const uniqueColumns = new Set(
|
|
172
|
+
t.constraints?.filter((c) => c.type === "UNIQUE" && c.columns?.length === 1).flatMap((c) => c.columns ?? []) ?? []
|
|
173
|
+
);
|
|
174
|
+
const fkByColumn = /* @__PURE__ */ new Map();
|
|
175
|
+
for (const c of t.constraints?.filter((c2) => c2.type === "FOREIGN_KEY") ?? []) {
|
|
176
|
+
const cols = c.columns ?? [];
|
|
177
|
+
const refCols = c.referencedColumns ?? [];
|
|
178
|
+
for (let i = 0; i < cols.length; i++) {
|
|
179
|
+
const refCol = refCols[i] ?? refCols[0] ?? cols[i];
|
|
180
|
+
fkByColumn.set(cols[i], `${c.referencedTable}.${refCol}`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const columnFragments = t.columns.map(
|
|
184
|
+
(col) => column({
|
|
185
|
+
name: col.name,
|
|
186
|
+
type: col.type,
|
|
187
|
+
pk: pkColumns.has(col.name) || void 0,
|
|
188
|
+
fk: fkByColumn.get(col.name),
|
|
189
|
+
unique: uniqueColumns.has(col.name) || void 0,
|
|
190
|
+
notNull: notNullColumns.has(col.name) || void 0,
|
|
191
|
+
default: defaultByColumn.get(col.name),
|
|
192
|
+
indexed: col.isIndexed || void 0,
|
|
193
|
+
values: col.values,
|
|
194
|
+
stats: col.stats
|
|
195
|
+
})
|
|
196
|
+
);
|
|
197
|
+
const indexFragments = (t.indexes ?? []).map(
|
|
198
|
+
(idx) => index({
|
|
199
|
+
name: idx.name,
|
|
200
|
+
columns: idx.columns,
|
|
201
|
+
unique: idx.unique,
|
|
202
|
+
type: idx.type
|
|
203
|
+
})
|
|
204
|
+
);
|
|
205
|
+
const constraintFragments = (t.constraints ?? []).filter(
|
|
206
|
+
(c) => c.type === "CHECK" || c.type === "UNIQUE" && (c.columns?.length ?? 0) > 1
|
|
207
|
+
).map(
|
|
208
|
+
(c) => constraint({
|
|
209
|
+
name: c.name,
|
|
210
|
+
type: c.type,
|
|
211
|
+
columns: c.columns,
|
|
212
|
+
definition: c.definition
|
|
213
|
+
})
|
|
214
|
+
);
|
|
215
|
+
return table({
|
|
216
|
+
name: t.name,
|
|
217
|
+
schema: t.schema,
|
|
218
|
+
rowCount: t.rowCount,
|
|
219
|
+
sizeHint: t.sizeHint,
|
|
220
|
+
columns: columnFragments,
|
|
221
|
+
indexes: indexFragments.length > 0 ? indexFragments : void 0,
|
|
222
|
+
constraints: constraintFragments.length > 0 ? constraintFragments : void 0
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Convert a View to a view fragment with nested column fragments.
|
|
227
|
+
*/
|
|
228
|
+
#viewToFragment(v) {
|
|
229
|
+
const columnFragments = v.columns.map(
|
|
230
|
+
(col) => column({
|
|
231
|
+
name: col.name,
|
|
232
|
+
type: col.type,
|
|
233
|
+
values: col.values,
|
|
234
|
+
stats: col.stats
|
|
235
|
+
})
|
|
236
|
+
);
|
|
237
|
+
return view({
|
|
238
|
+
name: v.name,
|
|
239
|
+
schema: v.schema,
|
|
240
|
+
columns: columnFragments,
|
|
241
|
+
definition: v.definition
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Convert a Relationship to a relationship fragment.
|
|
246
|
+
* Infers cardinality from row counts if available.
|
|
247
|
+
*/
|
|
248
|
+
#relationshipToFragment(rel, sourceTable, targetTable) {
|
|
249
|
+
const sourceCount = sourceTable?.rowCount;
|
|
250
|
+
const targetCount = targetTable?.rowCount;
|
|
251
|
+
let cardinality;
|
|
252
|
+
if (sourceCount != null && targetCount != null && targetCount > 0) {
|
|
253
|
+
const ratio = sourceCount / targetCount;
|
|
254
|
+
if (ratio > 5) {
|
|
255
|
+
cardinality = "many-to-one";
|
|
256
|
+
} else if (ratio < 1.2 && ratio > 0.8) {
|
|
257
|
+
cardinality = "one-to-one";
|
|
258
|
+
} else if (ratio < 0.2) {
|
|
259
|
+
cardinality = "one-to-many";
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return relationship({
|
|
263
|
+
from: { table: rel.table, columns: rel.from },
|
|
264
|
+
to: { table: rel.referenced_table, columns: rel.to },
|
|
265
|
+
cardinality
|
|
266
|
+
});
|
|
31
267
|
}
|
|
32
268
|
/**
|
|
33
269
|
* Convert unknown database value to number.
|
|
@@ -83,16 +319,19 @@ ${description}
|
|
|
83
319
|
|
|
84
320
|
// packages/text2sql/src/lib/adapters/groundings/abstract.grounding.ts
|
|
85
321
|
var AbstractGrounding = class {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
322
|
+
/**
|
|
323
|
+
* Grounding identifier for debugging/logging.
|
|
324
|
+
*/
|
|
325
|
+
name;
|
|
326
|
+
constructor(name) {
|
|
327
|
+
this.name = name;
|
|
89
328
|
}
|
|
90
329
|
};
|
|
91
330
|
|
|
92
331
|
// packages/text2sql/src/lib/adapters/groundings/column-stats.grounding.ts
|
|
93
332
|
var ColumnStatsGrounding = class extends AbstractGrounding {
|
|
94
333
|
constructor(config = {}) {
|
|
95
|
-
super("
|
|
334
|
+
super("columnStats");
|
|
96
335
|
}
|
|
97
336
|
/**
|
|
98
337
|
* Execute the grounding process.
|
|
@@ -101,26 +340,22 @@ var ColumnStatsGrounding = class extends AbstractGrounding {
|
|
|
101
340
|
async execute(ctx) {
|
|
102
341
|
const allContainers = [...ctx.tables, ...ctx.views];
|
|
103
342
|
for (const container of allContainers) {
|
|
104
|
-
for (const
|
|
343
|
+
for (const column2 of container.columns) {
|
|
105
344
|
try {
|
|
106
|
-
const stats = await this.collectStats(container.name,
|
|
345
|
+
const stats = await this.collectStats(container.name, column2);
|
|
107
346
|
if (stats) {
|
|
108
|
-
|
|
347
|
+
column2.stats = stats;
|
|
109
348
|
}
|
|
110
349
|
} catch (error) {
|
|
111
350
|
console.warn(
|
|
112
351
|
"Error collecting stats for",
|
|
113
352
|
container.name,
|
|
114
|
-
|
|
353
|
+
column2.name,
|
|
115
354
|
error
|
|
116
355
|
);
|
|
117
356
|
}
|
|
118
357
|
}
|
|
119
358
|
}
|
|
120
|
-
return () => this.#describe();
|
|
121
|
-
}
|
|
122
|
-
#describe() {
|
|
123
|
-
return null;
|
|
124
359
|
}
|
|
125
360
|
};
|
|
126
361
|
|
|
@@ -128,7 +363,7 @@ var ColumnStatsGrounding = class extends AbstractGrounding {
|
|
|
128
363
|
var ColumnValuesGrounding = class extends AbstractGrounding {
|
|
129
364
|
lowCardinalityLimit;
|
|
130
365
|
constructor(config = {}) {
|
|
131
|
-
super("
|
|
366
|
+
super("columnValues");
|
|
132
367
|
this.lowCardinalityLimit = config.lowCardinalityLimit ?? 20;
|
|
133
368
|
}
|
|
134
369
|
/**
|
|
@@ -146,14 +381,14 @@ var ColumnValuesGrounding = class extends AbstractGrounding {
|
|
|
146
381
|
* - CHECK ((status)::text = ANY (ARRAY['a'::text, 'b'::text]))
|
|
147
382
|
* - CHECK (status = 'active' OR status = 'inactive')
|
|
148
383
|
*/
|
|
149
|
-
parseCheckConstraint(
|
|
150
|
-
if (
|
|
384
|
+
parseCheckConstraint(constraint2, columnName) {
|
|
385
|
+
if (constraint2.type !== "CHECK" || !constraint2.definition) {
|
|
151
386
|
return void 0;
|
|
152
387
|
}
|
|
153
|
-
if (
|
|
388
|
+
if (constraint2.columns && !constraint2.columns.includes(columnName)) {
|
|
154
389
|
return void 0;
|
|
155
390
|
}
|
|
156
|
-
const def =
|
|
391
|
+
const def = constraint2.definition;
|
|
157
392
|
const escapedCol = this.escapeRegex(columnName);
|
|
158
393
|
const colPattern = `(?:\\(?\\(?${escapedCol}\\)?(?:::(?:text|varchar|character varying))?\\)?)`;
|
|
159
394
|
const inMatch = def.match(
|
|
@@ -211,107 +446,101 @@ var ColumnValuesGrounding = class extends AbstractGrounding {
|
|
|
211
446
|
async execute(ctx) {
|
|
212
447
|
const allContainers = [...ctx.tables, ...ctx.views];
|
|
213
448
|
for (const container of allContainers) {
|
|
214
|
-
const
|
|
215
|
-
for (const
|
|
449
|
+
const table2 = this.getTable(ctx, container.name);
|
|
450
|
+
for (const column2 of container.columns) {
|
|
216
451
|
try {
|
|
217
452
|
const result = await this.resolveColumnValues(
|
|
218
453
|
container.name,
|
|
219
|
-
|
|
220
|
-
|
|
454
|
+
column2,
|
|
455
|
+
table2?.constraints
|
|
221
456
|
);
|
|
222
457
|
if (result) {
|
|
223
|
-
|
|
224
|
-
|
|
458
|
+
column2.kind = result.kind;
|
|
459
|
+
column2.values = result.values;
|
|
225
460
|
}
|
|
226
461
|
} catch (error) {
|
|
227
462
|
console.warn(
|
|
228
463
|
"Error collecting column values for",
|
|
229
464
|
container.name,
|
|
230
|
-
|
|
465
|
+
column2.name,
|
|
231
466
|
error
|
|
232
467
|
);
|
|
233
468
|
}
|
|
234
469
|
}
|
|
235
470
|
}
|
|
236
|
-
return () => this.#describe();
|
|
237
471
|
}
|
|
238
472
|
/**
|
|
239
473
|
* Resolve column values from all sources in priority order.
|
|
240
474
|
*/
|
|
241
|
-
async resolveColumnValues(tableName,
|
|
242
|
-
const enumValues = await this.collectEnumValues(tableName,
|
|
475
|
+
async resolveColumnValues(tableName, column2, constraints2) {
|
|
476
|
+
const enumValues = await this.collectEnumValues(tableName, column2);
|
|
243
477
|
if (enumValues?.length) {
|
|
244
478
|
return { kind: "Enum", values: enumValues };
|
|
245
479
|
}
|
|
246
480
|
if (constraints2) {
|
|
247
|
-
for (const
|
|
248
|
-
const checkValues = this.parseCheckConstraint(
|
|
481
|
+
for (const constraint2 of constraints2) {
|
|
482
|
+
const checkValues = this.parseCheckConstraint(constraint2, column2.name);
|
|
249
483
|
if (checkValues?.length) {
|
|
250
484
|
return { kind: "Enum", values: checkValues };
|
|
251
485
|
}
|
|
252
486
|
}
|
|
253
487
|
}
|
|
254
|
-
const lowCardValues = await this.collectLowCardinality(tableName,
|
|
488
|
+
const lowCardValues = await this.collectLowCardinality(tableName, column2);
|
|
255
489
|
if (lowCardValues?.length) {
|
|
256
490
|
return { kind: "LowCardinality", values: lowCardValues };
|
|
257
491
|
}
|
|
258
492
|
return void 0;
|
|
259
493
|
}
|
|
260
|
-
#describe() {
|
|
261
|
-
return null;
|
|
262
|
-
}
|
|
263
494
|
};
|
|
264
495
|
|
|
265
496
|
// packages/text2sql/src/lib/adapters/groundings/constraint.grounding.ts
|
|
266
497
|
var ConstraintGrounding = class extends AbstractGrounding {
|
|
267
498
|
constructor(config = {}) {
|
|
268
|
-
super("
|
|
499
|
+
super("constraint");
|
|
269
500
|
}
|
|
270
501
|
/**
|
|
271
502
|
* Execute the grounding process.
|
|
272
503
|
* Annotates tables in ctx.tables with their constraints.
|
|
273
504
|
*/
|
|
274
505
|
async execute(ctx) {
|
|
275
|
-
for (const
|
|
506
|
+
for (const table2 of ctx.tables) {
|
|
276
507
|
try {
|
|
277
|
-
|
|
508
|
+
table2.constraints = await this.getConstraints(table2.name);
|
|
278
509
|
} catch (error) {
|
|
279
|
-
console.warn("Error collecting constraints for",
|
|
510
|
+
console.warn("Error collecting constraints for", table2.name, error);
|
|
280
511
|
}
|
|
281
512
|
}
|
|
282
|
-
return () => null;
|
|
283
513
|
}
|
|
284
514
|
};
|
|
285
515
|
|
|
286
516
|
// packages/text2sql/src/lib/adapters/groundings/indexes.grounding.ts
|
|
287
517
|
var IndexesGrounding = class extends AbstractGrounding {
|
|
288
518
|
constructor(config = {}) {
|
|
289
|
-
super("
|
|
519
|
+
super("index");
|
|
290
520
|
}
|
|
291
521
|
/**
|
|
292
522
|
* Execute the grounding process.
|
|
293
523
|
* Annotates tables in ctx.tables with their indexes and marks indexed columns.
|
|
294
524
|
*/
|
|
295
525
|
async execute(ctx) {
|
|
296
|
-
for (const
|
|
297
|
-
|
|
298
|
-
for (const
|
|
299
|
-
for (const colName of
|
|
300
|
-
const
|
|
301
|
-
if (
|
|
302
|
-
|
|
526
|
+
for (const table2 of ctx.tables) {
|
|
527
|
+
table2.indexes = await this.getIndexes(table2.name);
|
|
528
|
+
for (const index2 of table2.indexes ?? []) {
|
|
529
|
+
for (const colName of index2.columns) {
|
|
530
|
+
const column2 = table2.columns.find((c) => c.name === colName);
|
|
531
|
+
if (column2) {
|
|
532
|
+
column2.isIndexed = true;
|
|
303
533
|
}
|
|
304
534
|
}
|
|
305
535
|
}
|
|
306
536
|
}
|
|
307
|
-
return () => null;
|
|
308
537
|
}
|
|
309
538
|
};
|
|
310
539
|
|
|
311
540
|
// packages/text2sql/src/lib/adapters/groundings/info.grounding.ts
|
|
312
541
|
var InfoGrounding = class extends AbstractGrounding {
|
|
313
542
|
constructor(config = {}) {
|
|
314
|
-
super("
|
|
543
|
+
super("dialectInfo");
|
|
315
544
|
}
|
|
316
545
|
/**
|
|
317
546
|
* Execute the grounding process.
|
|
@@ -319,17 +548,6 @@ var InfoGrounding = class extends AbstractGrounding {
|
|
|
319
548
|
*/
|
|
320
549
|
async execute(ctx) {
|
|
321
550
|
ctx.info = await this.collectInfo();
|
|
322
|
-
const lines = [`Dialect: ${ctx.info.dialect ?? "unknown"}`];
|
|
323
|
-
if (ctx.info.version) {
|
|
324
|
-
lines.push(`Version: ${ctx.info.version}`);
|
|
325
|
-
}
|
|
326
|
-
if (ctx.info.database) {
|
|
327
|
-
lines.push(`Database: ${ctx.info.database}`);
|
|
328
|
-
}
|
|
329
|
-
if (ctx.info.details && Object.keys(ctx.info.details).length) {
|
|
330
|
-
lines.push(`Details: ${JSON.stringify(ctx.info.details)}`);
|
|
331
|
-
}
|
|
332
|
-
return () => lines.join("\n");
|
|
333
551
|
}
|
|
334
552
|
};
|
|
335
553
|
|
|
@@ -402,7 +620,7 @@ var ReportGrounding = class extends AbstractGrounding {
|
|
|
402
620
|
const cached = await this.#cache.get();
|
|
403
621
|
if (cached) {
|
|
404
622
|
ctx.report = cached;
|
|
405
|
-
return
|
|
623
|
+
return;
|
|
406
624
|
}
|
|
407
625
|
}
|
|
408
626
|
const report2 = await this.#generateReport();
|
|
@@ -410,7 +628,6 @@ var ReportGrounding = class extends AbstractGrounding {
|
|
|
410
628
|
if (this.#cache) {
|
|
411
629
|
await this.#cache.set(report2);
|
|
412
630
|
}
|
|
413
|
-
return () => report2;
|
|
414
631
|
}
|
|
415
632
|
async #generateReport() {
|
|
416
633
|
const { text } = await generate(
|
|
@@ -429,21 +646,20 @@ var ReportGrounding = class extends AbstractGrounding {
|
|
|
429
646
|
// packages/text2sql/src/lib/adapters/groundings/row-count.grounding.ts
|
|
430
647
|
var RowCountGrounding = class extends AbstractGrounding {
|
|
431
648
|
constructor(config = {}) {
|
|
432
|
-
super("
|
|
649
|
+
super("rowCount");
|
|
433
650
|
}
|
|
434
651
|
/**
|
|
435
652
|
* Execute the grounding process.
|
|
436
653
|
* Annotates tables in ctx.tables with row counts and size hints.
|
|
437
654
|
*/
|
|
438
655
|
async execute(ctx) {
|
|
439
|
-
for (const
|
|
440
|
-
const count = await this.getRowCount(
|
|
656
|
+
for (const table2 of ctx.tables) {
|
|
657
|
+
const count = await this.getRowCount(table2.name);
|
|
441
658
|
if (count != null) {
|
|
442
|
-
|
|
443
|
-
|
|
659
|
+
table2.rowCount = count;
|
|
660
|
+
table2.sizeHint = this.#classifyRowCount(count);
|
|
444
661
|
}
|
|
445
662
|
}
|
|
446
|
-
return () => null;
|
|
447
663
|
}
|
|
448
664
|
/**
|
|
449
665
|
* Classify row count into a size hint category.
|
|
@@ -458,13 +674,12 @@ var RowCountGrounding = class extends AbstractGrounding {
|
|
|
458
674
|
};
|
|
459
675
|
|
|
460
676
|
// packages/text2sql/src/lib/adapters/groundings/table.grounding.ts
|
|
461
|
-
import pluralize from "pluralize";
|
|
462
677
|
var TableGrounding = class extends AbstractGrounding {
|
|
463
678
|
#filter;
|
|
464
679
|
#forward;
|
|
465
680
|
#backward;
|
|
466
681
|
constructor(config = {}) {
|
|
467
|
-
super("
|
|
682
|
+
super("table");
|
|
468
683
|
this.#filter = config.filter;
|
|
469
684
|
this.#forward = config.forward;
|
|
470
685
|
this.#backward = config.backward;
|
|
@@ -482,7 +697,7 @@ var TableGrounding = class extends AbstractGrounding {
|
|
|
482
697
|
seedTables.map((name) => this.getTable(name))
|
|
483
698
|
);
|
|
484
699
|
ctx.tables.push(...tables3);
|
|
485
|
-
return
|
|
700
|
+
return;
|
|
486
701
|
}
|
|
487
702
|
const tables2 = {};
|
|
488
703
|
const allRelationships = [];
|
|
@@ -538,7 +753,6 @@ var TableGrounding = class extends AbstractGrounding {
|
|
|
538
753
|
const tablesList = Object.values(tables2);
|
|
539
754
|
ctx.tables.push(...tablesList);
|
|
540
755
|
ctx.relationships.push(...allRelationships);
|
|
541
|
-
return () => this.#describeTables(tablesList);
|
|
542
756
|
}
|
|
543
757
|
/**
|
|
544
758
|
* Apply the filter to get seed table names.
|
|
@@ -568,156 +782,6 @@ var TableGrounding = class extends AbstractGrounding {
|
|
|
568
782
|
all.push(rel);
|
|
569
783
|
}
|
|
570
784
|
}
|
|
571
|
-
#describeTables(tables2) {
|
|
572
|
-
if (!tables2.length) {
|
|
573
|
-
return "Schema unavailable.";
|
|
574
|
-
}
|
|
575
|
-
return tables2.map((table) => {
|
|
576
|
-
const rowCountInfo = table.rowCount != null ? ` [rows: ${table.rowCount}${table.sizeHint ? `, size: ${table.sizeHint}` : ""}]` : "";
|
|
577
|
-
const pkConstraint = table.constraints?.find(
|
|
578
|
-
(c) => c.type === "PRIMARY_KEY"
|
|
579
|
-
);
|
|
580
|
-
const pkColumns = new Set(pkConstraint?.columns ?? []);
|
|
581
|
-
const notNullColumns = new Set(
|
|
582
|
-
table.constraints?.filter((c) => c.type === "NOT_NULL").flatMap((c) => c.columns ?? []) ?? []
|
|
583
|
-
);
|
|
584
|
-
const defaultByColumn = /* @__PURE__ */ new Map();
|
|
585
|
-
for (const c of table.constraints?.filter(
|
|
586
|
-
(c2) => c2.type === "DEFAULT"
|
|
587
|
-
) ?? []) {
|
|
588
|
-
for (const col of c.columns ?? []) {
|
|
589
|
-
if (c.defaultValue != null) {
|
|
590
|
-
defaultByColumn.set(col, c.defaultValue);
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
const uniqueColumns = new Set(
|
|
595
|
-
table.constraints?.filter((c) => c.type === "UNIQUE" && c.columns?.length === 1).flatMap((c) => c.columns ?? []) ?? []
|
|
596
|
-
);
|
|
597
|
-
const fkByColumn = /* @__PURE__ */ new Map();
|
|
598
|
-
for (const c of table.constraints?.filter(
|
|
599
|
-
(c2) => c2.type === "FOREIGN_KEY"
|
|
600
|
-
) ?? []) {
|
|
601
|
-
const cols = c.columns ?? [];
|
|
602
|
-
const refCols = c.referencedColumns ?? [];
|
|
603
|
-
for (let i = 0; i < cols.length; i++) {
|
|
604
|
-
const refCol = refCols[i] ?? refCols[0] ?? cols[i];
|
|
605
|
-
fkByColumn.set(cols[i], `${c.referencedTable}.${refCol}`);
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
const columns = table.columns.map((column) => {
|
|
609
|
-
const annotations = [];
|
|
610
|
-
const isPrimaryKey = pkColumns.has(column.name);
|
|
611
|
-
if (isPrimaryKey) {
|
|
612
|
-
annotations.push("PK");
|
|
613
|
-
}
|
|
614
|
-
if (fkByColumn.has(column.name)) {
|
|
615
|
-
annotations.push(`FK -> ${fkByColumn.get(column.name)}`);
|
|
616
|
-
}
|
|
617
|
-
if (uniqueColumns.has(column.name)) {
|
|
618
|
-
annotations.push("UNIQUE");
|
|
619
|
-
}
|
|
620
|
-
if (notNullColumns.has(column.name)) {
|
|
621
|
-
annotations.push("NOT NULL");
|
|
622
|
-
}
|
|
623
|
-
if (defaultByColumn.has(column.name)) {
|
|
624
|
-
annotations.push(`DEFAULT: ${defaultByColumn.get(column.name)}`);
|
|
625
|
-
}
|
|
626
|
-
if (column.isIndexed && !isPrimaryKey) {
|
|
627
|
-
annotations.push("Indexed");
|
|
628
|
-
}
|
|
629
|
-
if (column.kind === "Enum" && column.values?.length) {
|
|
630
|
-
annotations.push(`Enum: ${column.values.join(", ")}`);
|
|
631
|
-
} else if (column.kind === "LowCardinality" && column.values?.length) {
|
|
632
|
-
annotations.push(`LowCardinality: ${column.values.join(", ")}`);
|
|
633
|
-
}
|
|
634
|
-
if (column.stats) {
|
|
635
|
-
const statParts = [];
|
|
636
|
-
if (column.stats.min != null || column.stats.max != null) {
|
|
637
|
-
const minText = column.stats.min ?? "n/a";
|
|
638
|
-
const maxText = column.stats.max ?? "n/a";
|
|
639
|
-
statParts.push(`range ${minText} \u2192 ${maxText}`);
|
|
640
|
-
}
|
|
641
|
-
if (column.stats.nullFraction != null && Number.isFinite(column.stats.nullFraction)) {
|
|
642
|
-
const percent = Math.round(column.stats.nullFraction * 1e3) / 10;
|
|
643
|
-
statParts.push(`null\u2248${percent}%`);
|
|
644
|
-
}
|
|
645
|
-
if (statParts.length) {
|
|
646
|
-
annotations.push(statParts.join(", "));
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
const annotationText = annotations.length ? ` [${annotations.join(", ")}]` : "";
|
|
650
|
-
return ` - ${column.name} (${column.type})${annotationText}`;
|
|
651
|
-
}).join("\n");
|
|
652
|
-
const indexes2 = table.indexes?.length ? `
|
|
653
|
-
Indexes:
|
|
654
|
-
${table.indexes.map((index) => {
|
|
655
|
-
const props = [];
|
|
656
|
-
if (index.unique) {
|
|
657
|
-
props.push("UNIQUE");
|
|
658
|
-
}
|
|
659
|
-
if (index.type) {
|
|
660
|
-
props.push(index.type);
|
|
661
|
-
}
|
|
662
|
-
const propsText = props.length ? ` (${props.join(", ")})` : "";
|
|
663
|
-
const columnsText = index.columns?.length ? index.columns.join(", ") : "expression";
|
|
664
|
-
return ` - ${index.name}${propsText}: ${columnsText}`;
|
|
665
|
-
}).join("\n")}` : "";
|
|
666
|
-
const multiColumnUniques = table.constraints?.filter(
|
|
667
|
-
(c) => c.type === "UNIQUE" && (c.columns?.length ?? 0) > 1
|
|
668
|
-
) ?? [];
|
|
669
|
-
const uniqueConstraints = multiColumnUniques.length ? `
|
|
670
|
-
Unique Constraints:
|
|
671
|
-
${multiColumnUniques.map((c) => ` - ${c.name}: (${c.columns?.join(", ")})`).join("\n")}` : "";
|
|
672
|
-
const checkConstraints = table.constraints?.filter((c) => c.type === "CHECK") ?? [];
|
|
673
|
-
const checks = checkConstraints.length ? `
|
|
674
|
-
Check Constraints:
|
|
675
|
-
${checkConstraints.map((c) => ` - ${c.name}: ${c.definition}`).join("\n")}` : "";
|
|
676
|
-
return `- Table: ${table.name}${rowCountInfo}
|
|
677
|
-
Columns:
|
|
678
|
-
${columns}${indexes2}${uniqueConstraints}${checks}`;
|
|
679
|
-
}).join("\n\n");
|
|
680
|
-
}
|
|
681
|
-
#formatTableLabel = (tableName) => {
|
|
682
|
-
const base = tableName.split(".").pop() ?? tableName;
|
|
683
|
-
return base.replace(/_/g, " ");
|
|
684
|
-
};
|
|
685
|
-
#describeRelationships = (tables2, relationships) => {
|
|
686
|
-
if (!relationships.length) {
|
|
687
|
-
return "None detected";
|
|
688
|
-
}
|
|
689
|
-
const tableMap = new Map(tables2.map((table) => [table.name, table]));
|
|
690
|
-
return relationships.map((relationship) => {
|
|
691
|
-
const sourceLabel = this.#formatTableLabel(relationship.table);
|
|
692
|
-
const targetLabel = this.#formatTableLabel(
|
|
693
|
-
relationship.referenced_table
|
|
694
|
-
);
|
|
695
|
-
const singularSource = pluralize.singular(sourceLabel);
|
|
696
|
-
const pluralSource = pluralize.plural(sourceLabel);
|
|
697
|
-
const singularTarget = pluralize.singular(targetLabel);
|
|
698
|
-
const pluralTarget = pluralize.plural(targetLabel);
|
|
699
|
-
const sourceTable = tableMap.get(relationship.table);
|
|
700
|
-
const targetTable = tableMap.get(relationship.referenced_table);
|
|
701
|
-
const sourceCount = sourceTable?.rowCount;
|
|
702
|
-
const targetCount = targetTable?.rowCount;
|
|
703
|
-
const ratio = sourceCount != null && targetCount != null && targetCount > 0 ? sourceCount / targetCount : null;
|
|
704
|
-
let cardinality = "each";
|
|
705
|
-
if (ratio != null) {
|
|
706
|
-
if (ratio > 5) {
|
|
707
|
-
cardinality = `many-to-one (\u2248${sourceCount} vs ${targetCount})`;
|
|
708
|
-
} else if (ratio < 1.2 && ratio > 0.8) {
|
|
709
|
-
cardinality = `roughly 1:1 (${sourceCount} vs ${targetCount})`;
|
|
710
|
-
} else if (ratio < 0.2) {
|
|
711
|
-
cardinality = `one-to-many (${sourceCount} vs ${targetCount})`;
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
const mappings = relationship.from.map((fromCol, idx) => {
|
|
715
|
-
const targetCol = relationship.to[idx] ?? relationship.to[0] ?? fromCol;
|
|
716
|
-
return `${relationship.table}.${fromCol} -> ${relationship.referenced_table}.${targetCol}`;
|
|
717
|
-
}).join(", ");
|
|
718
|
-
return `- ${relationship.table} (${relationship.from.join(", ")}) -> ${relationship.referenced_table} (${relationship.to.join(", ")}) [${cardinality}]`;
|
|
719
|
-
}).join("\n");
|
|
720
|
-
};
|
|
721
785
|
};
|
|
722
786
|
|
|
723
787
|
// packages/text2sql/src/lib/adapters/mysql/column-stats.mysql.grounding.ts
|
|
@@ -727,14 +791,14 @@ var MysqlColumnStatsGrounding = class extends ColumnStatsGrounding {
|
|
|
727
791
|
super(config);
|
|
728
792
|
this.#adapter = adapter;
|
|
729
793
|
}
|
|
730
|
-
async collectStats(tableName,
|
|
731
|
-
if (!this.#shouldCollectStats(
|
|
794
|
+
async collectStats(tableName, column2) {
|
|
795
|
+
if (!this.#shouldCollectStats(column2.type)) {
|
|
732
796
|
return void 0;
|
|
733
797
|
}
|
|
734
|
-
const { schema, table } = this.#adapter.parseTableName(tableName);
|
|
798
|
+
const { schema, table: table2 } = this.#adapter.parseTableName(tableName);
|
|
735
799
|
const database = schema || await this.#getCurrentDatabase();
|
|
736
|
-
const tableIdentifier = `${this.#adapter.quoteIdentifier(database)}.${this.#adapter.quoteIdentifier(
|
|
737
|
-
const columnIdentifier = this.#adapter.quoteIdentifier(
|
|
800
|
+
const tableIdentifier = `${this.#adapter.quoteIdentifier(database)}.${this.#adapter.quoteIdentifier(table2)}`;
|
|
801
|
+
const columnIdentifier = this.#adapter.quoteIdentifier(column2.name);
|
|
738
802
|
try {
|
|
739
803
|
const rows = await this.#adapter.runQuery(`
|
|
740
804
|
SELECT
|
|
@@ -801,15 +865,15 @@ var MysqlColumnValuesGrounding = class extends ColumnValuesGrounding {
|
|
|
801
865
|
/**
|
|
802
866
|
* Detect native MySQL ENUM types and extract their values.
|
|
803
867
|
*/
|
|
804
|
-
async collectEnumValues(tableName,
|
|
805
|
-
const { schema, table } = this.#adapter.parseTableName(tableName);
|
|
868
|
+
async collectEnumValues(tableName, column2) {
|
|
869
|
+
const { schema, table: table2 } = this.#adapter.parseTableName(tableName);
|
|
806
870
|
const database = schema || await this.#getCurrentDatabase();
|
|
807
871
|
const rows = await this.#adapter.runQuery(`
|
|
808
872
|
SELECT COLUMN_TYPE
|
|
809
873
|
FROM INFORMATION_SCHEMA.COLUMNS
|
|
810
874
|
WHERE TABLE_SCHEMA = '${this.#adapter.escapeString(database)}'
|
|
811
|
-
AND TABLE_NAME = '${this.#adapter.escapeString(
|
|
812
|
-
AND COLUMN_NAME = '${this.#adapter.escapeString(
|
|
875
|
+
AND TABLE_NAME = '${this.#adapter.escapeString(table2)}'
|
|
876
|
+
AND COLUMN_NAME = '${this.#adapter.escapeString(column2.name)}'
|
|
813
877
|
`);
|
|
814
878
|
const columnType = rows[0]?.COLUMN_TYPE;
|
|
815
879
|
if (!columnType) return void 0;
|
|
@@ -820,11 +884,11 @@ var MysqlColumnValuesGrounding = class extends ColumnValuesGrounding {
|
|
|
820
884
|
/**
|
|
821
885
|
* Collect distinct values for low cardinality columns.
|
|
822
886
|
*/
|
|
823
|
-
async collectLowCardinality(tableName,
|
|
824
|
-
const { schema, table } = this.#adapter.parseTableName(tableName);
|
|
887
|
+
async collectLowCardinality(tableName, column2) {
|
|
888
|
+
const { schema, table: table2 } = this.#adapter.parseTableName(tableName);
|
|
825
889
|
const database = schema || await this.#getCurrentDatabase();
|
|
826
|
-
const tableIdentifier = `${this.#adapter.quoteIdentifier(database)}.${this.#adapter.quoteIdentifier(
|
|
827
|
-
const columnIdentifier = this.#adapter.quoteIdentifier(
|
|
890
|
+
const tableIdentifier = `${this.#adapter.quoteIdentifier(database)}.${this.#adapter.quoteIdentifier(table2)}`;
|
|
891
|
+
const columnIdentifier = this.#adapter.quoteIdentifier(column2.name);
|
|
828
892
|
const limit = this.lowCardinalityLimit + 1;
|
|
829
893
|
try {
|
|
830
894
|
const rows = await this.#adapter.runQuery(`
|
|
@@ -901,7 +965,7 @@ var MysqlConstraintGrounding = class extends ConstraintGrounding {
|
|
|
901
965
|
this.#adapter = adapter;
|
|
902
966
|
}
|
|
903
967
|
async getConstraints(tableName) {
|
|
904
|
-
const { schema, table } = this.#adapter.parseTableName(tableName);
|
|
968
|
+
const { schema, table: table2 } = this.#adapter.parseTableName(tableName);
|
|
905
969
|
const database = schema || await this.#getCurrentDatabase();
|
|
906
970
|
const constraints2 = [];
|
|
907
971
|
const constraintRows = await this.#adapter.runQuery(`
|
|
@@ -918,7 +982,7 @@ var MysqlConstraintGrounding = class extends ConstraintGrounding {
|
|
|
918
982
|
AND tc.TABLE_SCHEMA = kcu.TABLE_SCHEMA
|
|
919
983
|
AND tc.TABLE_NAME = kcu.TABLE_NAME
|
|
920
984
|
WHERE tc.TABLE_SCHEMA = '${this.#adapter.escapeString(database)}'
|
|
921
|
-
AND tc.TABLE_NAME = '${this.#adapter.escapeString(
|
|
985
|
+
AND tc.TABLE_NAME = '${this.#adapter.escapeString(table2)}'
|
|
922
986
|
AND tc.CONSTRAINT_TYPE IN ('PRIMARY KEY', 'UNIQUE', 'FOREIGN KEY')
|
|
923
987
|
ORDER BY tc.CONSTRAINT_NAME, kcu.ORDINAL_POSITION
|
|
924
988
|
`);
|
|
@@ -961,7 +1025,7 @@ var MysqlConstraintGrounding = class extends ConstraintGrounding {
|
|
|
961
1025
|
SELECT COLUMN_NAME, IS_NULLABLE, COLUMN_DEFAULT
|
|
962
1026
|
FROM INFORMATION_SCHEMA.COLUMNS
|
|
963
1027
|
WHERE TABLE_SCHEMA = '${this.#adapter.escapeString(database)}'
|
|
964
|
-
AND TABLE_NAME = '${this.#adapter.escapeString(
|
|
1028
|
+
AND TABLE_NAME = '${this.#adapter.escapeString(table2)}'
|
|
965
1029
|
`);
|
|
966
1030
|
const pkConstraint = constraints2.find((c) => c.type === "PRIMARY_KEY");
|
|
967
1031
|
const pkColumns = new Set(pkConstraint?.columns ?? []);
|
|
@@ -993,7 +1057,7 @@ var MysqlConstraintGrounding = class extends ConstraintGrounding {
|
|
|
993
1057
|
SELECT CONSTRAINT_NAME, TABLE_NAME
|
|
994
1058
|
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
|
|
995
1059
|
WHERE TABLE_SCHEMA = '${this.#adapter.escapeString(database)}'
|
|
996
|
-
AND TABLE_NAME = '${this.#adapter.escapeString(
|
|
1060
|
+
AND TABLE_NAME = '${this.#adapter.escapeString(table2)}'
|
|
997
1061
|
AND CONSTRAINT_TYPE = 'CHECK'
|
|
998
1062
|
`);
|
|
999
1063
|
const checkTableMap = new Map(
|
|
@@ -1001,7 +1065,7 @@ var MysqlConstraintGrounding = class extends ConstraintGrounding {
|
|
|
1001
1065
|
);
|
|
1002
1066
|
for (const row of checkRows) {
|
|
1003
1067
|
if (!row.CONSTRAINT_NAME) continue;
|
|
1004
|
-
if (checkTableMap.get(row.CONSTRAINT_NAME) !==
|
|
1068
|
+
if (checkTableMap.get(row.CONSTRAINT_NAME) !== table2) continue;
|
|
1005
1069
|
constraints2.push({
|
|
1006
1070
|
name: row.CONSTRAINT_NAME,
|
|
1007
1071
|
type: "CHECK",
|
|
@@ -1040,7 +1104,7 @@ var MysqlIndexesGrounding = class extends IndexesGrounding {
|
|
|
1040
1104
|
this.#adapter = adapter;
|
|
1041
1105
|
}
|
|
1042
1106
|
async getIndexes(tableName) {
|
|
1043
|
-
const { schema, table } = this.#adapter.parseTableName(tableName);
|
|
1107
|
+
const { schema, table: table2 } = this.#adapter.parseTableName(tableName);
|
|
1044
1108
|
const database = schema || await this.#getCurrentDatabase();
|
|
1045
1109
|
const rows = await this.#adapter.runQuery(`
|
|
1046
1110
|
SELECT
|
|
@@ -1051,24 +1115,24 @@ var MysqlIndexesGrounding = class extends IndexesGrounding {
|
|
|
1051
1115
|
SEQ_IN_INDEX
|
|
1052
1116
|
FROM INFORMATION_SCHEMA.STATISTICS
|
|
1053
1117
|
WHERE TABLE_SCHEMA = '${this.#adapter.escapeString(database)}'
|
|
1054
|
-
AND TABLE_NAME = '${this.#adapter.escapeString(
|
|
1118
|
+
AND TABLE_NAME = '${this.#adapter.escapeString(table2)}'
|
|
1055
1119
|
ORDER BY INDEX_NAME, SEQ_IN_INDEX
|
|
1056
1120
|
`);
|
|
1057
1121
|
const indexMap = /* @__PURE__ */ new Map();
|
|
1058
1122
|
for (const row of rows) {
|
|
1059
1123
|
if (!row.INDEX_NAME) continue;
|
|
1060
|
-
let
|
|
1061
|
-
if (!
|
|
1062
|
-
|
|
1124
|
+
let index2 = indexMap.get(row.INDEX_NAME);
|
|
1125
|
+
if (!index2) {
|
|
1126
|
+
index2 = {
|
|
1063
1127
|
name: row.INDEX_NAME,
|
|
1064
1128
|
columns: [],
|
|
1065
1129
|
unique: row.NON_UNIQUE === 0,
|
|
1066
1130
|
type: row.INDEX_TYPE ?? void 0
|
|
1067
1131
|
};
|
|
1068
|
-
indexMap.set(row.INDEX_NAME,
|
|
1132
|
+
indexMap.set(row.INDEX_NAME, index2);
|
|
1069
1133
|
}
|
|
1070
1134
|
if (row.COLUMN_NAME) {
|
|
1071
|
-
|
|
1135
|
+
index2.columns.push(row.COLUMN_NAME);
|
|
1072
1136
|
}
|
|
1073
1137
|
}
|
|
1074
1138
|
return Array.from(indexMap.values());
|
|
@@ -1209,8 +1273,8 @@ var Mysql = class extends Adapter {
|
|
|
1209
1273
|
return value.replace(/`/g, "``");
|
|
1210
1274
|
}
|
|
1211
1275
|
buildSampleRowsQuery(tableName, columns, limit) {
|
|
1212
|
-
const { schema, table } = this.parseTableName(tableName);
|
|
1213
|
-
const tableIdentifier = schema ? `${this.quoteIdentifier(schema)}.${this.quoteIdentifier(
|
|
1276
|
+
const { schema, table: table2 } = this.parseTableName(tableName);
|
|
1277
|
+
const tableIdentifier = schema ? `${this.quoteIdentifier(schema)}.${this.quoteIdentifier(table2)}` : this.quoteIdentifier(table2);
|
|
1214
1278
|
const columnList = columns?.length ? columns.map((c) => this.quoteIdentifier(c)).join(", ") : "*";
|
|
1215
1279
|
return `SELECT ${columnList} FROM ${tableIdentifier} LIMIT ${limit}`;
|
|
1216
1280
|
}
|
|
@@ -1245,9 +1309,9 @@ var MysqlRowCountGrounding = class extends RowCountGrounding {
|
|
|
1245
1309
|
this.#adapter = adapter;
|
|
1246
1310
|
}
|
|
1247
1311
|
async getRowCount(tableName) {
|
|
1248
|
-
const { schema, table } = this.#adapter.parseTableName(tableName);
|
|
1312
|
+
const { schema, table: table2 } = this.#adapter.parseTableName(tableName);
|
|
1249
1313
|
const database = schema || await this.#getCurrentDatabase();
|
|
1250
|
-
const tableIdentifier = `${this.#adapter.quoteIdentifier(database)}.${this.#adapter.quoteIdentifier(
|
|
1314
|
+
const tableIdentifier = `${this.#adapter.quoteIdentifier(database)}.${this.#adapter.quoteIdentifier(table2)}`;
|
|
1251
1315
|
try {
|
|
1252
1316
|
const rows = await this.#adapter.runQuery(`SELECT COUNT(*) AS count FROM ${tableIdentifier}`);
|
|
1253
1317
|
return this.#toNumber(rows[0]?.count);
|
|
@@ -1296,19 +1360,19 @@ var MysqlTableGrounding = class extends TableGrounding {
|
|
|
1296
1360
|
return rows.map((r) => r.name);
|
|
1297
1361
|
}
|
|
1298
1362
|
async getTable(tableName) {
|
|
1299
|
-
const { schema, table } = this.#adapter.parseTableName(tableName);
|
|
1363
|
+
const { schema, table: table2 } = this.#adapter.parseTableName(tableName);
|
|
1300
1364
|
const database = schema || await this.#getCurrentDatabase();
|
|
1301
1365
|
const columns = await this.#adapter.runQuery(`
|
|
1302
1366
|
SELECT COLUMN_NAME, DATA_TYPE, COLUMN_TYPE
|
|
1303
1367
|
FROM INFORMATION_SCHEMA.COLUMNS
|
|
1304
1368
|
WHERE TABLE_SCHEMA = '${this.#adapter.escapeString(database)}'
|
|
1305
|
-
AND TABLE_NAME = '${this.#adapter.escapeString(
|
|
1369
|
+
AND TABLE_NAME = '${this.#adapter.escapeString(table2)}'
|
|
1306
1370
|
ORDER BY ORDINAL_POSITION
|
|
1307
1371
|
`);
|
|
1308
1372
|
return {
|
|
1309
1373
|
name: tableName,
|
|
1310
1374
|
schema: database,
|
|
1311
|
-
rawName:
|
|
1375
|
+
rawName: table2,
|
|
1312
1376
|
columns: columns.map((col) => ({
|
|
1313
1377
|
name: col.COLUMN_NAME ?? "unknown",
|
|
1314
1378
|
type: col.DATA_TYPE ?? "unknown"
|
|
@@ -1316,7 +1380,7 @@ var MysqlTableGrounding = class extends TableGrounding {
|
|
|
1316
1380
|
};
|
|
1317
1381
|
}
|
|
1318
1382
|
async findOutgoingRelations(tableName) {
|
|
1319
|
-
const { schema, table } = this.#adapter.parseTableName(tableName);
|
|
1383
|
+
const { schema, table: table2 } = this.#adapter.parseTableName(tableName);
|
|
1320
1384
|
const database = schema || await this.#getCurrentDatabase();
|
|
1321
1385
|
const rows = await this.#adapter.runQuery(`
|
|
1322
1386
|
SELECT
|
|
@@ -1329,14 +1393,14 @@ var MysqlTableGrounding = class extends TableGrounding {
|
|
|
1329
1393
|
kcu.REFERENCED_COLUMN_NAME
|
|
1330
1394
|
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu
|
|
1331
1395
|
WHERE kcu.TABLE_SCHEMA = '${this.#adapter.escapeString(database)}'
|
|
1332
|
-
AND kcu.TABLE_NAME = '${this.#adapter.escapeString(
|
|
1396
|
+
AND kcu.TABLE_NAME = '${this.#adapter.escapeString(table2)}'
|
|
1333
1397
|
AND kcu.REFERENCED_TABLE_NAME IS NOT NULL
|
|
1334
1398
|
ORDER BY kcu.CONSTRAINT_NAME, kcu.ORDINAL_POSITION
|
|
1335
1399
|
`);
|
|
1336
1400
|
return this.#groupRelationships(rows);
|
|
1337
1401
|
}
|
|
1338
1402
|
async findIncomingRelations(tableName) {
|
|
1339
|
-
const { schema, table } = this.#adapter.parseTableName(tableName);
|
|
1403
|
+
const { schema, table: table2 } = this.#adapter.parseTableName(tableName);
|
|
1340
1404
|
const database = schema || await this.#getCurrentDatabase();
|
|
1341
1405
|
const rows = await this.#adapter.runQuery(`
|
|
1342
1406
|
SELECT
|
|
@@ -1349,7 +1413,7 @@ var MysqlTableGrounding = class extends TableGrounding {
|
|
|
1349
1413
|
kcu.REFERENCED_COLUMN_NAME
|
|
1350
1414
|
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu
|
|
1351
1415
|
WHERE kcu.REFERENCED_TABLE_SCHEMA = '${this.#adapter.escapeString(database)}'
|
|
1352
|
-
AND kcu.REFERENCED_TABLE_NAME = '${this.#adapter.escapeString(
|
|
1416
|
+
AND kcu.REFERENCED_TABLE_NAME = '${this.#adapter.escapeString(table2)}'
|
|
1353
1417
|
ORDER BY kcu.CONSTRAINT_NAME, kcu.ORDINAL_POSITION
|
|
1354
1418
|
`);
|
|
1355
1419
|
return this.#groupRelationships(rows);
|
|
@@ -1363,15 +1427,15 @@ var MysqlTableGrounding = class extends TableGrounding {
|
|
|
1363
1427
|
const schema = row.TABLE_SCHEMA ?? "";
|
|
1364
1428
|
const referencedSchema = row.REFERENCED_TABLE_SCHEMA ?? "";
|
|
1365
1429
|
const key = `${schema}.${row.TABLE_NAME}:${row.CONSTRAINT_NAME}`;
|
|
1366
|
-
const
|
|
1430
|
+
const relationship2 = relationships.get(key) ?? {
|
|
1367
1431
|
table: `${schema}.${row.TABLE_NAME}`,
|
|
1368
1432
|
from: [],
|
|
1369
1433
|
referenced_table: `${referencedSchema}.${row.REFERENCED_TABLE_NAME}`,
|
|
1370
1434
|
to: []
|
|
1371
1435
|
};
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
relationships.set(key,
|
|
1436
|
+
relationship2.from.push(row.COLUMN_NAME ?? "unknown");
|
|
1437
|
+
relationship2.to.push(row.REFERENCED_COLUMN_NAME ?? "unknown");
|
|
1438
|
+
relationships.set(key, relationship2);
|
|
1375
1439
|
}
|
|
1376
1440
|
return Array.from(relationships.values());
|
|
1377
1441
|
}
|
|
@@ -1395,7 +1459,7 @@ var MysqlTableGrounding = class extends TableGrounding {
|
|
|
1395
1459
|
var ViewGrounding = class extends AbstractGrounding {
|
|
1396
1460
|
#filter;
|
|
1397
1461
|
constructor(config = {}) {
|
|
1398
|
-
super("
|
|
1462
|
+
super("view");
|
|
1399
1463
|
this.#filter = config.filter;
|
|
1400
1464
|
}
|
|
1401
1465
|
/**
|
|
@@ -1408,42 +1472,6 @@ var ViewGrounding = class extends AbstractGrounding {
|
|
|
1408
1472
|
viewNames.map((name) => this.getView(name))
|
|
1409
1473
|
);
|
|
1410
1474
|
ctx.views.push(...views2);
|
|
1411
|
-
return () => this.#describe(views2);
|
|
1412
|
-
}
|
|
1413
|
-
#describe(views2) {
|
|
1414
|
-
if (!views2.length) {
|
|
1415
|
-
return "No views available.";
|
|
1416
|
-
}
|
|
1417
|
-
return views2.map((view) => {
|
|
1418
|
-
const columns = view.columns.map((column) => {
|
|
1419
|
-
const annotations = [];
|
|
1420
|
-
if (column.kind === "LowCardinality" && column.values?.length) {
|
|
1421
|
-
annotations.push(`LowCardinality: ${column.values.join(", ")}`);
|
|
1422
|
-
}
|
|
1423
|
-
if (column.stats) {
|
|
1424
|
-
const statParts = [];
|
|
1425
|
-
if (column.stats.min != null || column.stats.max != null) {
|
|
1426
|
-
const minText = column.stats.min ?? "n/a";
|
|
1427
|
-
const maxText = column.stats.max ?? "n/a";
|
|
1428
|
-
statParts.push(`range ${minText} \u2192 ${maxText}`);
|
|
1429
|
-
}
|
|
1430
|
-
if (column.stats.nullFraction != null && Number.isFinite(column.stats.nullFraction)) {
|
|
1431
|
-
const percent = Math.round(column.stats.nullFraction * 1e3) / 10;
|
|
1432
|
-
statParts.push(`null\u2248${percent}%`);
|
|
1433
|
-
}
|
|
1434
|
-
if (statParts.length) {
|
|
1435
|
-
annotations.push(statParts.join(", "));
|
|
1436
|
-
}
|
|
1437
|
-
}
|
|
1438
|
-
const annotationText = annotations.length ? ` [${annotations.join(", ")}]` : "";
|
|
1439
|
-
return ` - ${column.name} (${column.type})${annotationText}`;
|
|
1440
|
-
}).join("\n");
|
|
1441
|
-
const definition = view.definition ? `
|
|
1442
|
-
Definition: ${view.definition.length > 200 ? view.definition.slice(0, 200) + "..." : view.definition}` : "";
|
|
1443
|
-
return `- View: ${view.name}${definition}
|
|
1444
|
-
Columns:
|
|
1445
|
-
${columns}`;
|
|
1446
|
-
}).join("\n\n");
|
|
1447
1475
|
}
|
|
1448
1476
|
/**
|
|
1449
1477
|
* Apply the filter to get view names.
|
|
@@ -1485,25 +1513,25 @@ var MysqlViewGrounding = class extends ViewGrounding {
|
|
|
1485
1513
|
return rows.map((r) => r.name);
|
|
1486
1514
|
}
|
|
1487
1515
|
async getView(viewName) {
|
|
1488
|
-
const { schema, table } = this.#adapter.parseTableName(viewName);
|
|
1516
|
+
const { schema, table: table2 } = this.#adapter.parseTableName(viewName);
|
|
1489
1517
|
const database = schema || await this.#getCurrentDatabase();
|
|
1490
1518
|
const columns = await this.#adapter.runQuery(`
|
|
1491
1519
|
SELECT COLUMN_NAME, DATA_TYPE
|
|
1492
1520
|
FROM INFORMATION_SCHEMA.COLUMNS
|
|
1493
1521
|
WHERE TABLE_SCHEMA = '${this.#adapter.escapeString(database)}'
|
|
1494
|
-
AND TABLE_NAME = '${this.#adapter.escapeString(
|
|
1522
|
+
AND TABLE_NAME = '${this.#adapter.escapeString(table2)}'
|
|
1495
1523
|
ORDER BY ORDINAL_POSITION
|
|
1496
1524
|
`);
|
|
1497
1525
|
const viewRows = await this.#adapter.runQuery(`
|
|
1498
1526
|
SELECT VIEW_DEFINITION
|
|
1499
1527
|
FROM INFORMATION_SCHEMA.VIEWS
|
|
1500
1528
|
WHERE TABLE_SCHEMA = '${this.#adapter.escapeString(database)}'
|
|
1501
|
-
AND TABLE_NAME = '${this.#adapter.escapeString(
|
|
1529
|
+
AND TABLE_NAME = '${this.#adapter.escapeString(table2)}'
|
|
1502
1530
|
`);
|
|
1503
1531
|
return {
|
|
1504
1532
|
name: viewName,
|
|
1505
1533
|
schema: database,
|
|
1506
|
-
rawName:
|
|
1534
|
+
rawName: table2,
|
|
1507
1535
|
definition: viewRows[0]?.VIEW_DEFINITION ?? void 0,
|
|
1508
1536
|
columns: columns.map((col) => ({
|
|
1509
1537
|
name: col.COLUMN_NAME ?? "unknown",
|