@askdb/core 1.0.0-beta.42 → 1.0.0-beta.44
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 +14 -8
- package/dist/ask.d.ts +101 -4
- package/dist/ask.d.ts.map +1 -1
- package/dist/ask.js +243 -25
- package/dist/ask.js.map +1 -1
- package/dist/enrichment/suggest.d.ts.map +1 -1
- package/dist/enrichment/suggest.js +3 -1
- package/dist/enrichment/suggest.js.map +1 -1
- package/dist/errors.d.ts +41 -5
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +9 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +8 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/retrieval/synthesize-ddl.d.ts +4 -0
- package/dist/retrieval/synthesize-ddl.d.ts.map +1 -1
- package/dist/retrieval/synthesize-ddl.js +5 -3
- package/dist/retrieval/synthesize-ddl.js.map +1 -1
- package/dist/schema/normalize.d.ts +10 -0
- package/dist/schema/normalize.d.ts.map +1 -1
- package/dist/schema/normalize.js.map +1 -1
- package/dist/schema/v2/format.d.ts +7 -0
- package/dist/schema/v2/format.d.ts.map +1 -1
- package/dist/schema/v2/format.js +20 -7
- package/dist/schema/v2/format.js.map +1 -1
- package/dist/schema/v2/index.d.ts +3 -1
- package/dist/schema/v2/index.d.ts.map +1 -1
- package/dist/schema/v2/index.js +1 -0
- package/dist/schema/v2/index.js.map +1 -1
- package/dist/schema/v2/loader.d.ts +32 -1
- package/dist/schema/v2/loader.d.ts.map +1 -1
- package/dist/schema/v2/loader.js +173 -49
- package/dist/schema/v2/loader.js.map +1 -1
- package/dist/schema/v2/mentions.d.ts +31 -0
- package/dist/schema/v2/mentions.d.ts.map +1 -0
- package/dist/schema/v2/mentions.js +47 -0
- package/dist/schema/v2/mentions.js.map +1 -0
- package/dist/schema/v2/normalized.d.ts +38 -0
- package/dist/schema/v2/normalized.d.ts.map +1 -1
- package/dist/schema/v2/parser.d.ts +9 -0
- package/dist/schema/v2/parser.d.ts.map +1 -1
- package/dist/schema/v2/parser.js +18 -2
- package/dist/schema/v2/parser.js.map +1 -1
- package/dist/schema/v2/tenant-policy-loader.d.ts.map +1 -1
- package/dist/schema/v2/tenant-policy-loader.js +7 -3
- package/dist/schema/v2/tenant-policy-loader.js.map +1 -1
- package/dist/schema/v2/tenant-policy.d.ts +28 -21
- package/dist/schema/v2/tenant-policy.d.ts.map +1 -1
- package/dist/schema/v2/tenant-policy.js +67 -11
- package/dist/schema/v2/tenant-policy.js.map +1 -1
- package/dist/sql/bind.d.ts +17 -15
- package/dist/sql/bind.d.ts.map +1 -1
- package/dist/sql/bind.js +38 -173
- package/dist/sql/bind.js.map +1 -1
- package/dist/sql/dialect-spec.d.ts +48 -3
- package/dist/sql/dialect-spec.d.ts.map +1 -1
- package/dist/sql/dialect-spec.js +89 -3
- package/dist/sql/dialect-spec.js.map +1 -1
- package/dist/sql/generate.d.ts +14 -0
- package/dist/sql/generate.d.ts.map +1 -1
- package/dist/sql/generate.js +31 -17
- package/dist/sql/generate.js.map +1 -1
- package/dist/sql/index.d.ts +2 -1
- package/dist/sql/index.d.ts.map +1 -1
- package/dist/sql/index.js +2 -1
- package/dist/sql/index.js.map +1 -1
- package/dist/sql/lexer.d.ts +114 -0
- package/dist/sql/lexer.d.ts.map +1 -0
- package/dist/sql/lexer.js +397 -0
- package/dist/sql/lexer.js.map +1 -0
- package/dist/sql/prompt-identifiers.d.ts +20 -0
- package/dist/sql/prompt-identifiers.d.ts.map +1 -0
- package/dist/sql/prompt-identifiers.js +64 -0
- package/dist/sql/prompt-identifiers.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 +22 -2
- package/dist/sql/prompt.js.map +1 -1
- package/dist/sql/reserved-words.d.ts +15 -0
- package/dist/sql/reserved-words.d.ts.map +1 -0
- package/dist/sql/reserved-words.js +102 -0
- package/dist/sql/reserved-words.js.map +1 -0
- package/dist/sql/sensitive-guardrail.d.ts +18 -3
- package/dist/sql/sensitive-guardrail.d.ts.map +1 -1
- package/dist/sql/sensitive-guardrail.js +446 -157
- package/dist/sql/sensitive-guardrail.js.map +1 -1
- package/dist/sql/tenant-guardrail.d.ts +70 -8
- package/dist/sql/tenant-guardrail.d.ts.map +1 -1
- package/dist/sql/tenant-guardrail.js +799 -52
- package/dist/sql/tenant-guardrail.js.map +1 -1
- package/dist/sql/tenant-hierarchy.d.ts +19 -0
- package/dist/sql/tenant-hierarchy.d.ts.map +1 -0
- package/dist/sql/tenant-hierarchy.js +53 -0
- package/dist/sql/tenant-hierarchy.js.map +1 -0
- package/dist/sql/tenant-placeholders.d.ts +47 -19
- package/dist/sql/tenant-placeholders.d.ts.map +1 -1
- package/dist/sql/tenant-placeholders.js +229 -58
- package/dist/sql/tenant-placeholders.js.map +1 -1
- package/dist/sql/tenant-prompt.d.ts +4 -0
- package/dist/sql/tenant-prompt.d.ts.map +1 -1
- package/dist/sql/tenant-prompt.js +79 -11
- package/dist/sql/tenant-prompt.js.map +1 -1
- package/dist/sql/tenant-scope-validate.d.ts +3 -1
- package/dist/sql/tenant-scope-validate.d.ts.map +1 -1
- package/dist/sql/tenant-scope-validate.js +5 -2
- package/dist/sql/tenant-scope-validate.js.map +1 -1
- package/dist/sql/validate.d.ts +34 -4
- package/dist/sql/validate.d.ts.map +1 -1
- package/dist/sql/validate.js +138 -37
- package/dist/sql/validate.js.map +1 -1
- package/package.json +11 -7
- package/dist/exec/postgres.d.ts +0 -6
- package/dist/exec/postgres.d.ts.map +0 -1
- package/dist/exec/postgres.js +0 -30
- package/dist/exec/postgres.js.map +0 -1
- package/dist/modes/post-execute-log.d.ts +0 -9
- package/dist/modes/post-execute-log.d.ts.map +0 -1
- package/dist/modes/post-execute-log.js +0 -26
- package/dist/modes/post-execute-log.js.map +0 -1
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
export const POSTGRES_LEXER = {
|
|
2
|
+
id: "postgres",
|
|
3
|
+
backslashEscapes: false,
|
|
4
|
+
doubleQuote: "identifier",
|
|
5
|
+
backtickIdentifiers: false,
|
|
6
|
+
bracketIdentifiers: false,
|
|
7
|
+
dollarQuotes: true,
|
|
8
|
+
escapeStrings: true,
|
|
9
|
+
hashComments: false,
|
|
10
|
+
dashCommentNeedsSpace: false,
|
|
11
|
+
nestedBlockComments: true,
|
|
12
|
+
executableComments: false,
|
|
13
|
+
atVariables: false,
|
|
14
|
+
hashIdentifiers: false,
|
|
15
|
+
};
|
|
16
|
+
export const MYSQL_LEXER = {
|
|
17
|
+
id: "mysql",
|
|
18
|
+
backslashEscapes: true,
|
|
19
|
+
doubleQuote: "string",
|
|
20
|
+
backtickIdentifiers: true,
|
|
21
|
+
bracketIdentifiers: false,
|
|
22
|
+
dollarQuotes: false,
|
|
23
|
+
escapeStrings: false,
|
|
24
|
+
hashComments: true,
|
|
25
|
+
dashCommentNeedsSpace: true,
|
|
26
|
+
nestedBlockComments: false,
|
|
27
|
+
executableComments: true,
|
|
28
|
+
atVariables: true,
|
|
29
|
+
hashIdentifiers: false,
|
|
30
|
+
};
|
|
31
|
+
export const SQLSERVER_LEXER = {
|
|
32
|
+
id: "sqlserver",
|
|
33
|
+
backslashEscapes: false,
|
|
34
|
+
doubleQuote: "identifier",
|
|
35
|
+
backtickIdentifiers: false,
|
|
36
|
+
bracketIdentifiers: "doubled",
|
|
37
|
+
dollarQuotes: false,
|
|
38
|
+
escapeStrings: false,
|
|
39
|
+
hashComments: false,
|
|
40
|
+
dashCommentNeedsSpace: false,
|
|
41
|
+
nestedBlockComments: true,
|
|
42
|
+
executableComments: false,
|
|
43
|
+
atVariables: true,
|
|
44
|
+
hashIdentifiers: true,
|
|
45
|
+
};
|
|
46
|
+
export const SQLITE_LEXER = {
|
|
47
|
+
id: "sqlite",
|
|
48
|
+
backslashEscapes: false,
|
|
49
|
+
doubleQuote: "identifier",
|
|
50
|
+
backtickIdentifiers: true,
|
|
51
|
+
bracketIdentifiers: "simple",
|
|
52
|
+
dollarQuotes: false,
|
|
53
|
+
escapeStrings: false,
|
|
54
|
+
hashComments: false,
|
|
55
|
+
dashCommentNeedsSpace: false,
|
|
56
|
+
nestedBlockComments: false,
|
|
57
|
+
executableComments: false,
|
|
58
|
+
atVariables: true,
|
|
59
|
+
hashIdentifiers: false,
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Dialect-agnostic profile for callers that have no dialect (the tenant placeholder
|
|
63
|
+
* path, the sensitive guardrail when no dialect is supplied). Recognizes the union of
|
|
64
|
+
* quoting forms — `'…'`, `E'…'`, `$tag$…$tag$`, `"…"`, `` `…` ``, `[…]` — with the
|
|
65
|
+
* escape rules the owning engine uses, and standard `--` / `/* *\/` comments.
|
|
66
|
+
*/
|
|
67
|
+
export const GENERIC_LEXER = {
|
|
68
|
+
id: "generic",
|
|
69
|
+
backslashEscapes: false,
|
|
70
|
+
doubleQuote: "identifier",
|
|
71
|
+
backtickIdentifiers: true,
|
|
72
|
+
bracketIdentifiers: "doubled",
|
|
73
|
+
dollarQuotes: true,
|
|
74
|
+
escapeStrings: true,
|
|
75
|
+
hashComments: false,
|
|
76
|
+
dashCommentNeedsSpace: false,
|
|
77
|
+
nestedBlockComments: false,
|
|
78
|
+
executableComments: false,
|
|
79
|
+
atVariables: true,
|
|
80
|
+
hashIdentifiers: false,
|
|
81
|
+
};
|
|
82
|
+
/** Every engine-specific profile. Used when the dialect is unknown and each reading must be safe. */
|
|
83
|
+
export const ENGINE_LEXER_PROFILES = [
|
|
84
|
+
POSTGRES_LEXER,
|
|
85
|
+
MYSQL_LEXER,
|
|
86
|
+
SQLSERVER_LEXER,
|
|
87
|
+
SQLITE_LEXER,
|
|
88
|
+
];
|
|
89
|
+
/**
|
|
90
|
+
* The lexer profile for a dialect, or `undefined` when the id is not a built-in engine
|
|
91
|
+
* family (callers should then check every profile in {@link ENGINE_LEXER_PROFILES}).
|
|
92
|
+
*
|
|
93
|
+
* `backslashEscapes` on the spec is honored: MySQL with `NO_BACKSLASH_ESCAPES` sets it
|
|
94
|
+
* to `false`; Postgres with `standard_conforming_strings = off` sets it to `true`.
|
|
95
|
+
* An unset value on a MySQL-family spec means the server default (escapes on).
|
|
96
|
+
*/
|
|
97
|
+
export function lexerProfileFor(dialect) {
|
|
98
|
+
switch (dialect.id) {
|
|
99
|
+
case "postgres":
|
|
100
|
+
case "cockroachdb":
|
|
101
|
+
return dialect.backslashEscapes === true
|
|
102
|
+
? { ...POSTGRES_LEXER, backslashEscapes: true }
|
|
103
|
+
: POSTGRES_LEXER;
|
|
104
|
+
case "mysql":
|
|
105
|
+
case "mariadb":
|
|
106
|
+
return dialect.backslashEscapes === false
|
|
107
|
+
? { ...MYSQL_LEXER, backslashEscapes: false }
|
|
108
|
+
: MYSQL_LEXER;
|
|
109
|
+
case "sqlserver":
|
|
110
|
+
return SQLSERVER_LEXER;
|
|
111
|
+
case "sqlite":
|
|
112
|
+
return SQLITE_LEXER;
|
|
113
|
+
default:
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const WORD_START = /[A-Za-z_\u0080-]/;
|
|
118
|
+
const WORD_CHAR = /[A-Za-z0-9_$\u0080-]/;
|
|
119
|
+
const DIGIT = /[0-9]/;
|
|
120
|
+
const HEX = /[0-9A-Fa-f]/;
|
|
121
|
+
const DOLLAR_TAG = /^\$([A-Za-z_\u0080-][A-Za-z0-9_\u0080-]*)?\$/;
|
|
122
|
+
/**
|
|
123
|
+
* Whether the `--` at `i` starts a line comment. It always does, except on MySQL/MariaDB
|
|
124
|
+
* (`needsSpace`), where it must be followed by whitespace, a control character, or the end
|
|
125
|
+
* of the statement: there `--1` is two minus signs and a number.
|
|
126
|
+
*/
|
|
127
|
+
export function startsDashComment(sql, i, needsSpace) {
|
|
128
|
+
if (sql[i] !== "-" || sql[i + 1] !== "-")
|
|
129
|
+
return false;
|
|
130
|
+
const after = sql[i + 2];
|
|
131
|
+
return !needsSpace || after === undefined || /[\s\x00-\x1f]/.test(after);
|
|
132
|
+
}
|
|
133
|
+
/** Split `sql` into tokens under `profile`. Whitespace is dropped; comments are kept. */
|
|
134
|
+
export function lexSql(sql, profile) {
|
|
135
|
+
const tokens = [];
|
|
136
|
+
const n = sql.length;
|
|
137
|
+
let i = 0;
|
|
138
|
+
/** Index in `tokens` of the open MySQL `/*! … *\/` executable-comment opener, or -1. */
|
|
139
|
+
let executableOpener = -1;
|
|
140
|
+
const push = (kind, start, end, extra) => {
|
|
141
|
+
const text = sql.slice(start, end);
|
|
142
|
+
const value = extra?.value ?? text;
|
|
143
|
+
const token = { kind, text, value, lower: value.toLowerCase(), start, end };
|
|
144
|
+
if (extra?.quote !== undefined)
|
|
145
|
+
token.quote = extra.quote;
|
|
146
|
+
if (extra?.unterminated)
|
|
147
|
+
token.unterminated = true;
|
|
148
|
+
tokens.push(token);
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* Scan a delimited run starting after the opening delimiter at `from`. `close` doubled
|
|
152
|
+
* is always an escaped delimiter; `backslash` additionally makes `\x` an escape.
|
|
153
|
+
*/
|
|
154
|
+
const scanDelimited = (from, close, backslash) => {
|
|
155
|
+
let j = from;
|
|
156
|
+
let value = "";
|
|
157
|
+
while (j < n) {
|
|
158
|
+
const c = sql[j];
|
|
159
|
+
if (backslash && c === "\\") {
|
|
160
|
+
value += sql.slice(j, j + 2);
|
|
161
|
+
j += 2;
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (c === close) {
|
|
165
|
+
if (sql[j + 1] === close) {
|
|
166
|
+
value += close;
|
|
167
|
+
j += 2;
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
return { end: j + 1, value, terminated: true };
|
|
171
|
+
}
|
|
172
|
+
value += c;
|
|
173
|
+
j++;
|
|
174
|
+
}
|
|
175
|
+
return { end: n, value, terminated: false };
|
|
176
|
+
};
|
|
177
|
+
const lexString = (start, quoteAt, backslash, kind) => {
|
|
178
|
+
const q = sql[quoteAt];
|
|
179
|
+
const r = scanDelimited(quoteAt + 1, q, backslash);
|
|
180
|
+
push(kind, start, Math.min(r.end, n), {
|
|
181
|
+
quote: q,
|
|
182
|
+
...(kind === "quoted_identifier" ? { value: r.value } : {}),
|
|
183
|
+
unterminated: !r.terminated,
|
|
184
|
+
});
|
|
185
|
+
i = r.end;
|
|
186
|
+
};
|
|
187
|
+
while (i < n) {
|
|
188
|
+
const ch = sql[i];
|
|
189
|
+
const next = sql[i + 1];
|
|
190
|
+
if (/\s/.test(ch)) {
|
|
191
|
+
i++;
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
// ---- comments -------------------------------------------------------
|
|
195
|
+
if (ch === "-" && next === "-") {
|
|
196
|
+
if (startsDashComment(sql, i, profile.dashCommentNeedsSpace)) {
|
|
197
|
+
let j = i + 2;
|
|
198
|
+
while (j < n && sql[j] !== "\n" && sql[j] !== "\r")
|
|
199
|
+
j++;
|
|
200
|
+
push("comment", i, j);
|
|
201
|
+
i = j;
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (ch === "#" && profile.hashComments) {
|
|
206
|
+
let j = i + 1;
|
|
207
|
+
while (j < n && sql[j] !== "\n" && sql[j] !== "\r")
|
|
208
|
+
j++;
|
|
209
|
+
push("comment", i, j);
|
|
210
|
+
i = j;
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (ch === "*" && next === "/" && executableOpener !== -1) {
|
|
214
|
+
push("comment", i, i + 2);
|
|
215
|
+
executableOpener = -1;
|
|
216
|
+
i += 2;
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
if (ch === "/" && next === "*") {
|
|
220
|
+
if (profile.executableComments && executableOpener === -1) {
|
|
221
|
+
const exec = /^\/\*M?!\d*/.exec(sql.slice(i));
|
|
222
|
+
if (exec) {
|
|
223
|
+
executableOpener = tokens.length;
|
|
224
|
+
push("comment", i, i + exec[0].length);
|
|
225
|
+
i += exec[0].length;
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
let j = i + 2;
|
|
230
|
+
let depth = 1;
|
|
231
|
+
while (j < n) {
|
|
232
|
+
if (sql[j] === "*" && sql[j + 1] === "/") {
|
|
233
|
+
depth--;
|
|
234
|
+
j += 2;
|
|
235
|
+
if (depth === 0)
|
|
236
|
+
break;
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
if (profile.nestedBlockComments && sql[j] === "/" && sql[j + 1] === "*") {
|
|
240
|
+
depth++;
|
|
241
|
+
j += 2;
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
j++;
|
|
245
|
+
}
|
|
246
|
+
push("comment", i, Math.min(j, n), { unterminated: depth > 0 });
|
|
247
|
+
i = j;
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
// ---- strings and quoted identifiers ---------------------------------
|
|
251
|
+
if (ch === "'") {
|
|
252
|
+
lexString(i, i, profile.backslashEscapes, "string");
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
if (ch === '"') {
|
|
256
|
+
if (profile.doubleQuote === "identifier")
|
|
257
|
+
lexString(i, i, false, "quoted_identifier");
|
|
258
|
+
else
|
|
259
|
+
lexString(i, i, profile.backslashEscapes, "string");
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
if (ch === "`" && profile.backtickIdentifiers) {
|
|
263
|
+
lexString(i, i, false, "quoted_identifier");
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
if (ch === "[" && profile.bracketIdentifiers) {
|
|
267
|
+
let j = i + 1;
|
|
268
|
+
let value = "";
|
|
269
|
+
let terminated = false;
|
|
270
|
+
while (j < n) {
|
|
271
|
+
if (sql[j] === "]") {
|
|
272
|
+
if (profile.bracketIdentifiers === "doubled" && sql[j + 1] === "]") {
|
|
273
|
+
value += "]";
|
|
274
|
+
j += 2;
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
j++;
|
|
278
|
+
terminated = true;
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
value += sql[j];
|
|
282
|
+
j++;
|
|
283
|
+
}
|
|
284
|
+
push("quoted_identifier", i, j, { value, quote: "[", unterminated: !terminated });
|
|
285
|
+
i = j;
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
if (ch === "$") {
|
|
289
|
+
if (profile.dollarQuotes) {
|
|
290
|
+
const tag = DOLLAR_TAG.exec(sql.slice(i));
|
|
291
|
+
if (tag) {
|
|
292
|
+
const opener = tag[0];
|
|
293
|
+
const closeAt = sql.indexOf(opener, i + opener.length);
|
|
294
|
+
const end = closeAt === -1 ? n : closeAt + opener.length;
|
|
295
|
+
push("string", i, end, { quote: opener, unterminated: closeAt === -1 });
|
|
296
|
+
i = end;
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (next !== undefined && (DIGIT.test(next) || (!profile.dollarQuotes && WORD_START.test(next)))) {
|
|
301
|
+
let j = i + 1;
|
|
302
|
+
while (j < n && WORD_CHAR.test(sql[j]) && sql[j] !== "$")
|
|
303
|
+
j++;
|
|
304
|
+
push("parameter", i, j);
|
|
305
|
+
i = j;
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
// ---- words (and prefixed string literals) ---------------------------
|
|
310
|
+
if (WORD_START.test(ch) || (ch === "#" && profile.hashIdentifiers && next !== undefined && (next === "#" || WORD_START.test(next)))) {
|
|
311
|
+
let j = i + 1;
|
|
312
|
+
while (j < n && (WORD_CHAR.test(sql[j]) || (profile.hashIdentifiers && sql[j] === "#")))
|
|
313
|
+
j++;
|
|
314
|
+
const word = sql.slice(i, j);
|
|
315
|
+
if (sql[j] === "'" && j - i === 1) {
|
|
316
|
+
const prefix = word.toLowerCase();
|
|
317
|
+
if (prefix === "e" && profile.escapeStrings) {
|
|
318
|
+
lexString(i, j, true, "string");
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
if (prefix === "n" || prefix === "x" || prefix === "b") {
|
|
322
|
+
lexString(i, j, profile.backslashEscapes, "string");
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
push("word", i, j);
|
|
327
|
+
i = j;
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
// ---- numbers --------------------------------------------------------
|
|
331
|
+
if (DIGIT.test(ch) || (ch === "." && next !== undefined && DIGIT.test(next))) {
|
|
332
|
+
let j = i;
|
|
333
|
+
if (ch === "0" && (next === "x" || next === "X") && HEX.test(sql[i + 2] ?? "")) {
|
|
334
|
+
j = i + 2;
|
|
335
|
+
while (j < n && HEX.test(sql[j]))
|
|
336
|
+
j++;
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
while (j < n && DIGIT.test(sql[j]))
|
|
340
|
+
j++;
|
|
341
|
+
if (sql[j] === "." && sql[j + 1] !== ".") {
|
|
342
|
+
j++;
|
|
343
|
+
while (j < n && DIGIT.test(sql[j]))
|
|
344
|
+
j++;
|
|
345
|
+
}
|
|
346
|
+
if ((sql[j] === "e" || sql[j] === "E") && /^[eE][+-]?[0-9]/.test(sql.slice(j))) {
|
|
347
|
+
j += sql[j + 1] === "+" || sql[j + 1] === "-" ? 2 : 1;
|
|
348
|
+
while (j < n && DIGIT.test(sql[j]))
|
|
349
|
+
j++;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
// Trailing letters (`1from`, MySQL `1abc`) are lexed as a separate word so a keyword
|
|
353
|
+
// glued to a number is still seen.
|
|
354
|
+
push("number", i, j);
|
|
355
|
+
i = j;
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
358
|
+
// ---- parameters and punctuation -------------------------------------
|
|
359
|
+
if (ch === ":" && next === ":") {
|
|
360
|
+
push("punct", i, i + 2);
|
|
361
|
+
i += 2;
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
if (ch === ":" && next !== undefined && WORD_START.test(next)) {
|
|
365
|
+
let j = i + 1;
|
|
366
|
+
while (j < n && WORD_CHAR.test(sql[j]))
|
|
367
|
+
j++;
|
|
368
|
+
push("parameter", i, j);
|
|
369
|
+
i = j;
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
if (ch === "@" && profile.atVariables) {
|
|
373
|
+
let j = i + 1;
|
|
374
|
+
if (sql[j] === "@")
|
|
375
|
+
j++;
|
|
376
|
+
if (j < n && WORD_START.test(sql[j])) {
|
|
377
|
+
while (j < n && WORD_CHAR.test(sql[j]))
|
|
378
|
+
j++;
|
|
379
|
+
push("parameter", i, j);
|
|
380
|
+
i = j;
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
push("punct", i, i + 1);
|
|
385
|
+
i++;
|
|
386
|
+
}
|
|
387
|
+
// An executable comment whose `*\/` never came: its body was lexed as code, but the
|
|
388
|
+
// comment itself runs off the end, so flag the opener like any other unclosed comment.
|
|
389
|
+
if (executableOpener !== -1)
|
|
390
|
+
tokens[executableOpener].unterminated = true;
|
|
391
|
+
return tokens;
|
|
392
|
+
}
|
|
393
|
+
/** True when any token ran off the end of the input. */
|
|
394
|
+
export function hasUnterminatedToken(tokens) {
|
|
395
|
+
return tokens.some((t) => t.unterminated === true);
|
|
396
|
+
}
|
|
397
|
+
//# sourceMappingURL=lexer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lexer.js","sourceRoot":"","sources":["../../src/sql/lexer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { DialectSpec } from "./dialect-spec.js";
|
|
2
|
+
type QuotedDialect = Pick<DialectSpec, "id" | "identifierQuote" | "reservedWords" | "extraForbiddenKeywords" | "backslashEscapes">;
|
|
3
|
+
/**
|
|
4
|
+
* How the NL→SQL prompt lists one identifier part (a schema, table or column name) for a
|
|
5
|
+
* dialect: quoted when it is one of the spec's `reservedWords` or a word `validateSelectSql`
|
|
6
|
+
* rejects unquoted, isn't a plain identifier, or
|
|
7
|
+
* has capitals on an engine that folds unquoted names to lowercase (`billing."order"` and
|
|
8
|
+
* `public."Post"` on Postgres, ``billing.`order` `` on MySQL, `billing.[order]` on SQL Server),
|
|
9
|
+
* bare otherwise. Pass it as `quoteIdentifier` to `formatSchemaV2ForNlToSql` or
|
|
10
|
+
* `synthesizeRetrievedDdl`; `ask()` does this itself.
|
|
11
|
+
*/
|
|
12
|
+
export declare function promptIdentifierQuoter(dialect: Pick<DialectSpec, "id" | "identifierQuote" | "reservedWords" | "extraForbiddenKeywords" | "backslashEscapes">): (name: string) => string;
|
|
13
|
+
/**
|
|
14
|
+
* The prompt rule for qualified names, with the dialect's quotes in its example. It shows only
|
|
15
|
+
* the right form: with `never \`schema.table\`` added, gpt-4o-mini quoted the whole dotted name
|
|
16
|
+
* more often, not less (#451).
|
|
17
|
+
*/
|
|
18
|
+
export declare function qualifiedNameQuotingRule(dialect: QuotedDialect): string;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=prompt-identifiers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-identifiers.d.ts","sourceRoot":"","sources":["../../src/sql/prompt-identifiers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA2BrD,KAAK,aAAa,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,iBAAiB,GAAG,eAAe,GAAG,wBAAwB,GAAG,kBAAkB,CAAC,CAAC;AAcnI;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,iBAAiB,GAAG,eAAe,GAAG,wBAAwB,GAAG,kBAAkB,CAAC,GACrH,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAa1B;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAIvE"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { lexerProfileFor } from "./lexer.js";
|
|
2
|
+
import { keywordsRejectedUnquoted } from "./validate.js";
|
|
3
|
+
/** A name the engine tokenizes as one identifier, unless it is a reserved word. */
|
|
4
|
+
const PLAIN_IDENTIFIER = /^[\p{L}_][\p{L}\p{Nd}_$]*$/u;
|
|
5
|
+
/**
|
|
6
|
+
* T-SQL's regular identifiers take letters from Unicode 3.2 only, and no characters outside
|
|
7
|
+
* the Basic Multilingual Plane (`𠮷`, `ẞ`), which `\p{L}` admits. ASCII is the safe subset.
|
|
8
|
+
*/
|
|
9
|
+
const ASCII_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_$]*$/;
|
|
10
|
+
/** Keyed by the lexer's engine family, so a dialect is quoted the way its SQL is lexed. */
|
|
11
|
+
const QUOTING = {
|
|
12
|
+
postgres: { open: '"', close: '"', foldsToLowercase: true, plain: PLAIN_IDENTIFIER },
|
|
13
|
+
mysql: { open: "`", close: "`", foldsToLowercase: false, plain: PLAIN_IDENTIFIER },
|
|
14
|
+
// Brackets, not double quotes: double quotes are a string under `SET QUOTED_IDENTIFIER OFF` (sqlcmd's default).
|
|
15
|
+
sqlserver: { open: "[", close: "]", foldsToLowercase: false, plain: ASCII_IDENTIFIER },
|
|
16
|
+
sqlite: { open: '"', close: '"', foldsToLowercase: false, plain: PLAIN_IDENTIFIER },
|
|
17
|
+
};
|
|
18
|
+
/** An id that is no built-in engine family quotes with `identifierQuote`. */
|
|
19
|
+
function quotingFor(dialect) {
|
|
20
|
+
const family = lexerProfileFor(dialect)?.id;
|
|
21
|
+
return family && family !== "generic"
|
|
22
|
+
? QUOTING[family]
|
|
23
|
+
: { open: dialect.identifierQuote, close: dialect.identifierQuote, foldsToLowercase: false, plain: PLAIN_IDENTIFIER };
|
|
24
|
+
}
|
|
25
|
+
function quote(quoting, name) {
|
|
26
|
+
return `${quoting.open}${name.split(quoting.close).join(quoting.close + quoting.close)}${quoting.close}`;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* How the NL→SQL prompt lists one identifier part (a schema, table or column name) for a
|
|
30
|
+
* dialect: quoted when it is one of the spec's `reservedWords` or a word `validateSelectSql`
|
|
31
|
+
* rejects unquoted, isn't a plain identifier, or
|
|
32
|
+
* has capitals on an engine that folds unquoted names to lowercase (`billing."order"` and
|
|
33
|
+
* `public."Post"` on Postgres, ``billing.`order` `` on MySQL, `billing.[order]` on SQL Server),
|
|
34
|
+
* bare otherwise. Pass it as `quoteIdentifier` to `formatSchemaV2ForNlToSql` or
|
|
35
|
+
* `synthesizeRetrievedDdl`; `ask()` does this itself.
|
|
36
|
+
*/
|
|
37
|
+
export function promptIdentifierQuoter(dialect) {
|
|
38
|
+
const quoting = quotingFor(dialect);
|
|
39
|
+
// The engine's reserved words, and the words AskDB's validator rejects unquoted (`copy`, `merge`).
|
|
40
|
+
const reserved = new Set([
|
|
41
|
+
...(dialect.reservedWords ?? []).map((word) => word.toLowerCase()),
|
|
42
|
+
...keywordsRejectedUnquoted(dialect),
|
|
43
|
+
]);
|
|
44
|
+
return (name) => quoting.plain.test(name) &&
|
|
45
|
+
!reserved.has(name.toLowerCase()) &&
|
|
46
|
+
!(quoting.foldsToLowercase && name !== name.toLowerCase())
|
|
47
|
+
? name
|
|
48
|
+
: quote(quoting, name);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The prompt rule for qualified names, with the dialect's quotes in its example. It shows only
|
|
52
|
+
* the right form: with `never \`schema.table\`` added, gpt-4o-mini quoted the whole dotted name
|
|
53
|
+
* more often, not less (#451).
|
|
54
|
+
*/
|
|
55
|
+
export function qualifiedNameQuotingRule(dialect) {
|
|
56
|
+
const quoting = quotingFor(dialect);
|
|
57
|
+
const parts = `${quote(quoting, "schema")}.${quote(quoting, "table")}`;
|
|
58
|
+
return `- When you quote a qualified name, quote each part separately: ${inlineCode(parts)}.`;
|
|
59
|
+
}
|
|
60
|
+
/** Markdown inline code that may itself contain backticks. */
|
|
61
|
+
function inlineCode(text) {
|
|
62
|
+
return text.includes("`") ? `\`\` ${text} \`\`` : `\`${text}\``;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=prompt-identifiers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-identifiers.js","sourceRoot":"","sources":["../../src/sql/prompt-identifiers.ts"],"names":[],"mappings":"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"}
|
package/dist/sql/prompt.d.ts
CHANGED
|
@@ -3,12 +3,18 @@ import { type FormatNlToSqlOptions } from "../schema/normalize.js";
|
|
|
3
3
|
import type { AnyNormalizedSchema } from "../schema/types.js";
|
|
4
4
|
import type { NormalizedTenantPolicy, TenantScope } from "../schema/v2/tenant-policy.js";
|
|
5
5
|
import type { DialectSpec } from "./dialect-spec.js";
|
|
6
|
+
/**
|
|
7
|
+
* The namespace whose tables the prompt lists unqualified: the dialect's
|
|
8
|
+
* `unqualifiedNamespace` when it is the schema's only namespace. Next to other
|
|
9
|
+
* namespaces it is a real name (a MySQL database list) and stays qualified.
|
|
10
|
+
*/
|
|
11
|
+
export declare function unqualifiedNamespaceFor(schema: AnyNormalizedSchema, namespace: string | undefined): string | undefined;
|
|
6
12
|
/**
|
|
7
13
|
* Build the dialect-parameterized NL→SQL user prompt. The same scaffolding is used
|
|
8
14
|
* for every dialect; the dialect's `displayName` and `promptBrief` are interpolated
|
|
9
15
|
* to steer the model toward dialect-correct syntax.
|
|
10
16
|
*/
|
|
11
|
-
export declare function buildNlToSqlUserPrompt(dialect: DialectSpec, question: string, schema: AnyNormalizedSchema, ambiguityNotes?: readonly string[], logger?: AskDbLogger, nlToSqlSchemaOptions?: FormatNlToSqlOptions,
|
|
17
|
+
export declare function buildNlToSqlUserPrompt(dialect: DialectSpec, question: string, schema: AnyNormalizedSchema, ambiguityNotes?: readonly string[], logger?: AskDbLogger, nlToSqlSchemaOptions?: Omit<FormatNlToSqlOptions, "unqualifiedNamespace" | "quoteIdentifier">,
|
|
12
18
|
/**
|
|
13
19
|
* Optional pre-synthesized DDL block. When supplied, this replaces the
|
|
14
20
|
* formatter output verbatim — used by `ask({ retriever })` to inject a
|
package/dist/sql/prompt.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/sql/prompt.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAK9D,OAAO,KAAK,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/sql/prompt.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAK9D,OAAO,KAAK,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAQrD;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,mBAAmB,EAC3B,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,MAAM,GAAG,SAAS,CAGpB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,mBAAmB,EAC3B,cAAc,GAAE,SAAS,MAAM,EAAO,EACtC,MAAM,CAAC,EAAE,WAAW,EACpB,oBAAoB,CAAC,EAAE,IAAI,CAAC,oBAAoB,EAAE,sBAAsB,GAAG,iBAAiB,CAAC;AAC7F;;;;;;GAMG;AACH,WAAW,CAAC,EAAE,MAAM,EACpB,YAAY,CAAC,EAAE,sBAAsB,EACrC,WAAW,CAAC,EAAE,WAAW;AACzB;;;;GAIG;AACH,YAAY,CAAC,EAAE,OAAO,GACrB,MAAM,CA2GR;AAED,oEAAoE;AACpE,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAErE"}
|
package/dist/sql/prompt.js
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
import { AskDbLogEvent } from "../logging/log-events.js";
|
|
2
2
|
import { formatSchemaForNlToSql, } from "../schema/normalize.js";
|
|
3
3
|
import { formatSchemaV2ForNlToSql, } from "../schema/v2/index.js";
|
|
4
|
+
import { promptIdentifierQuoter, qualifiedNameQuotingRule } from "./prompt-identifiers.js";
|
|
4
5
|
import { buildTenantPromptBlock } from "./tenant-prompt.js";
|
|
5
6
|
function isV2(schema) {
|
|
6
7
|
return "schemaId" in schema;
|
|
7
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* The namespace whose tables the prompt lists unqualified: the dialect's
|
|
11
|
+
* `unqualifiedNamespace` when it is the schema's only namespace. Next to other
|
|
12
|
+
* namespaces it is a real name (a MySQL database list) and stays qualified.
|
|
13
|
+
*/
|
|
14
|
+
export function unqualifiedNamespaceFor(schema, namespace) {
|
|
15
|
+
if (namespace === undefined || !isV2(schema))
|
|
16
|
+
return undefined;
|
|
17
|
+
return schema.tables.every((t) => t.schema === namespace) ? namespace : undefined;
|
|
18
|
+
}
|
|
8
19
|
/**
|
|
9
20
|
* Build the dialect-parameterized NL→SQL user prompt. The same scaffolding is used
|
|
10
21
|
* for every dialect; the dialect's `displayName` and `promptBrief` are interpolated
|
|
@@ -25,8 +36,13 @@ prebuiltDdl, tenantPolicy, tenantScope,
|
|
|
25
36
|
* pre-parameterize path (byte-identical).
|
|
26
37
|
*/
|
|
27
38
|
parameterize) {
|
|
39
|
+
const unqualifiedNamespace = unqualifiedNamespaceFor(schema, dialect.unqualifiedNamespace);
|
|
28
40
|
const formatted = isV2(schema)
|
|
29
|
-
? formatSchemaV2ForNlToSql(schema,
|
|
41
|
+
? formatSchemaV2ForNlToSql(schema, {
|
|
42
|
+
...nlToSqlSchemaOptions,
|
|
43
|
+
unqualifiedNamespace,
|
|
44
|
+
quoteIdentifier: promptIdentifierQuoter(dialect),
|
|
45
|
+
})
|
|
30
46
|
: formatSchemaForNlToSql(schema, nlToSqlSchemaOptions);
|
|
31
47
|
const ddl = prebuiltDdl ?? formatted.ddl;
|
|
32
48
|
const stats = formatted.stats;
|
|
@@ -50,7 +66,11 @@ parameterize) {
|
|
|
50
66
|
"Rules:",
|
|
51
67
|
`- Output exactly one ${dialect.displayName} SELECT query (CTE WITH is ok). End with optional semicolon.`,
|
|
52
68
|
'- Put the SQL only inside one markdown fenced block labelled ```sql (preferred). No extra commentary.',
|
|
53
|
-
|
|
69
|
+
unqualifiedNamespace === undefined
|
|
70
|
+
? "- Use identifiers from the schema below; qualify table names where it helps readability."
|
|
71
|
+
: `- Use identifiers from the schema below and write each table name exactly as it is listed. \`${unqualifiedNamespace}\` is not a schema in ${dialect.displayName}: never write \`${unqualifiedNamespace}.<table>\`, even where ids or notes below mention \`${unqualifiedNamespace}\`.`,
|
|
72
|
+
// Only a prompt that lists qualified names gets the rule; a v1 schema lists no schemas.
|
|
73
|
+
...(isV2(schema) && unqualifiedNamespace === undefined ? [qualifiedNameQuotingRule(dialect)] : []),
|
|
54
74
|
"- Do NOT use DDL or write statements (INSERT, UPDATE, DELETE, etc.). SELECT-only.",
|
|
55
75
|
`- Dialect notes: ${dialect.promptBrief}`,
|
|
56
76
|
"",
|
package/dist/sql/prompt.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/sql/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,OAAO,EACL,sBAAsB,GAEvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,wBAAwB,GAEzB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,SAAS,IAAI,CAAC,MAA2B;IACvC,OAAO,UAAU,IAAI,MAAM,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CACpC,OAAoB,EACpB,QAAgB,EAChB,MAA2B,EAC3B,iBAAoC,EAAE,EACtC,MAAoB,EACpB,
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/sql/prompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Words each engine family reserves, from its own docs. The built-in specs in
|
|
3
|
+
* `dialect-spec.ts` set them as `reservedWords`, and the NL→SQL prompt lists a schema, table
|
|
4
|
+
* or column with one of these names quoted (see `prompt-identifiers.ts`).
|
|
5
|
+
*
|
|
6
|
+
* Quoting a name that isn't reserved is harmless, so a list may be a superset; a word it
|
|
7
|
+
* misses reaches the model unquoted. When an engine reserves a new word, add it here.
|
|
8
|
+
* All lowercase.
|
|
9
|
+
*/
|
|
10
|
+
export declare const POSTGRES_RESERVED_WORDS: readonly string[];
|
|
11
|
+
export declare const COCKROACHDB_EXTRA_RESERVED_WORDS: readonly string[];
|
|
12
|
+
export declare const MYSQL_RESERVED_WORDS: readonly string[];
|
|
13
|
+
export declare const SQLSERVER_RESERVED_WORDS: readonly string[];
|
|
14
|
+
export declare const SQLITE_KEYWORDS: readonly string[];
|
|
15
|
+
//# sourceMappingURL=reserved-words.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reserved-words.d.ts","sourceRoot":"","sources":["../../src/sql/reserved-words.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,eAAO,MAAM,uBAAuB,EAAE,SAAS,MAAM,EAYpD,CAAC;AAKF,eAAO,MAAM,gCAAgC,EAAE,SAAS,MAAM,EAAuB,CAAC;AAItF,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EA8BjD,CAAC;AAGF,eAAO,MAAM,wBAAwB,EAAE,SAAS,MAAM,EAoBrD,CAAC;AAGF,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAgB5C,CAAC"}
|