@sigma4life/mysql-mcp-server 1.0.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/.env.example +35 -0
- package/.github/workflows/ci.yml +18 -0
- package/AUTHENTICATION.md +24 -0
- package/CLAUDE.md +37 -0
- package/CONTRIBUTING.md +19 -0
- package/LICENSE +21 -0
- package/QUERY_ACCESS_SETUP.md +65 -0
- package/README.md +144 -0
- package/SECURITY.md +10 -0
- package/TESTING.md +54 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +197 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/cache.d.ts +11 -0
- package/dist/core/cache.d.ts.map +1 -0
- package/dist/core/cache.js +30 -0
- package/dist/core/cache.js.map +1 -0
- package/dist/core/config.d.ts +24 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +63 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/database-url.d.ts +11 -0
- package/dist/core/database-url.d.ts.map +1 -0
- package/dist/core/database-url.js +37 -0
- package/dist/core/database-url.js.map +1 -0
- package/dist/core/database-url.test.d.ts +2 -0
- package/dist/core/database-url.test.d.ts.map +1 -0
- package/dist/core/database-url.test.js +22 -0
- package/dist/core/database-url.test.js.map +1 -0
- package/dist/core/logger.d.ts +3 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +17 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/mcp.d.ts +14 -0
- package/dist/core/mcp.d.ts.map +1 -0
- package/dist/core/mcp.js +23 -0
- package/dist/core/mcp.js.map +1 -0
- package/dist/core/query-safety.d.ts +10 -0
- package/dist/core/query-safety.d.ts.map +1 -0
- package/dist/core/query-safety.js +50 -0
- package/dist/core/query-safety.js.map +1 -0
- package/dist/core/query-safety.test.d.ts +2 -0
- package/dist/core/query-safety.test.d.ts.map +1 -0
- package/dist/core/query-safety.test.js +30 -0
- package/dist/core/query-safety.test.js.map +1 -0
- package/dist/core/schema-types.d.ts +53 -0
- package/dist/core/schema-types.d.ts.map +1 -0
- package/dist/core/schema-types.js +2 -0
- package/dist/core/schema-types.js.map +1 -0
- package/dist/core/security/access-control.d.ts +32 -0
- package/dist/core/security/access-control.d.ts.map +1 -0
- package/dist/core/security/access-control.js +244 -0
- package/dist/core/security/access-control.js.map +1 -0
- package/dist/core/security/config-loader.d.ts +20 -0
- package/dist/core/security/config-loader.d.ts.map +1 -0
- package/dist/core/security/config-loader.js +227 -0
- package/dist/core/security/config-loader.js.map +1 -0
- package/dist/core/security/types.d.ts +64 -0
- package/dist/core/security/types.d.ts.map +1 -0
- package/dist/core/security/types.js +28 -0
- package/dist/core/security/types.js.map +1 -0
- package/dist/core/sql-parser.d.ts +23 -0
- package/dist/core/sql-parser.d.ts.map +1 -0
- package/dist/core/sql-parser.js +460 -0
- package/dist/core/sql-parser.js.map +1 -0
- package/dist/core/sql-parser.test.d.ts +2 -0
- package/dist/core/sql-parser.test.d.ts.map +1 -0
- package/dist/core/sql-parser.test.js +21 -0
- package/dist/core/sql-parser.test.js.map +1 -0
- package/dist/handlers/accessible-schema.d.ts +53 -0
- package/dist/handlers/accessible-schema.d.ts.map +1 -0
- package/dist/handlers/accessible-schema.js +192 -0
- package/dist/handlers/accessible-schema.js.map +1 -0
- package/dist/handlers/data.d.ts +17 -0
- package/dist/handlers/data.d.ts.map +1 -0
- package/dist/handlers/data.js +30 -0
- package/dist/handlers/data.js.map +1 -0
- package/dist/handlers/relationships.d.ts +14 -0
- package/dist/handlers/relationships.d.ts.map +1 -0
- package/dist/handlers/relationships.js +77 -0
- package/dist/handlers/relationships.js.map +1 -0
- package/dist/handlers/schema.d.ts +14 -0
- package/dist/handlers/schema.d.ts.map +1 -0
- package/dist/handlers/schema.js +104 -0
- package/dist/handlers/schema.js.map +1 -0
- package/dist/handlers/search.d.ts +14 -0
- package/dist/handlers/search.d.ts.map +1 -0
- package/dist/handlers/search.js +18 -0
- package/dist/handlers/search.js.map +1 -0
- package/dist/handlers/validation.d.ts +32 -0
- package/dist/handlers/validation.d.ts.map +1 -0
- package/dist/handlers/validation.js +116 -0
- package/dist/handlers/validation.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +294 -0
- package/dist/index.js.map +1 -0
- package/dist/mysql/connection.d.ts +15 -0
- package/dist/mysql/connection.d.ts.map +1 -0
- package/dist/mysql/connection.js +57 -0
- package/dist/mysql/connection.js.map +1 -0
- package/dist/mysql/identifiers.d.ts +3 -0
- package/dist/mysql/identifiers.d.ts.map +1 -0
- package/dist/mysql/identifiers.js +10 -0
- package/dist/mysql/identifiers.js.map +1 -0
- package/dist/mysql/identifiers.test.d.ts +2 -0
- package/dist/mysql/identifiers.test.d.ts.map +1 -0
- package/dist/mysql/identifiers.test.js +11 -0
- package/dist/mysql/identifiers.test.js.map +1 -0
- package/dist/mysql/queries.d.ts +49 -0
- package/dist/mysql/queries.d.ts.map +1 -0
- package/dist/mysql/queries.js +206 -0
- package/dist/mysql/queries.js.map +1 -0
- package/docs/clients/claude-code.md +28 -0
- package/docs/clients/claude-desktop.md +35 -0
- package/docs/clients/codex.md +28 -0
- package/docs/clients/cursor.md +26 -0
- package/docs/clients/opencode.md +35 -0
- package/docs/clients/vscode.md +25 -0
- package/package.json +49 -0
- package/query-access.example.json +21 -0
- package/src/cli.ts +221 -0
- package/src/core/cache.ts +41 -0
- package/src/core/config.ts +97 -0
- package/src/core/database-url.test.ts +28 -0
- package/src/core/database-url.ts +47 -0
- package/src/core/logger.ts +24 -0
- package/src/core/mcp.ts +23 -0
- package/src/core/query-safety.test.ts +36 -0
- package/src/core/query-safety.ts +63 -0
- package/src/core/schema-types.ts +58 -0
- package/src/core/security/access-control.ts +321 -0
- package/src/core/security/config-loader.ts +315 -0
- package/src/core/security/types.ts +114 -0
- package/src/core/sql-parser.test.ts +37 -0
- package/src/core/sql-parser.ts +572 -0
- package/src/handlers/accessible-schema.ts +314 -0
- package/src/handlers/data.ts +66 -0
- package/src/handlers/relationships.ts +114 -0
- package/src/handlers/schema.ts +154 -0
- package/src/handlers/search.ts +34 -0
- package/src/handlers/validation.ts +165 -0
- package/src/index.ts +337 -0
- package/src/mysql/connection.ts +68 -0
- package/src/mysql/identifiers.test.ts +12 -0
- package/src/mysql/identifiers.ts +10 -0
- package/src/mysql/queries.ts +285 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQL Parser Utility for Access Control
|
|
3
|
+
*
|
|
4
|
+
* Uses node-sql-parser to parse SQL and extract:
|
|
5
|
+
* - Tables (including JOINs, subqueries, CTEs)
|
|
6
|
+
* - Columns being selected
|
|
7
|
+
* - SELECT * detection
|
|
8
|
+
* - Alias resolution
|
|
9
|
+
*/
|
|
10
|
+
import pkg from "node-sql-parser";
|
|
11
|
+
const { Parser } = pkg;
|
|
12
|
+
import { logger } from "./logger.js";
|
|
13
|
+
const parser = new Parser();
|
|
14
|
+
const PARSER_OPTIONS = { database: "MySQL" };
|
|
15
|
+
/**
|
|
16
|
+
* Parse a SQL query and extract tables, columns, and SELECT * usage
|
|
17
|
+
*/
|
|
18
|
+
export function parseQuery(sql, database) {
|
|
19
|
+
const result = {
|
|
20
|
+
tables: [],
|
|
21
|
+
columns: [],
|
|
22
|
+
hasSelectStar: false,
|
|
23
|
+
selectStarTables: [],
|
|
24
|
+
aliases: new Map(),
|
|
25
|
+
};
|
|
26
|
+
try {
|
|
27
|
+
const ast = parser.astify(sql, PARSER_OPTIONS);
|
|
28
|
+
logger.debug(`Parsed SQL AST: ${JSON.stringify(ast, null, 2)}`);
|
|
29
|
+
// Handle both single statement and array of statements
|
|
30
|
+
const statements = Array.isArray(ast) ? ast : [ast];
|
|
31
|
+
for (const stmt of statements) {
|
|
32
|
+
if (stmt && stmt.type === "select") {
|
|
33
|
+
processSelectStatement(stmt, database, database, result);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
logger.warn(`SQL parsing failed, falling back to regex: ${error.message}`);
|
|
39
|
+
// Fallback to regex-based parsing for queries the parser can't handle
|
|
40
|
+
return parseQueryWithRegex(sql, database);
|
|
41
|
+
}
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Process a SELECT statement and extract table/column info
|
|
46
|
+
* @param cteNames - Set of CTE names to skip when processing FROM clause (passed down from parent)
|
|
47
|
+
*/
|
|
48
|
+
function processSelectStatement(stmt, database, defaultSchema, result, cteNames = new Set()) {
|
|
49
|
+
// Process CTEs (WITH clause) - collect CTE names first, then process bodies
|
|
50
|
+
if (stmt.with) {
|
|
51
|
+
// First pass: collect all CTE names
|
|
52
|
+
for (const cte of stmt.with) {
|
|
53
|
+
if (cte.name?.value) {
|
|
54
|
+
cteNames.add(cte.name.value.toLowerCase());
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Second pass: process CTE bodies (real tables inside CTEs still need validation)
|
|
58
|
+
for (const cte of stmt.with) {
|
|
59
|
+
// Fix: CTE body is in cte.stmt.ast, not cte.stmt directly
|
|
60
|
+
if (cte.stmt?.ast) {
|
|
61
|
+
processSelectStatement(cte.stmt.ast, database, defaultSchema, result, cteNames);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Process FROM clause (tables) - pass cteNames to skip CTE references
|
|
66
|
+
if (stmt.from) {
|
|
67
|
+
processFromClause(stmt.from, database, defaultSchema, result, cteNames);
|
|
68
|
+
}
|
|
69
|
+
// Process SELECT columns
|
|
70
|
+
if (stmt.columns) {
|
|
71
|
+
processColumns(stmt.columns, database, defaultSchema, result);
|
|
72
|
+
}
|
|
73
|
+
// Process subqueries in WHERE, HAVING, etc.
|
|
74
|
+
if (stmt.where) {
|
|
75
|
+
processExpression(stmt.where, database, defaultSchema, result, cteNames);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Process FROM clause to extract tables
|
|
80
|
+
* @param cteNames - Set of CTE names to skip (they're query-scoped aliases, not real tables)
|
|
81
|
+
*/
|
|
82
|
+
function processFromClause(from, database, defaultSchema, result, cteNames = new Set()) {
|
|
83
|
+
for (const item of from) {
|
|
84
|
+
if (!item)
|
|
85
|
+
continue;
|
|
86
|
+
// Handle regular table reference
|
|
87
|
+
if (item.table) {
|
|
88
|
+
// Check if this is a CTE reference - skip adding to tables but track alias
|
|
89
|
+
if (cteNames.has(item.table.toLowerCase())) {
|
|
90
|
+
// CTE reference - register alias pointing to __cte__ marker
|
|
91
|
+
const cteRef = {
|
|
92
|
+
database,
|
|
93
|
+
schema: "__cte__",
|
|
94
|
+
table: item.table,
|
|
95
|
+
alias: item.as?.toLowerCase(),
|
|
96
|
+
};
|
|
97
|
+
result.aliases.set((item.as || item.table).toLowerCase(), cteRef);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
// Real table reference
|
|
101
|
+
const tableRef = extractTableRef(item, database, defaultSchema);
|
|
102
|
+
result.tables.push(tableRef);
|
|
103
|
+
// Track alias
|
|
104
|
+
if (item.as) {
|
|
105
|
+
result.aliases.set(item.as.toLowerCase(), tableRef);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// Handle subquery in FROM
|
|
110
|
+
if (item.expr && item.expr.ast) {
|
|
111
|
+
processSelectStatement(item.expr.ast, database, defaultSchema, result, cteNames);
|
|
112
|
+
// Track subquery alias
|
|
113
|
+
if (item.as) {
|
|
114
|
+
// Subquery alias doesn't map to a real table
|
|
115
|
+
result.aliases.set(item.as.toLowerCase(), {
|
|
116
|
+
database,
|
|
117
|
+
schema: "__subquery__",
|
|
118
|
+
table: item.as,
|
|
119
|
+
alias: item.as,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Handle JOINs
|
|
124
|
+
if (item.join) {
|
|
125
|
+
// The join target is in item itself after the join keyword
|
|
126
|
+
// Recursively process the joined table
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Extract table reference from AST node
|
|
132
|
+
*/
|
|
133
|
+
function extractTableRef(item, database, defaultSchema) {
|
|
134
|
+
// node-sql-parser may provide schema as 'db' property
|
|
135
|
+
const schema = item.db || defaultSchema;
|
|
136
|
+
const table = item.table;
|
|
137
|
+
const alias = item.as || undefined;
|
|
138
|
+
return {
|
|
139
|
+
database,
|
|
140
|
+
schema: schema.toLowerCase(),
|
|
141
|
+
table: table,
|
|
142
|
+
alias: alias?.toLowerCase(),
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Process SELECT columns
|
|
147
|
+
*/
|
|
148
|
+
function processColumns(columns, database, defaultSchema, result) {
|
|
149
|
+
// Handle SELECT *
|
|
150
|
+
if (columns === "*") {
|
|
151
|
+
result.hasSelectStar = true;
|
|
152
|
+
result.selectStarTables.push("*");
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
if (!Array.isArray(columns)) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
for (const col of columns) {
|
|
159
|
+
if (!col)
|
|
160
|
+
continue;
|
|
161
|
+
// Handle column expressions
|
|
162
|
+
if (col.expr) {
|
|
163
|
+
processColumnExpression(col.expr, database, defaultSchema, result);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Process a column expression to extract column references
|
|
169
|
+
*/
|
|
170
|
+
function processColumnExpression(expr, database, defaultSchema, result) {
|
|
171
|
+
if (!expr)
|
|
172
|
+
return;
|
|
173
|
+
// Handle star expression (SELECT * or table.*)
|
|
174
|
+
// node-sql-parser returns this as type='star' OR type='column_ref' with column='*'
|
|
175
|
+
if (expr.type === "star") {
|
|
176
|
+
result.hasSelectStar = true;
|
|
177
|
+
if (expr.table) {
|
|
178
|
+
result.selectStarTables.push(expr.table);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
result.selectStarTables.push("*");
|
|
182
|
+
}
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
// Handle column reference - check for SELECT * variant (column_ref with column='*')
|
|
186
|
+
if (expr.type === "column_ref") {
|
|
187
|
+
// Check if this is actually SELECT * or table.*
|
|
188
|
+
if (expr.column === "*") {
|
|
189
|
+
result.hasSelectStar = true;
|
|
190
|
+
if (expr.table) {
|
|
191
|
+
result.selectStarTables.push(expr.table);
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
result.selectStarTables.push("*");
|
|
195
|
+
}
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const colRef = extractColumnRef(expr, database, defaultSchema, result);
|
|
199
|
+
if (colRef) {
|
|
200
|
+
result.columns.push(colRef);
|
|
201
|
+
}
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
// Handle function calls - extract column references from arguments
|
|
205
|
+
if (expr.type === "function" || expr.type === "aggr_func") {
|
|
206
|
+
if (expr.args) {
|
|
207
|
+
if (expr.args.type === "expr_list") {
|
|
208
|
+
for (const arg of expr.args.value || []) {
|
|
209
|
+
processColumnExpression(arg, database, defaultSchema, result);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
else if (expr.args.expr) {
|
|
213
|
+
processColumnExpression(expr.args.expr, database, defaultSchema, result);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
// Handle binary expressions (e.g., col1 + col2)
|
|
219
|
+
if (expr.type === "binary_expr") {
|
|
220
|
+
processColumnExpression(expr.left, database, defaultSchema, result);
|
|
221
|
+
processColumnExpression(expr.right, database, defaultSchema, result);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
// Handle CASE expressions
|
|
225
|
+
if (expr.type === "case") {
|
|
226
|
+
if (expr.args) {
|
|
227
|
+
for (const arg of expr.args) {
|
|
228
|
+
if (arg.cond)
|
|
229
|
+
processColumnExpression(arg.cond, database, defaultSchema, result);
|
|
230
|
+
if (arg.result)
|
|
231
|
+
processColumnExpression(arg.result, database, defaultSchema, result);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
// Handle subqueries in SELECT
|
|
237
|
+
if (expr.type === "select" || expr.ast) {
|
|
238
|
+
const subStmt = expr.ast || expr;
|
|
239
|
+
processSelectStatement(subStmt, database, defaultSchema, result);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Extract column reference from AST node
|
|
244
|
+
*/
|
|
245
|
+
function extractColumnRef(expr, database, defaultSchema, result) {
|
|
246
|
+
const column = expr.column;
|
|
247
|
+
const tableOrAlias = expr.table;
|
|
248
|
+
if (!column)
|
|
249
|
+
return null;
|
|
250
|
+
// If table/alias is specified, resolve it
|
|
251
|
+
if (tableOrAlias) {
|
|
252
|
+
const aliasLower = tableOrAlias.toLowerCase();
|
|
253
|
+
const resolved = result.aliases.get(aliasLower);
|
|
254
|
+
if (resolved) {
|
|
255
|
+
// Skip subquery columns - we can't validate them against config
|
|
256
|
+
if (resolved.schema === "__subquery__") {
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
// Skip CTE columns - they're query-scoped aliases, real tables in CTE body already validated
|
|
260
|
+
if (resolved.schema === "__cte__") {
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
database: resolved.database,
|
|
265
|
+
schema: resolved.schema,
|
|
266
|
+
table: resolved.table,
|
|
267
|
+
column: column,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
// Table name used directly (not alias)
|
|
271
|
+
const tableRef = result.tables.find((t) => t.table.toLowerCase() === aliasLower ||
|
|
272
|
+
t.alias?.toLowerCase() === aliasLower);
|
|
273
|
+
if (tableRef) {
|
|
274
|
+
return {
|
|
275
|
+
database: tableRef.database,
|
|
276
|
+
schema: tableRef.schema,
|
|
277
|
+
table: tableRef.table,
|
|
278
|
+
column: column,
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
// Unknown table reference - use as-is
|
|
282
|
+
return {
|
|
283
|
+
database,
|
|
284
|
+
schema: defaultSchema,
|
|
285
|
+
table: tableOrAlias,
|
|
286
|
+
column: column,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
// No table specified - try to infer from single table query
|
|
290
|
+
if (result.tables.length === 1) {
|
|
291
|
+
const tableRef = result.tables[0];
|
|
292
|
+
return {
|
|
293
|
+
database: tableRef.database,
|
|
294
|
+
schema: tableRef.schema,
|
|
295
|
+
table: tableRef.table,
|
|
296
|
+
column: column,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
// Ambiguous - column without table in multi-table query
|
|
300
|
+
// Return with unknown table marker
|
|
301
|
+
return {
|
|
302
|
+
database,
|
|
303
|
+
schema: defaultSchema,
|
|
304
|
+
table: "__unknown__",
|
|
305
|
+
column: column,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Process expressions (WHERE, HAVING, etc.) for subqueries
|
|
310
|
+
* @param cteNames - Set of CTE names to pass to nested SELECT statements
|
|
311
|
+
*/
|
|
312
|
+
function processExpression(expr, database, defaultSchema, result, cteNames = new Set()) {
|
|
313
|
+
if (!expr)
|
|
314
|
+
return;
|
|
315
|
+
// Handle subqueries
|
|
316
|
+
if (expr.type === "select" || expr.ast) {
|
|
317
|
+
const subStmt = expr.ast || expr;
|
|
318
|
+
processSelectStatement(subStmt, database, defaultSchema, result, cteNames);
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
// Handle binary expressions
|
|
322
|
+
if (expr.left)
|
|
323
|
+
processExpression(expr.left, database, defaultSchema, result, cteNames);
|
|
324
|
+
if (expr.right)
|
|
325
|
+
processExpression(expr.right, database, defaultSchema, result, cteNames);
|
|
326
|
+
// Handle IN clause with subquery
|
|
327
|
+
if (expr.value && Array.isArray(expr.value)) {
|
|
328
|
+
for (const v of expr.value) {
|
|
329
|
+
processExpression(v, database, defaultSchema, result, cteNames);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Fallback regex-based parsing for queries the AST parser can't handle
|
|
335
|
+
*/
|
|
336
|
+
function parseQueryWithRegex(sql, database) {
|
|
337
|
+
const result = {
|
|
338
|
+
tables: [],
|
|
339
|
+
columns: [],
|
|
340
|
+
hasSelectStar: false,
|
|
341
|
+
selectStarTables: [],
|
|
342
|
+
aliases: new Map(),
|
|
343
|
+
};
|
|
344
|
+
const normalizedSql = sql.replace(/\s+/g, " ").trim();
|
|
345
|
+
// Extract CTE names from WITH clause before processing FROM/JOIN
|
|
346
|
+
// Pattern matches: WITH name AS (...), name2 AS (...)
|
|
347
|
+
// Also handles RECURSIVE: WITH RECURSIVE name AS (...)
|
|
348
|
+
const cteNames = new Set();
|
|
349
|
+
const ctePattern = /(?:WITH\s+(?:RECURSIVE\s+)?|,\s*)(`?[\w]+`?)\s+AS\s*\(/gi;
|
|
350
|
+
let match;
|
|
351
|
+
while ((match = ctePattern.exec(normalizedSql)) !== null) {
|
|
352
|
+
const cteName = match[1].replace(/`/g, "").toLowerCase();
|
|
353
|
+
cteNames.add(cteName);
|
|
354
|
+
logger.debug(`Regex parser found CTE name: ${cteName}`);
|
|
355
|
+
}
|
|
356
|
+
// Detect SELECT *
|
|
357
|
+
const selectStarPattern = /SELECT\s+(DISTINCT\s+)?(\*|[\w.]+\.\*)/gi;
|
|
358
|
+
while ((match = selectStarPattern.exec(normalizedSql)) !== null) {
|
|
359
|
+
result.hasSelectStar = true;
|
|
360
|
+
const starExpr = match[2];
|
|
361
|
+
if (starExpr === "*") {
|
|
362
|
+
result.selectStarTables.push("*");
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
// table.* format
|
|
366
|
+
const tablePart = starExpr.replace(".*", "");
|
|
367
|
+
result.selectStarTables.push(tablePart);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
// Helper function to add a table reference (skips CTEs)
|
|
371
|
+
const addTableRef = (tableName, alias) => {
|
|
372
|
+
// Handle schema.table format
|
|
373
|
+
const tableParts = tableName.split(".");
|
|
374
|
+
const table = tableParts.length > 1 ? tableParts[1] : tableParts[0];
|
|
375
|
+
const schema = tableParts.length > 1 ? tableParts[0] : database;
|
|
376
|
+
// Skip if this is a CTE name
|
|
377
|
+
if (cteNames.has(table.toLowerCase())) {
|
|
378
|
+
// Register CTE alias but don't add to tables
|
|
379
|
+
const cteRef = {
|
|
380
|
+
database,
|
|
381
|
+
schema: "__cte__",
|
|
382
|
+
table: table,
|
|
383
|
+
alias: alias?.toLowerCase(),
|
|
384
|
+
};
|
|
385
|
+
result.aliases.set((alias || table).toLowerCase(), cteRef);
|
|
386
|
+
logger.debug(`Regex parser skipping CTE reference: ${table}`);
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
const tableRef = {
|
|
390
|
+
database,
|
|
391
|
+
schema: schema.toLowerCase(),
|
|
392
|
+
table: table,
|
|
393
|
+
alias: alias?.toLowerCase(),
|
|
394
|
+
};
|
|
395
|
+
result.tables.push(tableRef);
|
|
396
|
+
if (alias) {
|
|
397
|
+
result.aliases.set(alias.toLowerCase(), tableRef);
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
// Extract tables from FROM clause (basic pattern)
|
|
401
|
+
const fromPattern = /FROM\s+(`?[\w.]+`?(?:\s+(?:AS\s+)?[\w]+)?)/gi;
|
|
402
|
+
while ((match = fromPattern.exec(normalizedSql)) !== null) {
|
|
403
|
+
const tableExpr = match[1].trim();
|
|
404
|
+
const parts = tableExpr.split(/\s+/);
|
|
405
|
+
const tableName = parts[0].replace(/`/g, "");
|
|
406
|
+
const alias = parts.length > 1 ? parts[parts.length - 1] : undefined;
|
|
407
|
+
addTableRef(tableName, alias);
|
|
408
|
+
}
|
|
409
|
+
// Extract tables from JOIN clauses
|
|
410
|
+
const joinPattern = /JOIN\s+(`?[\w.]+`?(?:\s+(?:AS\s+)?[\w]+)?)/gi;
|
|
411
|
+
while ((match = joinPattern.exec(normalizedSql)) !== null) {
|
|
412
|
+
const tableExpr = match[1].trim();
|
|
413
|
+
const parts = tableExpr.split(/\s+/);
|
|
414
|
+
const tableName = parts[0].replace(/`/g, "");
|
|
415
|
+
const alias = parts.length > 1 ? parts[parts.length - 1] : undefined;
|
|
416
|
+
addTableRef(tableName, alias);
|
|
417
|
+
}
|
|
418
|
+
logger.debug(`Regex parsing result: ${JSON.stringify(result, replacer, 2)}`);
|
|
419
|
+
return result;
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* JSON replacer to handle Map serialization
|
|
423
|
+
*/
|
|
424
|
+
function replacer(_key, value) {
|
|
425
|
+
if (value instanceof Map) {
|
|
426
|
+
return Object.fromEntries(value);
|
|
427
|
+
}
|
|
428
|
+
return value;
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Check if a query contains SELECT * or table.*
|
|
432
|
+
*/
|
|
433
|
+
export function hasSelectStar(sql) {
|
|
434
|
+
const pattern = /SELECT\s+(DISTINCT\s+)?(\*|[\w.]+\.\*)/i;
|
|
435
|
+
return pattern.test(sql);
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Extract table names from a simple SQL query (utility function)
|
|
439
|
+
*/
|
|
440
|
+
export function extractTableNames(sql) {
|
|
441
|
+
const tables = [];
|
|
442
|
+
const normalizedSql = sql.replace(/\s+/g, " ").trim();
|
|
443
|
+
// FROM clause
|
|
444
|
+
const fromMatch = normalizedSql.match(/FROM\s+(`?[\w.]+`?)/i);
|
|
445
|
+
if (fromMatch) {
|
|
446
|
+
const tableName = fromMatch[1].replace(/`/g, "");
|
|
447
|
+
const parts = tableName.split(".");
|
|
448
|
+
tables.push(parts[parts.length - 1]);
|
|
449
|
+
}
|
|
450
|
+
// JOIN clauses
|
|
451
|
+
const joinPattern = /JOIN\s+(`?[\w.]+`?)/gi;
|
|
452
|
+
let match;
|
|
453
|
+
while ((match = joinPattern.exec(normalizedSql)) !== null) {
|
|
454
|
+
const tableName = match[1].replace(/`/g, "");
|
|
455
|
+
const parts = tableName.split(".");
|
|
456
|
+
tables.push(parts[parts.length - 1]);
|
|
457
|
+
}
|
|
458
|
+
return tables;
|
|
459
|
+
}
|
|
460
|
+
//# sourceMappingURL=sql-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-parser.js","sourceRoot":"","sources":["../../src/core/sql-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-parser.test.d.ts","sourceRoot":"","sources":["../../src/core/sql-parser.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import test from 'node:test';
|
|
3
|
+
import { parseQuery } from './sql-parser.js';
|
|
4
|
+
test('parseQuery extracts MySQL table aliases and columns', () => {
|
|
5
|
+
const parsed = parseQuery('SELECT c.id, c.email, o.total FROM customers c JOIN orders o ON o.customer_id = c.id', 'app_db');
|
|
6
|
+
assert.equal(parsed.hasSelectStar, false);
|
|
7
|
+
assert.deepEqual(parsed.tables.map((table) => table.table), ['customers', 'orders']);
|
|
8
|
+
assert.deepEqual(parsed.columns.map((column) => `${column.table}.${column.column}`), ['customers.id', 'customers.email', 'orders.total']);
|
|
9
|
+
});
|
|
10
|
+
test('parseQuery detects SELECT star', () => {
|
|
11
|
+
const parsed = parseQuery('SELECT * FROM customers', 'app_db');
|
|
12
|
+
assert.equal(parsed.hasSelectStar, true);
|
|
13
|
+
assert.deepEqual(parsed.selectStarTables, ['*']);
|
|
14
|
+
});
|
|
15
|
+
test('parseQuery handles CTE source tables but skips CTE references', () => {
|
|
16
|
+
const parsed = parseQuery('WITH recent_orders AS (SELECT id, customer_id FROM orders) SELECT c.email FROM customers c JOIN recent_orders r ON r.customer_id = c.id', 'app_db');
|
|
17
|
+
assert(parsed.tables.some((table) => table.table === 'orders'));
|
|
18
|
+
assert(parsed.tables.some((table) => table.table === 'customers'));
|
|
19
|
+
assert(!parsed.tables.some((table) => table.table === 'recent_orders'));
|
|
20
|
+
});
|
|
21
|
+
//# sourceMappingURL=sql-parser.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-parser.test.js","sourceRoot":"","sources":["../../src/core/sql-parser.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,IAAI,CAAC,qDAAqD,EAAE,GAAG,EAAE;IAC/D,MAAM,MAAM,GAAG,UAAU,CACvB,sFAAsF,EACtF,QAAQ,CACT,CAAC;IAEF,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IAC1C,MAAM,CAAC,SAAS,CACd,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EACzC,CAAC,WAAW,EAAE,QAAQ,CAAC,CACxB,CAAC;IACF,MAAM,CAAC,SAAS,CACd,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,EAClE,CAAC,cAAc,EAAE,iBAAiB,EAAE,cAAc,CAAC,CACpD,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC1C,MAAM,MAAM,GAAG,UAAU,CAAC,yBAAyB,EAAE,QAAQ,CAAC,CAAC;IAC/D,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IACzC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;AACnD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,+DAA+D,EAAE,GAAG,EAAE;IACzE,MAAM,MAAM,GAAG,UAAU,CACvB,yIAAyI,EACzI,QAAQ,CACT,CAAC;IAEF,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC;IAChE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,WAAW,CAAC,CAAC,CAAC;IACnE,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,eAAe,CAAC,CAAC,CAAC;AAC1E,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export interface AccessibleColumn {
|
|
2
|
+
name: string;
|
|
3
|
+
dataType: string;
|
|
4
|
+
nullable: boolean;
|
|
5
|
+
isIdentity: boolean;
|
|
6
|
+
isPrimaryKey: boolean;
|
|
7
|
+
isForeignKey: boolean;
|
|
8
|
+
description?: string | null;
|
|
9
|
+
}
|
|
10
|
+
export interface AccessibleTable {
|
|
11
|
+
schema: string;
|
|
12
|
+
name: string;
|
|
13
|
+
type: 'TABLE' | 'VIEW';
|
|
14
|
+
columnAccessMode?: 'inclusion' | 'exclusion';
|
|
15
|
+
accessibleColumns: AccessibleColumn[];
|
|
16
|
+
blockedColumns?: string[];
|
|
17
|
+
allowedColumnsList?: string[];
|
|
18
|
+
}
|
|
19
|
+
export interface AccessibleSchemaResult {
|
|
20
|
+
database: string;
|
|
21
|
+
requireExplicitColumns: boolean;
|
|
22
|
+
configuredSchemas: string[];
|
|
23
|
+
tables: AccessibleTable[];
|
|
24
|
+
notes?: string[];
|
|
25
|
+
}
|
|
26
|
+
export interface AccessibleColumnInfo extends AccessibleColumn {
|
|
27
|
+
isAccessible: boolean;
|
|
28
|
+
accessDeniedReason?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface AccessibleTableInfo {
|
|
31
|
+
database: string;
|
|
32
|
+
schema: string;
|
|
33
|
+
table: string;
|
|
34
|
+
type: 'TABLE' | 'VIEW';
|
|
35
|
+
isAccessible: boolean;
|
|
36
|
+
accessDeniedReason?: string;
|
|
37
|
+
columnAccessMode?: 'inclusion' | 'exclusion';
|
|
38
|
+
columns?: AccessibleColumnInfo[];
|
|
39
|
+
indexes?: unknown[];
|
|
40
|
+
foreignKeys?: unknown[];
|
|
41
|
+
accessibleColumnCount?: number;
|
|
42
|
+
totalColumnCount?: number;
|
|
43
|
+
}
|
|
44
|
+
export declare function getAccessibleSchema(args: {
|
|
45
|
+
database?: string;
|
|
46
|
+
schema?: string;
|
|
47
|
+
}): Promise<AccessibleSchemaResult>;
|
|
48
|
+
export declare function getAccessibleTableInfo(args: {
|
|
49
|
+
database?: string;
|
|
50
|
+
table: string;
|
|
51
|
+
schema?: string;
|
|
52
|
+
}): Promise<AccessibleTableInfo>;
|
|
53
|
+
//# sourceMappingURL=accessible-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accessible-schema.d.ts","sourceRoot":"","sources":["../../src/handlers/accessible-schema.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,WAAW,GAAG,WAAW,CAAC;IAC7C,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;IACtC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,sBAAsB,EAAE,OAAO,CAAC;IAChC,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,oBAAqB,SAAQ,gBAAgB;IAC5D,YAAY,EAAE,OAAO,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gBAAgB,CAAC,EAAE,WAAW,GAAG,WAAW,CAAC;IAC7C,OAAO,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACjC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;IACxB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AA8HD,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAuDlC;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA8D/B"}
|