@askdb/core 1.0.0-beta.40 → 1.0.0-beta.42
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 +39 -1
- package/dist/ask.d.ts +48 -0
- package/dist/ask.d.ts.map +1 -1
- package/dist/ask.js +176 -10
- package/dist/ask.js.map +1 -1
- package/dist/enrichment/suggest.d.ts +7 -0
- package/dist/enrichment/suggest.d.ts.map +1 -1
- package/dist/enrichment/suggest.js +7 -1
- package/dist/enrichment/suggest.js.map +1 -1
- package/dist/errors.d.ts +49 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +20 -0
- package/dist/errors.js.map +1 -1
- package/dist/exec/postgres.d.ts +6 -0
- package/dist/exec/postgres.d.ts.map +1 -0
- package/dist/exec/postgres.js +30 -0
- package/dist/exec/postgres.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/logging/log-events.d.ts +13 -0
- package/dist/logging/log-events.d.ts.map +1 -1
- package/dist/logging/log-events.js +13 -0
- package/dist/logging/log-events.js.map +1 -1
- package/dist/modes/post-execute-log.d.ts +9 -0
- package/dist/modes/post-execute-log.d.ts.map +1 -0
- package/dist/modes/post-execute-log.js +26 -0
- package/dist/modes/post-execute-log.js.map +1 -0
- package/dist/sql/bind.d.ts +100 -0
- package/dist/sql/bind.d.ts.map +1 -0
- package/dist/sql/bind.js +560 -0
- package/dist/sql/bind.js.map +1 -0
- package/dist/sql/dialect-spec.d.ts +4 -0
- package/dist/sql/dialect-spec.d.ts.map +1 -1
- package/dist/sql/dialect-spec.js +8 -0
- package/dist/sql/dialect-spec.js.map +1 -1
- package/dist/sql/extract-sql.d.ts +8 -1
- package/dist/sql/extract-sql.d.ts.map +1 -1
- package/dist/sql/extract-sql.js +27 -4
- package/dist/sql/extract-sql.js.map +1 -1
- package/dist/sql/generate.d.ts +19 -0
- package/dist/sql/generate.d.ts.map +1 -1
- package/dist/sql/generate.js +79 -5
- package/dist/sql/generate.js.map +1 -1
- package/dist/sql/index.d.ts +4 -2
- package/dist/sql/index.d.ts.map +1 -1
- package/dist/sql/index.js +4 -2
- package/dist/sql/index.js.map +1 -1
- package/dist/sql/parameter-manifest.d.ts +34 -0
- package/dist/sql/parameter-manifest.d.ts.map +1 -0
- package/dist/sql/parameter-manifest.js +150 -0
- package/dist/sql/parameter-manifest.js.map +1 -0
- package/dist/sql/prompt.d.ts +7 -1
- package/dist/sql/prompt.d.ts.map +1 -1
- package/dist/sql/prompt.js +24 -1
- package/dist/sql/prompt.js.map +1 -1
- package/dist/sql/sensitive-guardrail.d.ts +47 -0
- package/dist/sql/sensitive-guardrail.d.ts.map +1 -0
- package/dist/sql/sensitive-guardrail.js +589 -0
- package/dist/sql/sensitive-guardrail.js.map +1 -0
- package/dist/sql/tenant-placeholders.d.ts +3 -2
- package/dist/sql/tenant-placeholders.d.ts.map +1 -1
- package/dist/sql/tenant-placeholders.js +14 -11
- package/dist/sql/tenant-placeholders.js.map +1 -1
- package/dist/sql/validate.d.ts.map +1 -1
- package/dist/sql/validate.js +1 -47
- package/dist/sql/validate.js.map +1 -1
- package/package.json +6 -5
- package/dist/ai/provider.d.ts +0 -116
- package/dist/ai/provider.d.ts.map +0 -1
- package/dist/ai/provider.js +0 -255
- package/dist/ai/provider.js.map +0 -1
package/dist/sql/bind.js
ADDED
|
@@ -0,0 +1,560 @@
|
|
|
1
|
+
import { QueryParameterError, } from "../errors.js";
|
|
2
|
+
import { BUILT_IN_DIALECTS, } from "./dialect-spec.js";
|
|
3
|
+
import { validateSelectSql } from "./validate.js";
|
|
4
|
+
/**
|
|
5
|
+
* Tokenize SQL into contiguous code vs quoted regions.
|
|
6
|
+
* Recognizes single-quoted strings (doubled-quote escapes), double-quoted
|
|
7
|
+
* identifiers, PostgreSQL dollar-quoting, MySQL backticks, and SQL Server brackets.
|
|
8
|
+
*/
|
|
9
|
+
export function tokenizeSqlSpans(sql) {
|
|
10
|
+
const spans = [];
|
|
11
|
+
let i = 0;
|
|
12
|
+
let codeStart = 0;
|
|
13
|
+
const pushCode = (end) => {
|
|
14
|
+
if (end > codeStart)
|
|
15
|
+
spans.push({ kind: "code", start: codeStart, end });
|
|
16
|
+
};
|
|
17
|
+
while (i < sql.length) {
|
|
18
|
+
const ch = sql[i];
|
|
19
|
+
if (ch === "'") {
|
|
20
|
+
pushCode(i);
|
|
21
|
+
const start = i;
|
|
22
|
+
i++;
|
|
23
|
+
while (i < sql.length) {
|
|
24
|
+
if (sql[i] === "'" && sql[i + 1] === "'") {
|
|
25
|
+
i += 2;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (sql[i] === "'") {
|
|
29
|
+
i++;
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
i++;
|
|
33
|
+
}
|
|
34
|
+
spans.push({ kind: "quoted", start, end: i });
|
|
35
|
+
codeStart = i;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (ch === '"') {
|
|
39
|
+
pushCode(i);
|
|
40
|
+
const start = i;
|
|
41
|
+
i++;
|
|
42
|
+
while (i < sql.length && sql[i] !== '"') {
|
|
43
|
+
if (sql[i] === "\\")
|
|
44
|
+
i++;
|
|
45
|
+
i++;
|
|
46
|
+
}
|
|
47
|
+
if (i < sql.length)
|
|
48
|
+
i++;
|
|
49
|
+
spans.push({ kind: "quoted", start, end: i });
|
|
50
|
+
codeStart = i;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (ch === "`") {
|
|
54
|
+
pushCode(i);
|
|
55
|
+
const start = i;
|
|
56
|
+
i++;
|
|
57
|
+
while (i < sql.length && sql[i] !== "`") {
|
|
58
|
+
if (sql[i] === "\\")
|
|
59
|
+
i++;
|
|
60
|
+
i++;
|
|
61
|
+
}
|
|
62
|
+
if (i < sql.length)
|
|
63
|
+
i++;
|
|
64
|
+
spans.push({ kind: "quoted", start, end: i });
|
|
65
|
+
codeStart = i;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (ch === "[") {
|
|
69
|
+
pushCode(i);
|
|
70
|
+
const start = i;
|
|
71
|
+
i++;
|
|
72
|
+
while (i < sql.length && sql[i] !== "]") {
|
|
73
|
+
i++;
|
|
74
|
+
}
|
|
75
|
+
if (i < sql.length)
|
|
76
|
+
i++;
|
|
77
|
+
spans.push({ kind: "quoted", start, end: i });
|
|
78
|
+
codeStart = i;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
// Dollar-quoting: $tag$ … $tag$. Do not treat $1 as a dollar quote.
|
|
82
|
+
if (ch === "$" && /^\$\w*\$/.test(sql.slice(i))) {
|
|
83
|
+
const tagMatch = /^\$(\w*)\$/.exec(sql.slice(i));
|
|
84
|
+
const opener = tagMatch[0];
|
|
85
|
+
const closerAt = sql.indexOf(opener, i + opener.length);
|
|
86
|
+
if (closerAt === -1) {
|
|
87
|
+
// Unterminated — treat remainder as code (matches prior fail-open).
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
pushCode(i);
|
|
91
|
+
const end = closerAt + opener.length;
|
|
92
|
+
spans.push({ kind: "quoted", start: i, end });
|
|
93
|
+
i = end;
|
|
94
|
+
codeStart = i;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
i++;
|
|
98
|
+
}
|
|
99
|
+
pushCode(sql.length);
|
|
100
|
+
return spans;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Strip quoted regions for keyword / multi-statement checks.
|
|
104
|
+
* Preserves historical replacement markers for quotes the old stripper knew
|
|
105
|
+
* about (`''`, `""`, `$$`); new quote forms (backticks, brackets) become spaces.
|
|
106
|
+
*/
|
|
107
|
+
export function stripSqlStringLiterals(sql) {
|
|
108
|
+
// Walk with the same control flow as the historical stripper for ', ", and $$,
|
|
109
|
+
// then additionally skip backticks and brackets — producing equivalent output
|
|
110
|
+
// for previously-supported forms.
|
|
111
|
+
let out = "";
|
|
112
|
+
let i = 0;
|
|
113
|
+
while (i < sql.length) {
|
|
114
|
+
const ch = sql[i];
|
|
115
|
+
if (ch === "'") {
|
|
116
|
+
i++;
|
|
117
|
+
while (i < sql.length) {
|
|
118
|
+
if (sql[i] === "'" && sql[i + 1] === "'") {
|
|
119
|
+
i += 2;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (sql[i] === "'") {
|
|
123
|
+
i++;
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
i++;
|
|
127
|
+
}
|
|
128
|
+
out += "''";
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (ch === '"') {
|
|
132
|
+
i++;
|
|
133
|
+
while (i < sql.length && sql[i] !== '"') {
|
|
134
|
+
if (sql[i] === "\\")
|
|
135
|
+
i++;
|
|
136
|
+
i++;
|
|
137
|
+
}
|
|
138
|
+
if (i < sql.length)
|
|
139
|
+
i++;
|
|
140
|
+
out += '""';
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
if (ch === "`") {
|
|
144
|
+
i++;
|
|
145
|
+
while (i < sql.length && sql[i] !== "`") {
|
|
146
|
+
if (sql[i] === "\\")
|
|
147
|
+
i++;
|
|
148
|
+
i++;
|
|
149
|
+
}
|
|
150
|
+
if (i < sql.length)
|
|
151
|
+
i++;
|
|
152
|
+
out += "``";
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
if (ch === "[") {
|
|
156
|
+
i++;
|
|
157
|
+
while (i < sql.length && sql[i] !== "]") {
|
|
158
|
+
i++;
|
|
159
|
+
}
|
|
160
|
+
if (i < sql.length)
|
|
161
|
+
i++;
|
|
162
|
+
out += "[]";
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
if (ch === "$" && /^\$\w*\$/.test(sql.slice(i))) {
|
|
166
|
+
// Match historical indexOf-based closer scan for observable parity.
|
|
167
|
+
const end = sql.indexOf("$", i + 1);
|
|
168
|
+
const tagEnd = sql.indexOf("$", end + 1);
|
|
169
|
+
if (tagEnd === -1)
|
|
170
|
+
return out + sql.slice(i);
|
|
171
|
+
i = tagEnd + 1;
|
|
172
|
+
out += "$$";
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
out += ch;
|
|
176
|
+
i++;
|
|
177
|
+
}
|
|
178
|
+
return out;
|
|
179
|
+
}
|
|
180
|
+
const PLACEHOLDER_TOKEN_RE = /:([a-z][a-z0-9_]*)/g;
|
|
181
|
+
/**
|
|
182
|
+
* Find `:name` placeholders only outside quoted regions, in source order.
|
|
183
|
+
* A quoted `':name'` is invisible by construction.
|
|
184
|
+
*/
|
|
185
|
+
export function scanPlaceholders(sql) {
|
|
186
|
+
const spans = tokenizeSqlSpans(sql);
|
|
187
|
+
const out = [];
|
|
188
|
+
for (const span of spans) {
|
|
189
|
+
if (span.kind !== "code")
|
|
190
|
+
continue;
|
|
191
|
+
const segment = sql.slice(span.start, span.end);
|
|
192
|
+
PLACEHOLDER_TOKEN_RE.lastIndex = 0;
|
|
193
|
+
let m;
|
|
194
|
+
while ((m = PLACEHOLDER_TOKEN_RE.exec(segment)) !== null) {
|
|
195
|
+
const name = m[1];
|
|
196
|
+
const start = span.start + m.index;
|
|
197
|
+
const end = start + m[0].length;
|
|
198
|
+
out.push({ name, placeholder: m[0], start, end });
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return out;
|
|
202
|
+
}
|
|
203
|
+
export function scanTenantPlaceholders(sql) {
|
|
204
|
+
return scanPlaceholders(sql).filter((p) => /^tenant_[a-z0-9_]+_ids$/.test(p.name));
|
|
205
|
+
}
|
|
206
|
+
// ---------------------------------------------------------------------------
|
|
207
|
+
// List-context validation
|
|
208
|
+
// ---------------------------------------------------------------------------
|
|
209
|
+
/**
|
|
210
|
+
* A `many` placeholder must be the sole expression inside `IN (...)` / `NOT IN (...)`,
|
|
211
|
+
* or the sole argument of `= ANY(...)` on array dialects.
|
|
212
|
+
*/
|
|
213
|
+
export function isValidListContext(sql, occurrence, listBinding) {
|
|
214
|
+
const before = sql.slice(0, occurrence.start);
|
|
215
|
+
const after = sql.slice(occurrence.end);
|
|
216
|
+
const inBefore = /(?:NOT\s+)?IN\s*\(\s*$/i.exec(before);
|
|
217
|
+
if (inBefore) {
|
|
218
|
+
return /^\s*\)/.test(after);
|
|
219
|
+
}
|
|
220
|
+
if (listBinding === "array") {
|
|
221
|
+
const anyBefore = /=\s*ANY\s*\(\s*$/i.exec(before);
|
|
222
|
+
if (anyBefore) {
|
|
223
|
+
return /^\s*\)/.test(after);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
/** Detect whether an occurrence sits inside IN ( … ) and return the span of `IN (` … `)`. */
|
|
229
|
+
function inListSpan(sql, occ) {
|
|
230
|
+
const before = sql.slice(0, occ.start);
|
|
231
|
+
const after = sql.slice(occ.end);
|
|
232
|
+
const inBefore = /(?:NOT\s+)?IN\s*\(\s*$/i.exec(before);
|
|
233
|
+
if (!inBefore || !/^\s*\)/.test(after))
|
|
234
|
+
return undefined;
|
|
235
|
+
const closeMatch = /^\s*\)/.exec(after);
|
|
236
|
+
return {
|
|
237
|
+
start: occ.start - inBefore[0].length,
|
|
238
|
+
end: occ.end + closeMatch[0].length,
|
|
239
|
+
isNot: /^NOT\s+/i.test(inBefore[0]),
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
function anySpan(sql, occ) {
|
|
243
|
+
const before = sql.slice(0, occ.start);
|
|
244
|
+
const after = sql.slice(occ.end);
|
|
245
|
+
const anyBefore = /=\s*ANY\s*\(\s*$/i.exec(before);
|
|
246
|
+
if (!anyBefore || !/^\s*\)/.test(after))
|
|
247
|
+
return undefined;
|
|
248
|
+
const closeMatch = /^\s*\)/.exec(after);
|
|
249
|
+
return {
|
|
250
|
+
start: occ.start - anyBefore[0].length,
|
|
251
|
+
end: occ.end + closeMatch[0].length,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
// ---------------------------------------------------------------------------
|
|
255
|
+
// Dialect-aware literal escaping
|
|
256
|
+
// ---------------------------------------------------------------------------
|
|
257
|
+
const CONTROL_CHAR_RE = /[\u0000-\u001f\u007f]/;
|
|
258
|
+
/**
|
|
259
|
+
* Escape a scalar value as a SQL literal for the given dialect.
|
|
260
|
+
* Never includes the raw parameter value in thrown error messages.
|
|
261
|
+
*/
|
|
262
|
+
export function escapeSqlLiteral(value, dialect) {
|
|
263
|
+
if (typeof value === "boolean") {
|
|
264
|
+
return value ? "TRUE" : "FALSE";
|
|
265
|
+
}
|
|
266
|
+
if (typeof value === "number") {
|
|
267
|
+
if (!Number.isFinite(value)) {
|
|
268
|
+
throw paramError("INVALID_VALUE", "Numeric parameter must be a finite number.");
|
|
269
|
+
}
|
|
270
|
+
return String(value);
|
|
271
|
+
}
|
|
272
|
+
if (CONTROL_CHAR_RE.test(value)) {
|
|
273
|
+
throw paramError("INVALID_VALUE", "String parameter contains a disallowed control character.");
|
|
274
|
+
}
|
|
275
|
+
let escaped = value.replace(/'/g, "''");
|
|
276
|
+
if (dialect?.backslashEscapes === true) {
|
|
277
|
+
escaped = escaped.replace(/\\/g, "\\\\");
|
|
278
|
+
}
|
|
279
|
+
return `'${escaped}'`;
|
|
280
|
+
}
|
|
281
|
+
export function escapeSqlLiteralList(values, dialect) {
|
|
282
|
+
return `(${values.map((v) => escapeSqlLiteral(v, dialect)).join(", ")})`;
|
|
283
|
+
}
|
|
284
|
+
/** Quote-doubling only — used when no dialect is supplied (legacy tenant path). */
|
|
285
|
+
export function escapeSqlLiteralLegacy(value) {
|
|
286
|
+
return "'" + value.replace(/'/g, "''") + "'";
|
|
287
|
+
}
|
|
288
|
+
export function markerStyleForDialect(id) {
|
|
289
|
+
switch (id) {
|
|
290
|
+
case "postgres":
|
|
291
|
+
case "cockroachdb":
|
|
292
|
+
return "dollar";
|
|
293
|
+
case "sqlserver":
|
|
294
|
+
return "atp";
|
|
295
|
+
case "mysql":
|
|
296
|
+
case "mariadb":
|
|
297
|
+
case "sqlite":
|
|
298
|
+
return "question";
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
export function formatMarker(style, ordinal) {
|
|
302
|
+
switch (style) {
|
|
303
|
+
case "dollar":
|
|
304
|
+
return `$${ordinal}`;
|
|
305
|
+
case "question":
|
|
306
|
+
return "?";
|
|
307
|
+
case "atp":
|
|
308
|
+
return `@p${ordinal}`;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
function listBindingOf(spec) {
|
|
312
|
+
return spec.listBinding ?? "expand";
|
|
313
|
+
}
|
|
314
|
+
function nextMarker(style, counters) {
|
|
315
|
+
switch (style) {
|
|
316
|
+
case "dollar":
|
|
317
|
+
return formatMarker("dollar", counters.dollar++);
|
|
318
|
+
case "atp":
|
|
319
|
+
return formatMarker("atp", counters.atp++);
|
|
320
|
+
case "question":
|
|
321
|
+
return formatMarker("question", 0);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
// ---------------------------------------------------------------------------
|
|
325
|
+
// bindPreparedQuery
|
|
326
|
+
// ---------------------------------------------------------------------------
|
|
327
|
+
function paramError(reason, message) {
|
|
328
|
+
return new QueryParameterError(message, reason);
|
|
329
|
+
}
|
|
330
|
+
function lookupValue(values, name, placeholder) {
|
|
331
|
+
if (Object.prototype.hasOwnProperty.call(values, placeholder)) {
|
|
332
|
+
return values[placeholder];
|
|
333
|
+
}
|
|
334
|
+
if (Object.prototype.hasOwnProperty.call(values, name)) {
|
|
335
|
+
return values[name];
|
|
336
|
+
}
|
|
337
|
+
return undefined;
|
|
338
|
+
}
|
|
339
|
+
function assertValueMatchesDeclaration(value, type, cardinality) {
|
|
340
|
+
if (cardinality === "many") {
|
|
341
|
+
if (!Array.isArray(value)) {
|
|
342
|
+
throw paramError("INVALID_VALUE", "List parameter requires a non-empty array value.");
|
|
343
|
+
}
|
|
344
|
+
if (value.length === 0) {
|
|
345
|
+
throw paramError("INVALID_VALUE", "List parameter requires a non-empty array value.");
|
|
346
|
+
}
|
|
347
|
+
return value.map((v) => assertScalar(v, type));
|
|
348
|
+
}
|
|
349
|
+
if (Array.isArray(value)) {
|
|
350
|
+
throw paramError("INVALID_VALUE", "Scalar parameter must not be an array.");
|
|
351
|
+
}
|
|
352
|
+
return assertScalar(value, type);
|
|
353
|
+
}
|
|
354
|
+
function assertScalar(value, type) {
|
|
355
|
+
if (value === null || value === undefined) {
|
|
356
|
+
throw paramError("INVALID_VALUE", "Parameter value must not be null or undefined.");
|
|
357
|
+
}
|
|
358
|
+
if (typeof value === "object") {
|
|
359
|
+
throw paramError("INVALID_VALUE", "Parameter value must be a string, number, or boolean.");
|
|
360
|
+
}
|
|
361
|
+
switch (type) {
|
|
362
|
+
case "string":
|
|
363
|
+
case "date":
|
|
364
|
+
case "datetime":
|
|
365
|
+
if (typeof value !== "string") {
|
|
366
|
+
throw paramError("INVALID_VALUE", `Parameter of type ${type} requires a string value.`);
|
|
367
|
+
}
|
|
368
|
+
if (type === "date" && !/^\d{4}-\d{2}-\d{2}$/.test(value)) {
|
|
369
|
+
throw paramError("INVALID_VALUE", "Date parameter must be an ISO date string (YYYY-MM-DD).");
|
|
370
|
+
}
|
|
371
|
+
if (type === "datetime" &&
|
|
372
|
+
!/^\d{4}-\d{2}-\d{2}([T ]\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:?\d{2})?)?$/.test(value)) {
|
|
373
|
+
throw paramError("INVALID_VALUE", "Datetime parameter must be an ISO datetime string.");
|
|
374
|
+
}
|
|
375
|
+
return value;
|
|
376
|
+
case "number":
|
|
377
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
378
|
+
throw paramError("INVALID_VALUE", "Numeric parameter must be a finite number.");
|
|
379
|
+
}
|
|
380
|
+
return value;
|
|
381
|
+
case "boolean":
|
|
382
|
+
if (typeof value !== "boolean") {
|
|
383
|
+
throw paramError("INVALID_VALUE", "Boolean parameter requires a boolean value.");
|
|
384
|
+
}
|
|
385
|
+
return value;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Pure, synchronous binder. Substitutes placeholders with escaped literals and
|
|
390
|
+
* allocates dialect-correct driver markers. Does not authorize tenant IDs.
|
|
391
|
+
*/
|
|
392
|
+
export function bindPreparedQuery(prepared, values) {
|
|
393
|
+
const spec = BUILT_IN_DIALECTS[prepared.dialect];
|
|
394
|
+
if (!spec) {
|
|
395
|
+
throw paramError("DIALECT_UNSUPPORTED", `Unknown dialect '${prepared.dialect}'.`);
|
|
396
|
+
}
|
|
397
|
+
const listBinding = listBindingOf(spec);
|
|
398
|
+
const style = markerStyleForDialect(prepared.dialect);
|
|
399
|
+
const namedSql = prepared.namedSql;
|
|
400
|
+
const occurrences = scanPlaceholders(namedSql);
|
|
401
|
+
const declByName = new Map(prepared.parameters.map((p) => [p.name, p]));
|
|
402
|
+
for (const p of prepared.parameters) {
|
|
403
|
+
if (!occurrences.some((o) => o.name === p.name)) {
|
|
404
|
+
throw paramError("UNRESOLVED_PLACEHOLDER", `Declared parameter '${p.name}' does not appear in namedSql.`);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
for (const occ of occurrences) {
|
|
408
|
+
if (!declByName.has(occ.name)) {
|
|
409
|
+
throw paramError("UNRESOLVED_PLACEHOLDER", `Placeholder '${occ.placeholder}' has no matching parameter declaration.`);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
const resolvedValues = new Map();
|
|
413
|
+
for (const p of prepared.parameters) {
|
|
414
|
+
const raw = lookupValue(values, p.name, p.placeholder);
|
|
415
|
+
if (raw === undefined) {
|
|
416
|
+
throw paramError("MISSING_VALUE", `Missing value for parameter '${p.name}'.`);
|
|
417
|
+
}
|
|
418
|
+
resolvedValues.set(p.name, assertValueMatchesDeclaration(raw, p.type, p.cardinality));
|
|
419
|
+
}
|
|
420
|
+
for (const occ of occurrences) {
|
|
421
|
+
const decl = declByName.get(occ.name);
|
|
422
|
+
if (decl.cardinality === "many" && !isValidListContext(namedSql, occ, listBinding)) {
|
|
423
|
+
throw paramError("INVALID_LIST_CONTEXT", `List parameter '${occ.name}' must appear as the sole expression inside IN (...)` +
|
|
424
|
+
(listBinding === "array" ? " or = ANY(...)" : "") +
|
|
425
|
+
".");
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
const edits = [];
|
|
429
|
+
const params = [];
|
|
430
|
+
const bindings = [];
|
|
431
|
+
const bindingByName = new Map();
|
|
432
|
+
const counters = { dollar: 1, atp: 0 };
|
|
433
|
+
const ensureBinding = (decl, value) => {
|
|
434
|
+
let binding = bindingByName.get(decl.name);
|
|
435
|
+
if (!binding) {
|
|
436
|
+
binding = {
|
|
437
|
+
name: decl.name,
|
|
438
|
+
placeholder: decl.placeholder,
|
|
439
|
+
type: decl.type,
|
|
440
|
+
cardinality: decl.cardinality,
|
|
441
|
+
description: decl.description,
|
|
442
|
+
value,
|
|
443
|
+
markers: [],
|
|
444
|
+
indices: [],
|
|
445
|
+
source: decl.source,
|
|
446
|
+
};
|
|
447
|
+
bindingByName.set(decl.name, binding);
|
|
448
|
+
bindings.push(binding);
|
|
449
|
+
}
|
|
450
|
+
return binding;
|
|
451
|
+
};
|
|
452
|
+
for (const occ of occurrences) {
|
|
453
|
+
const decl = declByName.get(occ.name);
|
|
454
|
+
const value = resolvedValues.get(occ.name);
|
|
455
|
+
if (decl.cardinality === "many") {
|
|
456
|
+
const list = value;
|
|
457
|
+
const listLiteral = escapeSqlLiteralList(list, spec);
|
|
458
|
+
const binding = ensureBinding(decl, value);
|
|
459
|
+
if (listBinding === "array") {
|
|
460
|
+
// One array-typed driver param. unboundSql uses = ANY($n); bound sql uses IN (...).
|
|
461
|
+
const marker = nextMarker(style, counters);
|
|
462
|
+
const indices = [params.length];
|
|
463
|
+
params.push(list);
|
|
464
|
+
binding.markers.push(marker);
|
|
465
|
+
binding.indices.push(...indices);
|
|
466
|
+
const inSp = inListSpan(namedSql, occ);
|
|
467
|
+
const anySp = anySpan(namedSql, occ);
|
|
468
|
+
if (inSp) {
|
|
469
|
+
edits.push({
|
|
470
|
+
start: inSp.start,
|
|
471
|
+
end: inSp.end,
|
|
472
|
+
literal: `${inSp.isNot ? "NOT " : ""}IN ${listLiteral}`,
|
|
473
|
+
marker: inSp.isNot ? `<> ALL(${marker})` : `= ANY(${marker})`,
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
else if (anySp) {
|
|
477
|
+
edits.push({
|
|
478
|
+
start: anySp.start,
|
|
479
|
+
end: anySp.end,
|
|
480
|
+
literal: `IN ${listLiteral}`,
|
|
481
|
+
marker: `= ANY(${marker})`,
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
else {
|
|
485
|
+
// Validated above; defensive.
|
|
486
|
+
edits.push({
|
|
487
|
+
start: occ.start,
|
|
488
|
+
end: occ.end,
|
|
489
|
+
literal: listLiteral,
|
|
490
|
+
marker,
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
else {
|
|
495
|
+
// expand: one marker / literal element per value
|
|
496
|
+
const markerTexts = [];
|
|
497
|
+
for (const item of list) {
|
|
498
|
+
const marker = nextMarker(style, counters);
|
|
499
|
+
markerTexts.push(marker);
|
|
500
|
+
binding.indices.push(params.length);
|
|
501
|
+
binding.markers.push(marker);
|
|
502
|
+
params.push(item);
|
|
503
|
+
}
|
|
504
|
+
const inSp = inListSpan(namedSql, occ);
|
|
505
|
+
if (inSp) {
|
|
506
|
+
// Replace only the placeholder — outer IN ( ) stays; emit bare list.
|
|
507
|
+
edits.push({
|
|
508
|
+
start: occ.start,
|
|
509
|
+
end: occ.end,
|
|
510
|
+
literal: list.map((v) => escapeSqlLiteral(v, spec)).join(", "),
|
|
511
|
+
marker: markerTexts.join(", "),
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
else {
|
|
515
|
+
edits.push({
|
|
516
|
+
start: occ.start,
|
|
517
|
+
end: occ.end,
|
|
518
|
+
literal: listLiteral,
|
|
519
|
+
marker: `(${markerTexts.join(", ")})`,
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
else {
|
|
525
|
+
const scalar = value;
|
|
526
|
+
const literal = escapeSqlLiteral(scalar, spec);
|
|
527
|
+
const marker = nextMarker(style, counters);
|
|
528
|
+
const binding = ensureBinding(decl, value);
|
|
529
|
+
binding.markers.push(marker);
|
|
530
|
+
binding.indices.push(params.length);
|
|
531
|
+
params.push(scalar);
|
|
532
|
+
edits.push({ start: occ.start, end: occ.end, literal, marker });
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
edits.sort((a, b) => b.start - a.start);
|
|
536
|
+
let sql = namedSql;
|
|
537
|
+
let unboundSql = namedSql;
|
|
538
|
+
for (const edit of edits) {
|
|
539
|
+
sql = sql.slice(0, edit.start) + edit.literal + sql.slice(edit.end);
|
|
540
|
+
unboundSql = unboundSql.slice(0, edit.start) + edit.marker + unboundSql.slice(edit.end);
|
|
541
|
+
}
|
|
542
|
+
if (scanPlaceholders(sql).length > 0 || scanPlaceholders(unboundSql).length > 0) {
|
|
543
|
+
throw paramError("UNRESOLVED_PLACEHOLDER", "One or more placeholders remain after binding.");
|
|
544
|
+
}
|
|
545
|
+
validateSelectSql(spec, sql);
|
|
546
|
+
validateSelectSql(spec, unboundSql);
|
|
547
|
+
return { sql, unboundSql, params, bindings };
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* Compare two SQL strings structurally for the parameterize consistency check.
|
|
551
|
+
*/
|
|
552
|
+
export function sqlStructurallyEqual(a, b) {
|
|
553
|
+
const norm = (s) => s
|
|
554
|
+
.trim()
|
|
555
|
+
.replace(/;\s*$/, "")
|
|
556
|
+
.replace(/\s+/g, " ")
|
|
557
|
+
.toLowerCase();
|
|
558
|
+
return norm(a) === norm(b);
|
|
559
|
+
}
|
|
560
|
+
//# sourceMappingURL=bind.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bind.js","sourceRoot":"","sources":["../../src/sql/bind.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,6 +23,10 @@ export type DialectSpec = {
|
|
|
23
23
|
extraForbiddenKeywords?: readonly string[];
|
|
24
24
|
/** Optional engine-specific post-validator. Receives SQL already passing the base shape checks. */
|
|
25
25
|
extraValidate?: (sql: string) => void;
|
|
26
|
+
/** How list-valued placeholders bind in `unboundSql`. Default "expand" when absent. */
|
|
27
|
+
listBinding?: "array" | "expand";
|
|
28
|
+
/** Whether backslash is an escape character inside string literals. Default false. */
|
|
29
|
+
backslashEscapes?: boolean;
|
|
26
30
|
};
|
|
27
31
|
/** PostgreSQL — the original AskDB target. */
|
|
28
32
|
export declare const POSTGRES_DIALECT: DialectSpec;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dialect-spec.d.ts","sourceRoot":"","sources":["../../src/sql/dialect-spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,gHAAgH;AAChH,MAAM,MAAM,SAAS,GACjB,UAAU,GACV,aAAa,GACb,OAAO,GACP,SAAS,GACT,QAAQ,GACR,WAAW,CAAC;AAEhB,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,SAAS,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,eAAe,EAAE,GAAG,GAAG,GAAG,CAAC;IAC3B,6EAA6E;IAC7E,sBAAsB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,mGAAmG;IACnG,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"dialect-spec.d.ts","sourceRoot":"","sources":["../../src/sql/dialect-spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,gHAAgH;AAChH,MAAM,MAAM,SAAS,GACjB,UAAU,GACV,aAAa,GACb,OAAO,GACP,SAAS,GACT,QAAQ,GACR,WAAW,CAAC;AAEhB,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,SAAS,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,eAAe,EAAE,GAAG,GAAG,GAAG,CAAC;IAC3B,6EAA6E;IAC7E,sBAAsB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,mGAAmG;IACnG,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,uFAAuF;IACvF,WAAW,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IACjC,sFAAsF;IACtF,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,gBAAgB,EAAE,WAU9B,CAAC;AAEF,kFAAkF;AAClF,eAAO,MAAM,mBAAmB,EAAE,WAIjC,CAAC;AAEF,mEAAmE;AACnE,eAAO,MAAM,aAAa,EAAE,WAY3B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,WAI7B,CAAC;AAEF,+EAA+E;AAC/E,eAAO,MAAM,cAAc,EAAE,WAgB5B,CAAC;AAEF,oCAAoC;AACpC,eAAO,MAAM,iBAAiB,EAAE,WAgB/B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;;;;;CAOqB,CAAC;AAEpD,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,iBAAiB,CAAC;AAE9D,eAAO,MAAM,qBAAqB,EAAE,SAAS,gBAAgB,EAE7B,CAAC;AAEjC,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,gBAAgB,CAE5E;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,gBAAgB,GAAG,WAAW,CAQhE"}
|
package/dist/sql/dialect-spec.js
CHANGED
|
@@ -18,6 +18,8 @@ export const POSTGRES_DIALECT = {
|
|
|
18
18
|
"Quote identifiers with double quotes when they collide with keywords or contain mixed case. " +
|
|
19
19
|
'Cast with `value::type`. Use NOW(), CURRENT_DATE, date_trunc(). Concatenate with `||`.',
|
|
20
20
|
identifierQuote: '"',
|
|
21
|
+
listBinding: "array",
|
|
22
|
+
backslashEscapes: false,
|
|
21
23
|
};
|
|
22
24
|
/** CockroachDB — PostgreSQL-wire-compatible; reuses the Postgres prompt brief. */
|
|
23
25
|
export const COCKROACHDB_DIALECT = {
|
|
@@ -35,6 +37,8 @@ export const MYSQL_DIALECT = {
|
|
|
35
37
|
"Concatenate with `CONCAT(a, b)` — `||` is logical OR in MySQL, not string concat. " +
|
|
36
38
|
"Limit rows with `LIMIT n` (or `LIMIT offset, n`).",
|
|
37
39
|
identifierQuote: "`",
|
|
40
|
+
listBinding: "expand",
|
|
41
|
+
backslashEscapes: true,
|
|
38
42
|
};
|
|
39
43
|
/**
|
|
40
44
|
* MariaDB — MySQL-protocol-compatible; the SELECT surface is functionally
|
|
@@ -60,6 +64,8 @@ export const SQLITE_DIALECT = {
|
|
|
60
64
|
// is maintenance. None belong in a generated read-only SELECT. (`vacuum` is
|
|
61
65
|
// already in the dialect-agnostic base denylist.)
|
|
62
66
|
extraForbiddenKeywords: ["attach", "detach", "pragma", "reindex"],
|
|
67
|
+
listBinding: "expand",
|
|
68
|
+
backslashEscapes: false,
|
|
63
69
|
};
|
|
64
70
|
/** Microsoft SQL Server (T-SQL). */
|
|
65
71
|
export const SQLSERVER_DIALECT = {
|
|
@@ -75,6 +81,8 @@ export const SQLSERVER_DIALECT = {
|
|
|
75
81
|
// T-SQL keywords that shouldn't appear in read-only analytics SQL. (`call`
|
|
76
82
|
// is already in the base denylist; T-SQL uses EXEC / EXECUTE for procs.)
|
|
77
83
|
extraForbiddenKeywords: ["exec", "execute", "merge", "openrowset", "openquery"],
|
|
84
|
+
listBinding: "expand",
|
|
85
|
+
backslashEscapes: false,
|
|
78
86
|
};
|
|
79
87
|
/**
|
|
80
88
|
* Registry of dialect specs shipped with `@askdb/core`. Connectors that
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dialect-spec.js","sourceRoot":"","sources":["../../src/sql/dialect-spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"dialect-spec.js","sourceRoot":"","sources":["../../src/sql/dialect-spec.ts"],"names":[],"mappings":"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"}
|