@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
|
+
);
|
|
148
|
+
}
|
|
149
|
+
if (ctx.report) {
|
|
150
|
+
fragments.push({ name: "businessContext", data: ctx.report });
|
|
21
151
|
}
|
|
22
|
-
return
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
+
}
|
|
169
|
+
}
|
|
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}`);
|
|
26
181
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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,79 +340,73 @@ 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
|
|
|
127
362
|
// packages/text2sql/src/lib/adapters/groundings/constraint.grounding.ts
|
|
128
363
|
var ConstraintGrounding = class extends AbstractGrounding {
|
|
129
364
|
constructor(config = {}) {
|
|
130
|
-
super("
|
|
365
|
+
super("constraint");
|
|
131
366
|
}
|
|
132
367
|
/**
|
|
133
368
|
* Execute the grounding process.
|
|
134
369
|
* Annotates tables in ctx.tables with their constraints.
|
|
135
370
|
*/
|
|
136
371
|
async execute(ctx) {
|
|
137
|
-
for (const
|
|
372
|
+
for (const table2 of ctx.tables) {
|
|
138
373
|
try {
|
|
139
|
-
|
|
374
|
+
table2.constraints = await this.getConstraints(table2.name);
|
|
140
375
|
} catch (error) {
|
|
141
|
-
console.warn("Error collecting constraints for",
|
|
376
|
+
console.warn("Error collecting constraints for", table2.name, error);
|
|
142
377
|
}
|
|
143
378
|
}
|
|
144
|
-
return () => null;
|
|
145
379
|
}
|
|
146
380
|
};
|
|
147
381
|
|
|
148
382
|
// packages/text2sql/src/lib/adapters/groundings/indexes.grounding.ts
|
|
149
383
|
var IndexesGrounding = class extends AbstractGrounding {
|
|
150
384
|
constructor(config = {}) {
|
|
151
|
-
super("
|
|
385
|
+
super("index");
|
|
152
386
|
}
|
|
153
387
|
/**
|
|
154
388
|
* Execute the grounding process.
|
|
155
389
|
* Annotates tables in ctx.tables with their indexes and marks indexed columns.
|
|
156
390
|
*/
|
|
157
391
|
async execute(ctx) {
|
|
158
|
-
for (const
|
|
159
|
-
|
|
160
|
-
for (const
|
|
161
|
-
for (const colName of
|
|
162
|
-
const
|
|
163
|
-
if (
|
|
164
|
-
|
|
392
|
+
for (const table2 of ctx.tables) {
|
|
393
|
+
table2.indexes = await this.getIndexes(table2.name);
|
|
394
|
+
for (const index2 of table2.indexes ?? []) {
|
|
395
|
+
for (const colName of index2.columns) {
|
|
396
|
+
const column2 = table2.columns.find((c) => c.name === colName);
|
|
397
|
+
if (column2) {
|
|
398
|
+
column2.isIndexed = true;
|
|
165
399
|
}
|
|
166
400
|
}
|
|
167
401
|
}
|
|
168
402
|
}
|
|
169
|
-
return () => null;
|
|
170
403
|
}
|
|
171
404
|
};
|
|
172
405
|
|
|
173
406
|
// packages/text2sql/src/lib/adapters/groundings/info.grounding.ts
|
|
174
407
|
var InfoGrounding = class extends AbstractGrounding {
|
|
175
408
|
constructor(config = {}) {
|
|
176
|
-
super("
|
|
409
|
+
super("dialectInfo");
|
|
177
410
|
}
|
|
178
411
|
/**
|
|
179
412
|
* Execute the grounding process.
|
|
@@ -181,17 +414,6 @@ var InfoGrounding = class extends AbstractGrounding {
|
|
|
181
414
|
*/
|
|
182
415
|
async execute(ctx) {
|
|
183
416
|
ctx.info = await this.collectInfo();
|
|
184
|
-
const lines = [`Dialect: ${ctx.info.dialect ?? "unknown"}`];
|
|
185
|
-
if (ctx.info.version) {
|
|
186
|
-
lines.push(`Version: ${ctx.info.version}`);
|
|
187
|
-
}
|
|
188
|
-
if (ctx.info.database) {
|
|
189
|
-
lines.push(`Database: ${ctx.info.database}`);
|
|
190
|
-
}
|
|
191
|
-
if (ctx.info.details && Object.keys(ctx.info.details).length) {
|
|
192
|
-
lines.push(`Details: ${JSON.stringify(ctx.info.details)}`);
|
|
193
|
-
}
|
|
194
|
-
return () => lines.join("\n");
|
|
195
417
|
}
|
|
196
418
|
};
|
|
197
419
|
|
|
@@ -199,7 +421,7 @@ var InfoGrounding = class extends AbstractGrounding {
|
|
|
199
421
|
var ColumnValuesGrounding = class extends AbstractGrounding {
|
|
200
422
|
lowCardinalityLimit;
|
|
201
423
|
constructor(config = {}) {
|
|
202
|
-
super("
|
|
424
|
+
super("columnValues");
|
|
203
425
|
this.lowCardinalityLimit = config.lowCardinalityLimit ?? 20;
|
|
204
426
|
}
|
|
205
427
|
/**
|
|
@@ -217,14 +439,14 @@ var ColumnValuesGrounding = class extends AbstractGrounding {
|
|
|
217
439
|
* - CHECK ((status)::text = ANY (ARRAY['a'::text, 'b'::text]))
|
|
218
440
|
* - CHECK (status = 'active' OR status = 'inactive')
|
|
219
441
|
*/
|
|
220
|
-
parseCheckConstraint(
|
|
221
|
-
if (
|
|
442
|
+
parseCheckConstraint(constraint2, columnName) {
|
|
443
|
+
if (constraint2.type !== "CHECK" || !constraint2.definition) {
|
|
222
444
|
return void 0;
|
|
223
445
|
}
|
|
224
|
-
if (
|
|
446
|
+
if (constraint2.columns && !constraint2.columns.includes(columnName)) {
|
|
225
447
|
return void 0;
|
|
226
448
|
}
|
|
227
|
-
const def =
|
|
449
|
+
const def = constraint2.definition;
|
|
228
450
|
const escapedCol = this.escapeRegex(columnName);
|
|
229
451
|
const colPattern = `(?:\\(?\\(?${escapedCol}\\)?(?:::(?:text|varchar|character varying))?\\)?)`;
|
|
230
452
|
const inMatch = def.match(
|
|
@@ -282,55 +504,51 @@ var ColumnValuesGrounding = class extends AbstractGrounding {
|
|
|
282
504
|
async execute(ctx) {
|
|
283
505
|
const allContainers = [...ctx.tables, ...ctx.views];
|
|
284
506
|
for (const container of allContainers) {
|
|
285
|
-
const
|
|
286
|
-
for (const
|
|
507
|
+
const table2 = this.getTable(ctx, container.name);
|
|
508
|
+
for (const column2 of container.columns) {
|
|
287
509
|
try {
|
|
288
510
|
const result = await this.resolveColumnValues(
|
|
289
511
|
container.name,
|
|
290
|
-
|
|
291
|
-
|
|
512
|
+
column2,
|
|
513
|
+
table2?.constraints
|
|
292
514
|
);
|
|
293
515
|
if (result) {
|
|
294
|
-
|
|
295
|
-
|
|
516
|
+
column2.kind = result.kind;
|
|
517
|
+
column2.values = result.values;
|
|
296
518
|
}
|
|
297
519
|
} catch (error) {
|
|
298
520
|
console.warn(
|
|
299
521
|
"Error collecting column values for",
|
|
300
522
|
container.name,
|
|
301
|
-
|
|
523
|
+
column2.name,
|
|
302
524
|
error
|
|
303
525
|
);
|
|
304
526
|
}
|
|
305
527
|
}
|
|
306
528
|
}
|
|
307
|
-
return () => this.#describe();
|
|
308
529
|
}
|
|
309
530
|
/**
|
|
310
531
|
* Resolve column values from all sources in priority order.
|
|
311
532
|
*/
|
|
312
|
-
async resolveColumnValues(tableName,
|
|
313
|
-
const enumValues = await this.collectEnumValues(tableName,
|
|
533
|
+
async resolveColumnValues(tableName, column2, constraints2) {
|
|
534
|
+
const enumValues = await this.collectEnumValues(tableName, column2);
|
|
314
535
|
if (enumValues?.length) {
|
|
315
536
|
return { kind: "Enum", values: enumValues };
|
|
316
537
|
}
|
|
317
538
|
if (constraints2) {
|
|
318
|
-
for (const
|
|
319
|
-
const checkValues = this.parseCheckConstraint(
|
|
539
|
+
for (const constraint2 of constraints2) {
|
|
540
|
+
const checkValues = this.parseCheckConstraint(constraint2, column2.name);
|
|
320
541
|
if (checkValues?.length) {
|
|
321
542
|
return { kind: "Enum", values: checkValues };
|
|
322
543
|
}
|
|
323
544
|
}
|
|
324
545
|
}
|
|
325
|
-
const lowCardValues = await this.collectLowCardinality(tableName,
|
|
546
|
+
const lowCardValues = await this.collectLowCardinality(tableName, column2);
|
|
326
547
|
if (lowCardValues?.length) {
|
|
327
548
|
return { kind: "LowCardinality", values: lowCardValues };
|
|
328
549
|
}
|
|
329
550
|
return void 0;
|
|
330
551
|
}
|
|
331
|
-
#describe() {
|
|
332
|
-
return null;
|
|
333
|
-
}
|
|
334
552
|
};
|
|
335
553
|
|
|
336
554
|
// packages/text2sql/src/lib/adapters/groundings/report.grounding.ts
|
|
@@ -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/sqlserver/column-stats.sqlserver.grounding.ts
|
|
@@ -727,13 +791,13 @@ var SqlServerColumnStatsGrounding = 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);
|
|
735
|
-
const tableIdentifier = `[${this.#adapter.escape(schema)}].[${this.#adapter.escape(
|
|
736
|
-
const columnIdentifier = `[${this.#adapter.escape(
|
|
798
|
+
const { schema, table: table2 } = this.#adapter.parseTableName(tableName);
|
|
799
|
+
const tableIdentifier = `[${this.#adapter.escape(schema)}].[${this.#adapter.escape(table2)}]`;
|
|
800
|
+
const columnIdentifier = `[${this.#adapter.escape(column2.name)}]`;
|
|
737
801
|
const sql = `
|
|
738
802
|
SELECT
|
|
739
803
|
CAST(MIN(${columnIdentifier}) AS NVARCHAR(MAX)) AS min_value,
|
|
@@ -776,7 +840,7 @@ var SqlServerConstraintGrounding = class extends ConstraintGrounding {
|
|
|
776
840
|
this.#adapter = adapter;
|
|
777
841
|
}
|
|
778
842
|
async getConstraints(tableName) {
|
|
779
|
-
const { schema, table } = this.#adapter.parseTableName(tableName);
|
|
843
|
+
const { schema, table: table2 } = this.#adapter.parseTableName(tableName);
|
|
780
844
|
const constraints2 = [];
|
|
781
845
|
const pkRows = await this.#adapter.runQuery(`
|
|
782
846
|
SELECT
|
|
@@ -787,7 +851,7 @@ var SqlServerConstraintGrounding = class extends ConstraintGrounding {
|
|
|
787
851
|
JOIN sys.tables t ON kc.parent_object_id = t.object_id
|
|
788
852
|
JOIN sys.schemas s ON t.schema_id = s.schema_id
|
|
789
853
|
WHERE s.name = '${this.#adapter.escapeString(schema)}'
|
|
790
|
-
AND t.name = '${this.#adapter.escapeString(
|
|
854
|
+
AND t.name = '${this.#adapter.escapeString(table2)}'
|
|
791
855
|
AND kc.type = 'PK'
|
|
792
856
|
ORDER BY ic.key_ordinal
|
|
793
857
|
`);
|
|
@@ -812,7 +876,7 @@ var SqlServerConstraintGrounding = class extends ConstraintGrounding {
|
|
|
812
876
|
JOIN sys.tables ref_t ON fk.referenced_object_id = ref_t.object_id
|
|
813
877
|
JOIN sys.schemas ref_s ON ref_t.schema_id = ref_s.schema_id
|
|
814
878
|
WHERE s.name = '${this.#adapter.escapeString(schema)}'
|
|
815
|
-
AND t.name = '${this.#adapter.escapeString(
|
|
879
|
+
AND t.name = '${this.#adapter.escapeString(table2)}'
|
|
816
880
|
ORDER BY fk.name, fkc.constraint_column_id
|
|
817
881
|
`);
|
|
818
882
|
const fkMap = /* @__PURE__ */ new Map();
|
|
@@ -847,7 +911,7 @@ var SqlServerConstraintGrounding = class extends ConstraintGrounding {
|
|
|
847
911
|
JOIN sys.tables t ON cc.parent_object_id = t.object_id
|
|
848
912
|
JOIN sys.schemas s ON t.schema_id = s.schema_id
|
|
849
913
|
WHERE s.name = '${this.#adapter.escapeString(schema)}'
|
|
850
|
-
AND t.name = '${this.#adapter.escapeString(
|
|
914
|
+
AND t.name = '${this.#adapter.escapeString(table2)}'
|
|
851
915
|
`);
|
|
852
916
|
for (const row of checkRows) {
|
|
853
917
|
constraints2.push({
|
|
@@ -865,7 +929,7 @@ var SqlServerConstraintGrounding = class extends ConstraintGrounding {
|
|
|
865
929
|
JOIN sys.tables t ON i.object_id = t.object_id
|
|
866
930
|
JOIN sys.schemas s ON t.schema_id = s.schema_id
|
|
867
931
|
WHERE s.name = '${this.#adapter.escapeString(schema)}'
|
|
868
|
-
AND t.name = '${this.#adapter.escapeString(
|
|
932
|
+
AND t.name = '${this.#adapter.escapeString(table2)}'
|
|
869
933
|
AND i.is_unique_constraint = 1
|
|
870
934
|
ORDER BY i.name, ic.key_ordinal
|
|
871
935
|
`);
|
|
@@ -895,21 +959,21 @@ var SqlServerConstraintGrounding = class extends ConstraintGrounding {
|
|
|
895
959
|
JOIN sys.schemas s ON t.schema_id = s.schema_id
|
|
896
960
|
LEFT JOIN sys.default_constraints dc ON c.default_object_id = dc.object_id
|
|
897
961
|
WHERE s.name = '${this.#adapter.escapeString(schema)}'
|
|
898
|
-
AND t.name = '${this.#adapter.escapeString(
|
|
962
|
+
AND t.name = '${this.#adapter.escapeString(table2)}'
|
|
899
963
|
`);
|
|
900
964
|
const pkConstraint = constraints2.find((c) => c.type === "PRIMARY_KEY");
|
|
901
965
|
const pkColumns = new Set(pkConstraint?.columns ?? []);
|
|
902
966
|
for (const col of columnRows) {
|
|
903
967
|
if (col.is_nullable === 0 && !pkColumns.has(col.column_name)) {
|
|
904
968
|
constraints2.push({
|
|
905
|
-
name: `${
|
|
969
|
+
name: `${table2}_${col.column_name}_notnull`,
|
|
906
970
|
type: "NOT_NULL",
|
|
907
971
|
columns: [col.column_name]
|
|
908
972
|
});
|
|
909
973
|
}
|
|
910
974
|
if (col.default_definition != null) {
|
|
911
975
|
constraints2.push({
|
|
912
|
-
name: `${
|
|
976
|
+
name: `${table2}_${col.column_name}_default`,
|
|
913
977
|
type: "DEFAULT",
|
|
914
978
|
columns: [col.column_name],
|
|
915
979
|
defaultValue: col.default_definition.replace(/^\(/, "").replace(/\)$/, "")
|
|
@@ -930,7 +994,7 @@ var SqlServerIndexesGrounding = class extends IndexesGrounding {
|
|
|
930
994
|
this.#schemas = config.schemas;
|
|
931
995
|
}
|
|
932
996
|
async getIndexes(tableName) {
|
|
933
|
-
const { schema, table } = this.#adapter.parseTableName(tableName);
|
|
997
|
+
const { schema, table: table2 } = this.#adapter.parseTableName(tableName);
|
|
934
998
|
const rows = await this.#adapter.runQuery(`
|
|
935
999
|
SELECT
|
|
936
1000
|
i.name AS index_name,
|
|
@@ -947,7 +1011,7 @@ var SqlServerIndexesGrounding = class extends IndexesGrounding {
|
|
|
947
1011
|
JOIN sys.schemas s
|
|
948
1012
|
ON t.schema_id = s.schema_id
|
|
949
1013
|
WHERE s.name = '${this.#adapter.escapeString(schema)}'
|
|
950
|
-
AND t.name = '${this.#adapter.escapeString(
|
|
1014
|
+
AND t.name = '${this.#adapter.escapeString(table2)}'
|
|
951
1015
|
AND i.name IS NOT NULL
|
|
952
1016
|
AND ic.is_included_column = 0
|
|
953
1017
|
ORDER BY i.name, ic.key_ordinal
|
|
@@ -1006,10 +1070,10 @@ var SqlServerColumnValuesGrounding = class extends ColumnValuesGrounding {
|
|
|
1006
1070
|
super(config);
|
|
1007
1071
|
this.#adapter = adapter;
|
|
1008
1072
|
}
|
|
1009
|
-
async collectLowCardinality(tableName,
|
|
1010
|
-
const { schema, table } = this.#adapter.parseTableName(tableName);
|
|
1011
|
-
const tableIdentifier = `[${this.#adapter.escape(schema)}].[${this.#adapter.escape(
|
|
1012
|
-
const columnIdentifier = `[${this.#adapter.escape(
|
|
1073
|
+
async collectLowCardinality(tableName, column2) {
|
|
1074
|
+
const { schema, table: table2 } = this.#adapter.parseTableName(tableName);
|
|
1075
|
+
const tableIdentifier = `[${this.#adapter.escape(schema)}].[${this.#adapter.escape(table2)}]`;
|
|
1076
|
+
const columnIdentifier = `[${this.#adapter.escape(column2.name)}]`;
|
|
1013
1077
|
const limit = this.lowCardinalityLimit + 1;
|
|
1014
1078
|
const sql = `
|
|
1015
1079
|
SELECT DISTINCT TOP ${limit} CAST(${columnIdentifier} AS NVARCHAR(MAX)) AS value
|
|
@@ -1039,8 +1103,8 @@ var SqlServerRowCountGrounding = class extends RowCountGrounding {
|
|
|
1039
1103
|
this.#adapter = adapter;
|
|
1040
1104
|
}
|
|
1041
1105
|
async getRowCount(tableName) {
|
|
1042
|
-
const { schema, table } = this.#adapter.parseTableName(tableName);
|
|
1043
|
-
const tableIdentifier = `[${this.#adapter.escape(schema)}].[${this.#adapter.escape(
|
|
1106
|
+
const { schema, table: table2 } = this.#adapter.parseTableName(tableName);
|
|
1107
|
+
const tableIdentifier = `[${this.#adapter.escape(schema)}].[${this.#adapter.escape(table2)}]`;
|
|
1044
1108
|
const rows = await this.#adapter.runQuery(
|
|
1045
1109
|
`SELECT COUNT(*) as count FROM ${tableIdentifier}`
|
|
1046
1110
|
);
|
|
@@ -1141,8 +1205,8 @@ var SqlServer = class extends Adapter {
|
|
|
1141
1205
|
return value.replace(/]/g, "]]");
|
|
1142
1206
|
}
|
|
1143
1207
|
buildSampleRowsQuery(tableName, columns, limit) {
|
|
1144
|
-
const { schema, table } = this.parseTableName(tableName);
|
|
1145
|
-
const tableIdentifier = `${this.quoteIdentifier(schema)}.${this.quoteIdentifier(
|
|
1208
|
+
const { schema, table: table2 } = this.parseTableName(tableName);
|
|
1209
|
+
const tableIdentifier = `${this.quoteIdentifier(schema)}.${this.quoteIdentifier(table2)}`;
|
|
1146
1210
|
const columnList = columns?.length ? columns.map((c) => this.quoteIdentifier(c)).join(", ") : "*";
|
|
1147
1211
|
return `SELECT TOP ${limit} ${columnList} FROM ${tableIdentifier}`;
|
|
1148
1212
|
}
|
|
@@ -1169,17 +1233,17 @@ var SqlServer = class extends Adapter {
|
|
|
1169
1233
|
const schema = row.table_schema ?? "dbo";
|
|
1170
1234
|
const tableName = row.table_name;
|
|
1171
1235
|
const qualifiedName = `${schema}.${tableName}`;
|
|
1172
|
-
const
|
|
1236
|
+
const table2 = tables2.get(qualifiedName) ?? {
|
|
1173
1237
|
name: qualifiedName,
|
|
1174
1238
|
schema,
|
|
1175
1239
|
rawName: tableName,
|
|
1176
1240
|
columns: []
|
|
1177
1241
|
};
|
|
1178
|
-
|
|
1242
|
+
table2.columns.push({
|
|
1179
1243
|
name: row.column_name ?? "unknown",
|
|
1180
1244
|
type: row.data_type ?? "unknown"
|
|
1181
1245
|
});
|
|
1182
|
-
tables2.set(qualifiedName,
|
|
1246
|
+
tables2.set(qualifiedName, table2);
|
|
1183
1247
|
}
|
|
1184
1248
|
return Array.from(tables2.values());
|
|
1185
1249
|
}
|
|
@@ -1213,26 +1277,26 @@ var SqlServer = class extends Adapter {
|
|
|
1213
1277
|
const schema = row.table_schema ?? "dbo";
|
|
1214
1278
|
const referencedSchema = row.referenced_table_schema ?? "dbo";
|
|
1215
1279
|
const key = `${schema}.${row.table_name}:${row.constraint_name}`;
|
|
1216
|
-
const
|
|
1280
|
+
const relationship2 = relationships.get(key) ?? {
|
|
1217
1281
|
table: `${schema}.${row.table_name}`,
|
|
1218
1282
|
from: [],
|
|
1219
1283
|
referenced_table: `${referencedSchema}.${row.referenced_table_name}`,
|
|
1220
1284
|
to: []
|
|
1221
1285
|
};
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
relationships.set(key,
|
|
1286
|
+
relationship2.from.push(row.column_name ?? "unknown");
|
|
1287
|
+
relationship2.to.push(row.referenced_column_name ?? "unknown");
|
|
1288
|
+
relationships.set(key, relationship2);
|
|
1225
1289
|
}
|
|
1226
1290
|
return Array.from(relationships.values());
|
|
1227
1291
|
}
|
|
1228
1292
|
async #annotateRowCounts(tables2, onProgress) {
|
|
1229
1293
|
const total = tables2.length;
|
|
1230
1294
|
for (let i = 0; i < tables2.length; i++) {
|
|
1231
|
-
const
|
|
1232
|
-
const tableIdentifier = this.#formatQualifiedTableName(
|
|
1295
|
+
const table2 = tables2[i];
|
|
1296
|
+
const tableIdentifier = this.#formatQualifiedTableName(table2);
|
|
1233
1297
|
onProgress?.({
|
|
1234
1298
|
phase: "row_counts",
|
|
1235
|
-
message: `Counting rows in ${
|
|
1299
|
+
message: `Counting rows in ${table2.name}...`,
|
|
1236
1300
|
current: i + 1,
|
|
1237
1301
|
total
|
|
1238
1302
|
});
|
|
@@ -1240,8 +1304,8 @@ var SqlServer = class extends Adapter {
|
|
|
1240
1304
|
const rows = await this.#runIntrospectionQuery(`SELECT COUNT(*) as count FROM ${tableIdentifier}`);
|
|
1241
1305
|
const rowCount2 = this.#toNumber(rows[0]?.count);
|
|
1242
1306
|
if (rowCount2 != null) {
|
|
1243
|
-
|
|
1244
|
-
|
|
1307
|
+
table2.rowCount = rowCount2;
|
|
1308
|
+
table2.sizeHint = this.#classifyRowCount(rowCount2);
|
|
1245
1309
|
}
|
|
1246
1310
|
} catch {
|
|
1247
1311
|
continue;
|
|
@@ -1258,7 +1322,7 @@ var SqlServer = class extends Adapter {
|
|
|
1258
1322
|
if (!tables2.length) {
|
|
1259
1323
|
return;
|
|
1260
1324
|
}
|
|
1261
|
-
const tableMap = new Map(tables2.map((
|
|
1325
|
+
const tableMap = new Map(tables2.map((table2) => [table2.name, table2]));
|
|
1262
1326
|
const rows = await this.#runIntrospectionQuery(`
|
|
1263
1327
|
SELECT
|
|
1264
1328
|
sch.name AS schema_name,
|
|
@@ -1290,35 +1354,35 @@ var SqlServer = class extends Adapter {
|
|
|
1290
1354
|
}
|
|
1291
1355
|
const schema = row.schema_name ?? "dbo";
|
|
1292
1356
|
const tableKey = `${schema}.${row.table_name}`;
|
|
1293
|
-
const
|
|
1294
|
-
if (!
|
|
1357
|
+
const table2 = tableMap.get(tableKey);
|
|
1358
|
+
if (!table2) {
|
|
1295
1359
|
continue;
|
|
1296
1360
|
}
|
|
1297
1361
|
const indexKey = `${tableKey}:${row.index_name}`;
|
|
1298
|
-
let
|
|
1299
|
-
if (!
|
|
1300
|
-
|
|
1362
|
+
let index2 = indexMap.get(indexKey);
|
|
1363
|
+
if (!index2) {
|
|
1364
|
+
index2 = {
|
|
1301
1365
|
name: row.index_name,
|
|
1302
1366
|
columns: [],
|
|
1303
1367
|
unique: Boolean(row.is_unique),
|
|
1304
1368
|
type: row.type_desc ?? void 0
|
|
1305
1369
|
};
|
|
1306
|
-
indexMap.set(indexKey,
|
|
1307
|
-
if (!
|
|
1308
|
-
|
|
1370
|
+
indexMap.set(indexKey, index2);
|
|
1371
|
+
if (!table2.indexes) {
|
|
1372
|
+
table2.indexes = [];
|
|
1309
1373
|
}
|
|
1310
|
-
|
|
1374
|
+
table2.indexes.push(index2);
|
|
1311
1375
|
}
|
|
1312
1376
|
if (row.is_included_column) {
|
|
1313
1377
|
continue;
|
|
1314
1378
|
}
|
|
1315
1379
|
if (row.column_name) {
|
|
1316
|
-
|
|
1317
|
-
const
|
|
1380
|
+
index2.columns.push(row.column_name);
|
|
1381
|
+
const column2 = table2.columns.find(
|
|
1318
1382
|
(col) => col.name === row.column_name
|
|
1319
1383
|
);
|
|
1320
|
-
if (
|
|
1321
|
-
|
|
1384
|
+
if (column2) {
|
|
1385
|
+
column2.isIndexed = true;
|
|
1322
1386
|
}
|
|
1323
1387
|
}
|
|
1324
1388
|
}
|
|
@@ -1329,19 +1393,19 @@ var SqlServer = class extends Adapter {
|
|
|
1329
1393
|
}
|
|
1330
1394
|
const total = tables2.length;
|
|
1331
1395
|
for (let i = 0; i < tables2.length; i++) {
|
|
1332
|
-
const
|
|
1333
|
-
const tableIdentifier = this.#formatQualifiedTableName(
|
|
1396
|
+
const table2 = tables2[i];
|
|
1397
|
+
const tableIdentifier = this.#formatQualifiedTableName(table2);
|
|
1334
1398
|
onProgress?.({
|
|
1335
1399
|
phase: "column_stats",
|
|
1336
|
-
message: `Collecting stats for ${
|
|
1400
|
+
message: `Collecting stats for ${table2.name}...`,
|
|
1337
1401
|
current: i + 1,
|
|
1338
1402
|
total
|
|
1339
1403
|
});
|
|
1340
|
-
for (const
|
|
1341
|
-
if (!this.#shouldCollectStats(
|
|
1404
|
+
for (const column2 of table2.columns) {
|
|
1405
|
+
if (!this.#shouldCollectStats(column2.type)) {
|
|
1342
1406
|
continue;
|
|
1343
1407
|
}
|
|
1344
|
-
const columnIdentifier = this.#quoteIdentifier(
|
|
1408
|
+
const columnIdentifier = this.#quoteIdentifier(column2.name);
|
|
1345
1409
|
const sql = `
|
|
1346
1410
|
SELECT
|
|
1347
1411
|
CONVERT(NVARCHAR(4000), MIN(${columnIdentifier})) AS min_value,
|
|
@@ -1356,7 +1420,7 @@ var SqlServer = class extends Adapter {
|
|
|
1356
1420
|
}
|
|
1357
1421
|
const nullFraction = this.#toNumber(rows[0]?.null_fraction);
|
|
1358
1422
|
if (rows[0]?.min_value != null || rows[0]?.max_value != null || nullFraction != null) {
|
|
1359
|
-
|
|
1423
|
+
column2.stats = {
|
|
1360
1424
|
min: rows[0]?.min_value ?? void 0,
|
|
1361
1425
|
max: rows[0]?.max_value ?? void 0,
|
|
1362
1426
|
nullFraction: nullFraction != null && Number.isFinite(nullFraction) ? Math.max(0, Math.min(1, nullFraction)) : void 0
|
|
@@ -1371,16 +1435,16 @@ var SqlServer = class extends Adapter {
|
|
|
1371
1435
|
async #annotateLowCardinalityColumns(tables2, onProgress) {
|
|
1372
1436
|
const total = tables2.length;
|
|
1373
1437
|
for (let i = 0; i < tables2.length; i++) {
|
|
1374
|
-
const
|
|
1375
|
-
const tableIdentifier = this.#formatQualifiedTableName(
|
|
1438
|
+
const table2 = tables2[i];
|
|
1439
|
+
const tableIdentifier = this.#formatQualifiedTableName(table2);
|
|
1376
1440
|
onProgress?.({
|
|
1377
1441
|
phase: "low_cardinality",
|
|
1378
|
-
message: `Analyzing cardinality in ${
|
|
1442
|
+
message: `Analyzing cardinality in ${table2.name}...`,
|
|
1379
1443
|
current: i + 1,
|
|
1380
1444
|
total
|
|
1381
1445
|
});
|
|
1382
|
-
for (const
|
|
1383
|
-
const columnIdentifier = this.#quoteIdentifier(
|
|
1446
|
+
for (const column2 of table2.columns) {
|
|
1447
|
+
const columnIdentifier = this.#quoteIdentifier(column2.name);
|
|
1384
1448
|
const limit = LOW_CARDINALITY_LIMIT + 1;
|
|
1385
1449
|
const sql = `
|
|
1386
1450
|
SELECT DISTINCT TOP (${limit}) ${columnIdentifier} AS value
|
|
@@ -1409,8 +1473,8 @@ var SqlServer = class extends Adapter {
|
|
|
1409
1473
|
if (shouldSkip || !values.length) {
|
|
1410
1474
|
continue;
|
|
1411
1475
|
}
|
|
1412
|
-
|
|
1413
|
-
|
|
1476
|
+
column2.kind = "LowCardinality";
|
|
1477
|
+
column2.values = values;
|
|
1414
1478
|
}
|
|
1415
1479
|
}
|
|
1416
1480
|
}
|
|
@@ -1473,19 +1537,19 @@ var SqlServer = class extends Adapter {
|
|
|
1473
1537
|
#quoteIdentifier(name) {
|
|
1474
1538
|
return `[${name.replace(/]/g, "]]")}]`;
|
|
1475
1539
|
}
|
|
1476
|
-
#formatQualifiedTableName(
|
|
1477
|
-
if (
|
|
1478
|
-
return `${this.#quoteIdentifier(
|
|
1540
|
+
#formatQualifiedTableName(table2) {
|
|
1541
|
+
if (table2.schema && table2.rawName) {
|
|
1542
|
+
return `${this.#quoteIdentifier(table2.schema)}.${this.#quoteIdentifier(table2.rawName)}`;
|
|
1479
1543
|
}
|
|
1480
|
-
if (
|
|
1481
|
-
const [schemaPart, ...rest] =
|
|
1544
|
+
if (table2.name.includes(".")) {
|
|
1545
|
+
const [schemaPart, ...rest] = table2.name.split(".");
|
|
1482
1546
|
const tablePart = rest.join(".") || schemaPart;
|
|
1483
1547
|
if (rest.length === 0) {
|
|
1484
1548
|
return this.#quoteIdentifier(schemaPart);
|
|
1485
1549
|
}
|
|
1486
1550
|
return `${this.#quoteIdentifier(schemaPart)}.${this.#quoteIdentifier(tablePart)}`;
|
|
1487
1551
|
}
|
|
1488
|
-
return this.#quoteIdentifier(
|
|
1552
|
+
return this.#quoteIdentifier(table2.name);
|
|
1489
1553
|
}
|
|
1490
1554
|
#toNumber(value) {
|
|
1491
1555
|
if (typeof value === "number" && Number.isFinite(value)) {
|
|
@@ -1567,18 +1631,18 @@ var SqlServerTableGrounding = class extends TableGrounding {
|
|
|
1567
1631
|
return rows.map((r) => r.name);
|
|
1568
1632
|
}
|
|
1569
1633
|
async getTable(tableName) {
|
|
1570
|
-
const { schema, table } = this.#adapter.parseTableName(tableName);
|
|
1634
|
+
const { schema, table: table2 } = this.#adapter.parseTableName(tableName);
|
|
1571
1635
|
const columns = await this.#adapter.runQuery(`
|
|
1572
1636
|
SELECT COLUMN_NAME AS column_name, DATA_TYPE AS data_type
|
|
1573
1637
|
FROM INFORMATION_SCHEMA.COLUMNS
|
|
1574
1638
|
WHERE TABLE_SCHEMA = '${this.#adapter.escapeString(schema)}'
|
|
1575
|
-
AND TABLE_NAME = '${this.#adapter.escapeString(
|
|
1639
|
+
AND TABLE_NAME = '${this.#adapter.escapeString(table2)}'
|
|
1576
1640
|
ORDER BY ORDINAL_POSITION
|
|
1577
1641
|
`);
|
|
1578
1642
|
return {
|
|
1579
1643
|
name: tableName,
|
|
1580
1644
|
schema,
|
|
1581
|
-
rawName:
|
|
1645
|
+
rawName: table2,
|
|
1582
1646
|
columns: columns.map((col) => ({
|
|
1583
1647
|
name: col.column_name ?? "unknown",
|
|
1584
1648
|
type: col.data_type ?? "unknown"
|
|
@@ -1586,7 +1650,7 @@ var SqlServerTableGrounding = class extends TableGrounding {
|
|
|
1586
1650
|
};
|
|
1587
1651
|
}
|
|
1588
1652
|
async findOutgoingRelations(tableName) {
|
|
1589
|
-
const { schema, table } = this.#adapter.parseTableName(tableName);
|
|
1653
|
+
const { schema, table: table2 } = this.#adapter.parseTableName(tableName);
|
|
1590
1654
|
const rows = await this.#adapter.runQuery(`
|
|
1591
1655
|
SELECT
|
|
1592
1656
|
fk.CONSTRAINT_NAME AS constraint_name,
|
|
@@ -1603,13 +1667,13 @@ var SqlServerTableGrounding = class extends TableGrounding {
|
|
|
1603
1667
|
ON pk.CONSTRAINT_NAME = rc.UNIQUE_CONSTRAINT_NAME
|
|
1604
1668
|
AND pk.ORDINAL_POSITION = fk.ORDINAL_POSITION
|
|
1605
1669
|
WHERE fk.TABLE_SCHEMA = '${this.#adapter.escapeString(schema)}'
|
|
1606
|
-
AND fk.TABLE_NAME = '${this.#adapter.escapeString(
|
|
1670
|
+
AND fk.TABLE_NAME = '${this.#adapter.escapeString(table2)}'
|
|
1607
1671
|
ORDER BY fk.CONSTRAINT_NAME, fk.ORDINAL_POSITION
|
|
1608
1672
|
`);
|
|
1609
1673
|
return this.#groupRelationships(rows);
|
|
1610
1674
|
}
|
|
1611
1675
|
async findIncomingRelations(tableName) {
|
|
1612
|
-
const { schema, table } = this.#adapter.parseTableName(tableName);
|
|
1676
|
+
const { schema, table: table2 } = this.#adapter.parseTableName(tableName);
|
|
1613
1677
|
const rows = await this.#adapter.runQuery(`
|
|
1614
1678
|
SELECT
|
|
1615
1679
|
fk.CONSTRAINT_NAME AS constraint_name,
|
|
@@ -1626,7 +1690,7 @@ var SqlServerTableGrounding = class extends TableGrounding {
|
|
|
1626
1690
|
ON pk.CONSTRAINT_NAME = rc.UNIQUE_CONSTRAINT_NAME
|
|
1627
1691
|
AND pk.ORDINAL_POSITION = fk.ORDINAL_POSITION
|
|
1628
1692
|
WHERE pk.TABLE_SCHEMA = '${this.#adapter.escapeString(schema)}'
|
|
1629
|
-
AND pk.TABLE_NAME = '${this.#adapter.escapeString(
|
|
1693
|
+
AND pk.TABLE_NAME = '${this.#adapter.escapeString(table2)}'
|
|
1630
1694
|
ORDER BY fk.CONSTRAINT_NAME, fk.ORDINAL_POSITION
|
|
1631
1695
|
`);
|
|
1632
1696
|
return this.#groupRelationships(rows);
|
|
@@ -1641,15 +1705,15 @@ var SqlServerTableGrounding = class extends TableGrounding {
|
|
|
1641
1705
|
const schema = row.table_schema ?? defaultSchema;
|
|
1642
1706
|
const referencedSchema = row.referenced_table_schema ?? defaultSchema;
|
|
1643
1707
|
const key = `${schema}.${row.table_name}:${row.constraint_name}`;
|
|
1644
|
-
const
|
|
1708
|
+
const relationship2 = relationships.get(key) ?? {
|
|
1645
1709
|
table: `${schema}.${row.table_name}`,
|
|
1646
1710
|
from: [],
|
|
1647
1711
|
referenced_table: `${referencedSchema}.${row.referenced_table_name}`,
|
|
1648
1712
|
to: []
|
|
1649
1713
|
};
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
relationships.set(key,
|
|
1714
|
+
relationship2.from.push(row.column_name ?? "unknown");
|
|
1715
|
+
relationship2.to.push(row.referenced_column_name ?? "unknown");
|
|
1716
|
+
relationships.set(key, relationship2);
|
|
1653
1717
|
}
|
|
1654
1718
|
return Array.from(relationships.values());
|
|
1655
1719
|
}
|
|
@@ -1659,7 +1723,7 @@ var SqlServerTableGrounding = class extends TableGrounding {
|
|
|
1659
1723
|
var ViewGrounding = class extends AbstractGrounding {
|
|
1660
1724
|
#filter;
|
|
1661
1725
|
constructor(config = {}) {
|
|
1662
|
-
super("
|
|
1726
|
+
super("view");
|
|
1663
1727
|
this.#filter = config.filter;
|
|
1664
1728
|
}
|
|
1665
1729
|
/**
|
|
@@ -1672,42 +1736,6 @@ var ViewGrounding = class extends AbstractGrounding {
|
|
|
1672
1736
|
viewNames.map((name) => this.getView(name))
|
|
1673
1737
|
);
|
|
1674
1738
|
ctx.views.push(...views2);
|
|
1675
|
-
return () => this.#describe(views2);
|
|
1676
|
-
}
|
|
1677
|
-
#describe(views2) {
|
|
1678
|
-
if (!views2.length) {
|
|
1679
|
-
return "No views available.";
|
|
1680
|
-
}
|
|
1681
|
-
return views2.map((view) => {
|
|
1682
|
-
const columns = view.columns.map((column) => {
|
|
1683
|
-
const annotations = [];
|
|
1684
|
-
if (column.kind === "LowCardinality" && column.values?.length) {
|
|
1685
|
-
annotations.push(`LowCardinality: ${column.values.join(", ")}`);
|
|
1686
|
-
}
|
|
1687
|
-
if (column.stats) {
|
|
1688
|
-
const statParts = [];
|
|
1689
|
-
if (column.stats.min != null || column.stats.max != null) {
|
|
1690
|
-
const minText = column.stats.min ?? "n/a";
|
|
1691
|
-
const maxText = column.stats.max ?? "n/a";
|
|
1692
|
-
statParts.push(`range ${minText} \u2192 ${maxText}`);
|
|
1693
|
-
}
|
|
1694
|
-
if (column.stats.nullFraction != null && Number.isFinite(column.stats.nullFraction)) {
|
|
1695
|
-
const percent = Math.round(column.stats.nullFraction * 1e3) / 10;
|
|
1696
|
-
statParts.push(`null\u2248${percent}%`);
|
|
1697
|
-
}
|
|
1698
|
-
if (statParts.length) {
|
|
1699
|
-
annotations.push(statParts.join(", "));
|
|
1700
|
-
}
|
|
1701
|
-
}
|
|
1702
|
-
const annotationText = annotations.length ? ` [${annotations.join(", ")}]` : "";
|
|
1703
|
-
return ` - ${column.name} (${column.type})${annotationText}`;
|
|
1704
|
-
}).join("\n");
|
|
1705
|
-
const definition = view.definition ? `
|
|
1706
|
-
Definition: ${view.definition.length > 200 ? view.definition.slice(0, 200) + "..." : view.definition}` : "";
|
|
1707
|
-
return `- View: ${view.name}${definition}
|
|
1708
|
-
Columns:
|
|
1709
|
-
${columns}`;
|
|
1710
|
-
}).join("\n\n");
|
|
1711
1739
|
}
|
|
1712
1740
|
/**
|
|
1713
1741
|
* Apply the filter to get view names.
|
|
@@ -1749,26 +1777,26 @@ var SqlServerViewGrounding = class extends ViewGrounding {
|
|
|
1749
1777
|
return rows.map((r) => r.name);
|
|
1750
1778
|
}
|
|
1751
1779
|
async getView(viewName) {
|
|
1752
|
-
const { schema, table:
|
|
1780
|
+
const { schema, table: view2 } = this.#adapter.parseTableName(viewName);
|
|
1753
1781
|
const defRows = await this.#adapter.runQuery(`
|
|
1754
1782
|
SELECT m.definition
|
|
1755
1783
|
FROM sys.views v
|
|
1756
1784
|
JOIN sys.schemas s ON v.schema_id = s.schema_id
|
|
1757
1785
|
JOIN sys.sql_modules m ON v.object_id = m.object_id
|
|
1758
1786
|
WHERE s.name = '${this.#adapter.escapeString(schema)}'
|
|
1759
|
-
AND v.name = '${this.#adapter.escapeString(
|
|
1787
|
+
AND v.name = '${this.#adapter.escapeString(view2)}'
|
|
1760
1788
|
`);
|
|
1761
1789
|
const columns = await this.#adapter.runQuery(`
|
|
1762
1790
|
SELECT COLUMN_NAME AS column_name, DATA_TYPE AS data_type
|
|
1763
1791
|
FROM INFORMATION_SCHEMA.COLUMNS
|
|
1764
1792
|
WHERE TABLE_SCHEMA = '${this.#adapter.escapeString(schema)}'
|
|
1765
|
-
AND TABLE_NAME = '${this.#adapter.escapeString(
|
|
1793
|
+
AND TABLE_NAME = '${this.#adapter.escapeString(view2)}'
|
|
1766
1794
|
ORDER BY ORDINAL_POSITION
|
|
1767
1795
|
`);
|
|
1768
1796
|
return {
|
|
1769
1797
|
name: viewName,
|
|
1770
1798
|
schema,
|
|
1771
|
-
rawName:
|
|
1799
|
+
rawName: view2,
|
|
1772
1800
|
definition: defRows[0]?.definition ?? void 0,
|
|
1773
1801
|
columns: columns.map((col) => ({
|
|
1774
1802
|
name: col.column_name ?? "unknown",
|