@aroman22/codegraph-vba-darwin-arm64 1.15.0 → 1.17.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/lib/dist/bin/codegraph.js +13 -7
- package/lib/dist/bin/codegraph.js.map +1 -1
- package/lib/dist/bin/daemon-release.d.ts +7 -0
- package/lib/dist/bin/daemon-release.d.ts.map +1 -0
- package/lib/dist/bin/daemon-release.js +18 -0
- package/lib/dist/bin/daemon-release.js.map +1 -0
- package/lib/dist/db/queries.d.ts +41 -0
- package/lib/dist/db/queries.d.ts.map +1 -1
- package/lib/dist/db/queries.js +78 -1
- package/lib/dist/db/queries.js.map +1 -1
- package/lib/dist/extraction/access-erd-extractor.d.ts +57 -0
- package/lib/dist/extraction/access-erd-extractor.d.ts.map +1 -0
- package/lib/dist/extraction/access-erd-extractor.js +389 -0
- package/lib/dist/extraction/access-erd-extractor.js.map +1 -0
- package/lib/dist/extraction/extraction-version.d.ts +1 -1
- package/lib/dist/extraction/extraction-version.js +1 -1
- package/lib/dist/extraction/grammars.d.ts +20 -0
- package/lib/dist/extraction/grammars.d.ts.map +1 -1
- package/lib/dist/extraction/grammars.js +34 -0
- package/lib/dist/extraction/grammars.js.map +1 -1
- package/lib/dist/extraction/index.d.ts +1 -0
- package/lib/dist/extraction/index.d.ts.map +1 -1
- package/lib/dist/extraction/index.js +371 -351
- package/lib/dist/extraction/index.js.map +1 -1
- package/lib/dist/extraction/parse-pool.d.ts +8 -3
- package/lib/dist/extraction/parse-pool.d.ts.map +1 -1
- package/lib/dist/extraction/parse-pool.js +1 -2
- package/lib/dist/extraction/parse-pool.js.map +1 -1
- package/lib/dist/extraction/parse-worker.js +7 -6
- package/lib/dist/extraction/parse-worker.js.map +1 -1
- package/lib/dist/extraction/sql-query-extractor.d.ts +16 -14
- package/lib/dist/extraction/sql-query-extractor.d.ts.map +1 -1
- package/lib/dist/extraction/sql-query-extractor.js +43 -31
- package/lib/dist/extraction/sql-query-extractor.js.map +1 -1
- package/lib/dist/extraction/sql-table-scan.d.ts +184 -0
- package/lib/dist/extraction/sql-table-scan.d.ts.map +1 -0
- package/lib/dist/extraction/sql-table-scan.js +288 -0
- package/lib/dist/extraction/sql-table-scan.js.map +1 -0
- package/lib/dist/extraction/tree-sitter.d.ts +10 -1
- package/lib/dist/extraction/tree-sitter.d.ts.map +1 -1
- package/lib/dist/extraction/tree-sitter.js +34 -3
- package/lib/dist/extraction/tree-sitter.js.map +1 -1
- package/lib/dist/extraction/vba/call-sweep.d.ts +2 -7
- package/lib/dist/extraction/vba/call-sweep.d.ts.map +1 -1
- package/lib/dist/extraction/vba/call-sweep.js +144 -90
- package/lib/dist/extraction/vba/call-sweep.js.map +1 -1
- package/lib/dist/extraction/vba/calls.d.ts +24 -4
- package/lib/dist/extraction/vba/calls.d.ts.map +1 -1
- package/lib/dist/extraction/vba/calls.js +42 -12
- package/lib/dist/extraction/vba/calls.js.map +1 -1
- package/lib/dist/extraction/vba/constants.d.ts +7 -14
- package/lib/dist/extraction/vba/constants.d.ts.map +1 -1
- package/lib/dist/extraction/vba/constants.js +8 -36
- package/lib/dist/extraction/vba/constants.js.map +1 -1
- package/lib/dist/extraction/vba/context.d.ts +443 -7
- package/lib/dist/extraction/vba/context.d.ts.map +1 -1
- package/lib/dist/extraction/vba/context.js +325 -29
- package/lib/dist/extraction/vba/context.js.map +1 -1
- package/lib/dist/extraction/vba/controls.d.ts +18 -1
- package/lib/dist/extraction/vba/controls.d.ts.map +1 -1
- package/lib/dist/extraction/vba/controls.js +99 -27
- package/lib/dist/extraction/vba/controls.js.map +1 -1
- package/lib/dist/extraction/vba/declarations.d.ts +1 -6
- package/lib/dist/extraction/vba/declarations.d.ts.map +1 -1
- package/lib/dist/extraction/vba/declarations.js +5 -39
- package/lib/dist/extraction/vba/declarations.js.map +1 -1
- package/lib/dist/extraction/vba/dims.d.ts +11 -7
- package/lib/dist/extraction/vba/dims.d.ts.map +1 -1
- package/lib/dist/extraction/vba/dims.js +265 -29
- package/lib/dist/extraction/vba/dims.js.map +1 -1
- package/lib/dist/extraction/vba/docmd.d.ts +29 -2
- package/lib/dist/extraction/vba/docmd.d.ts.map +1 -1
- package/lib/dist/extraction/vba/docmd.js +297 -18
- package/lib/dist/extraction/vba/docmd.js.map +1 -1
- package/lib/dist/extraction/vba/enums-consts.d.ts +7 -14
- package/lib/dist/extraction/vba/enums-consts.d.ts.map +1 -1
- package/lib/dist/extraction/vba/enums-consts.js +11 -45
- package/lib/dist/extraction/vba/enums-consts.js.map +1 -1
- package/lib/dist/extraction/vba/error-channel.d.ts +57 -0
- package/lib/dist/extraction/vba/error-channel.d.ts.map +1 -0
- package/lib/dist/extraction/vba/error-channel.js +128 -0
- package/lib/dist/extraction/vba/error-channel.js.map +1 -0
- package/lib/dist/extraction/vba/errors.d.ts +64 -0
- package/lib/dist/extraction/vba/errors.d.ts.map +1 -0
- package/lib/dist/extraction/vba/errors.js +775 -0
- package/lib/dist/extraction/vba/errors.js.map +1 -0
- package/lib/dist/extraction/vba/filesystem-statements.d.ts +23 -0
- package/lib/dist/extraction/vba/filesystem-statements.d.ts.map +1 -0
- package/lib/dist/extraction/vba/filesystem-statements.js +70 -0
- package/lib/dist/extraction/vba/filesystem-statements.js.map +1 -0
- package/lib/dist/extraction/vba/implements.d.ts +1 -6
- package/lib/dist/extraction/vba/implements.d.ts.map +1 -1
- package/lib/dist/extraction/vba/implements.js +1 -22
- package/lib/dist/extraction/vba/implements.js.map +1 -1
- package/lib/dist/extraction/vba/labels.d.ts +26 -0
- package/lib/dist/extraction/vba/labels.d.ts.map +1 -0
- package/lib/dist/extraction/vba/labels.js +180 -0
- package/lib/dist/extraction/vba/labels.js.map +1 -0
- package/lib/dist/extraction/vba/module-vars.d.ts +36 -0
- package/lib/dist/extraction/vba/module-vars.d.ts.map +1 -0
- package/lib/dist/extraction/vba/module-vars.js +145 -0
- package/lib/dist/extraction/vba/module-vars.js.map +1 -0
- package/lib/dist/extraction/vba/options.d.ts +88 -0
- package/lib/dist/extraction/vba/options.d.ts.map +1 -0
- package/lib/dist/extraction/vba/options.js +39 -0
- package/lib/dist/extraction/vba/options.js.map +1 -0
- package/lib/dist/extraction/vba/parameters.d.ts +35 -0
- package/lib/dist/extraction/vba/parameters.d.ts.map +1 -0
- package/lib/dist/extraction/vba/parameters.js +110 -0
- package/lib/dist/extraction/vba/parameters.js.map +1 -0
- package/lib/dist/extraction/vba/procedures.d.ts +1 -9
- package/lib/dist/extraction/vba/procedures.d.ts.map +1 -1
- package/lib/dist/extraction/vba/procedures.js +174 -112
- package/lib/dist/extraction/vba/procedures.js.map +1 -1
- package/lib/dist/extraction/vba/rules.d.ts +10 -5
- package/lib/dist/extraction/vba/rules.d.ts.map +1 -1
- package/lib/dist/extraction/vba/rules.js +19 -0
- package/lib/dist/extraction/vba/rules.js.map +1 -1
- package/lib/dist/extraction/vba/runtime-objects.d.ts +59 -0
- package/lib/dist/extraction/vba/runtime-objects.d.ts.map +1 -0
- package/lib/dist/extraction/vba/runtime-objects.js +106 -0
- package/lib/dist/extraction/vba/runtime-objects.js.map +1 -0
- package/lib/dist/extraction/vba/signature.d.ts +57 -0
- package/lib/dist/extraction/vba/signature.d.ts.map +1 -0
- package/lib/dist/extraction/vba/signature.js +164 -0
- package/lib/dist/extraction/vba/signature.js.map +1 -0
- package/lib/dist/extraction/vba/sql-wrapper.d.ts +76 -3
- package/lib/dist/extraction/vba/sql-wrapper.d.ts.map +1 -1
- package/lib/dist/extraction/vba/sql-wrapper.js +725 -151
- package/lib/dist/extraction/vba/sql-wrapper.js.map +1 -1
- package/lib/dist/extraction/vba/tempvars.d.ts.map +1 -1
- package/lib/dist/extraction/vba/tempvars.js +4 -0
- package/lib/dist/extraction/vba/tempvars.js.map +1 -1
- package/lib/dist/extraction/vba/text-utils.d.ts +62 -2
- package/lib/dist/extraction/vba/text-utils.d.ts.map +1 -1
- package/lib/dist/extraction/vba/text-utils.js +84 -6
- package/lib/dist/extraction/vba/text-utils.js.map +1 -1
- package/lib/dist/extraction/vba-extractor.d.ts +18 -1
- package/lib/dist/extraction/vba-extractor.d.ts.map +1 -1
- package/lib/dist/extraction/vba-extractor.js +111 -16
- package/lib/dist/extraction/vba-extractor.js.map +1 -1
- package/lib/dist/extraction/vba-form-extractor.d.ts +28 -14
- package/lib/dist/extraction/vba-form-extractor.d.ts.map +1 -1
- package/lib/dist/extraction/vba-form-extractor.js +56 -21
- package/lib/dist/extraction/vba-form-extractor.js.map +1 -1
- package/lib/dist/extraction/vba-preprocess.d.ts +89 -3
- package/lib/dist/extraction/vba-preprocess.d.ts.map +1 -1
- package/lib/dist/extraction/vba-preprocess.js +221 -57
- package/lib/dist/extraction/vba-preprocess.js.map +1 -1
- package/lib/dist/extraction/vba-source.d.ts +0 -10
- package/lib/dist/extraction/vba-source.d.ts.map +1 -1
- package/lib/dist/extraction/vba-source.js +0 -13
- package/lib/dist/extraction/vba-source.js.map +1 -1
- package/lib/dist/extraction/vba-test-manifest-extractor.d.ts +0 -6
- package/lib/dist/extraction/vba-test-manifest-extractor.d.ts.map +1 -1
- package/lib/dist/extraction/vba-test-manifest-extractor.js +0 -1
- package/lib/dist/extraction/vba-test-manifest-extractor.js.map +1 -1
- package/lib/dist/graph/behavior-evidence.d.ts +162 -0
- package/lib/dist/graph/behavior-evidence.d.ts.map +1 -0
- package/lib/dist/graph/behavior-evidence.js +529 -0
- package/lib/dist/graph/behavior-evidence.js.map +1 -0
- package/lib/dist/index.d.ts +22 -0
- package/lib/dist/index.d.ts.map +1 -1
- package/lib/dist/index.js +37 -1
- package/lib/dist/index.js.map +1 -1
- package/lib/dist/mcp/daemon-manager.d.ts.map +1 -1
- package/lib/dist/mcp/daemon-manager.js +7 -3
- package/lib/dist/mcp/daemon-manager.js.map +1 -1
- package/lib/dist/mcp/daemon-paths.d.ts +6 -0
- package/lib/dist/mcp/daemon-paths.d.ts.map +1 -1
- package/lib/dist/mcp/daemon-paths.js +15 -0
- package/lib/dist/mcp/daemon-paths.js.map +1 -1
- package/lib/dist/mcp/daemon-registry.d.ts +82 -7
- package/lib/dist/mcp/daemon-registry.d.ts.map +1 -1
- package/lib/dist/mcp/daemon-registry.js +557 -45
- package/lib/dist/mcp/daemon-registry.js.map +1 -1
- package/lib/dist/mcp/daemon-watchdog.d.ts +12 -0
- package/lib/dist/mcp/daemon-watchdog.d.ts.map +1 -1
- package/lib/dist/mcp/daemon-watchdog.js +37 -7
- package/lib/dist/mcp/daemon-watchdog.js.map +1 -1
- package/lib/dist/mcp/daemon.d.ts +20 -1
- package/lib/dist/mcp/daemon.d.ts.map +1 -1
- package/lib/dist/mcp/daemon.js +123 -30
- package/lib/dist/mcp/daemon.js.map +1 -1
- package/lib/dist/mcp/index.d.ts.map +1 -1
- package/lib/dist/mcp/index.js +13 -2
- package/lib/dist/mcp/index.js.map +1 -1
- package/lib/dist/mcp/proxy.d.ts +32 -0
- package/lib/dist/mcp/proxy.d.ts.map +1 -1
- package/lib/dist/mcp/proxy.js +163 -31
- package/lib/dist/mcp/proxy.js.map +1 -1
- package/lib/dist/mcp/server-instructions.d.ts +1 -1
- package/lib/dist/mcp/server-instructions.d.ts.map +1 -1
- package/lib/dist/mcp/server-instructions.js +26 -4
- package/lib/dist/mcp/server-instructions.js.map +1 -1
- package/lib/dist/mcp/tools.d.ts +12 -0
- package/lib/dist/mcp/tools.d.ts.map +1 -1
- package/lib/dist/mcp/tools.js +92 -1
- package/lib/dist/mcp/tools.js.map +1 -1
- package/lib/dist/project-config.d.ts +43 -2
- package/lib/dist/project-config.d.ts.map +1 -1
- package/lib/dist/project-config.js +86 -2
- package/lib/dist/project-config.js.map +1 -1
- package/lib/dist/resolution/index.d.ts +47 -2
- package/lib/dist/resolution/index.d.ts.map +1 -1
- package/lib/dist/resolution/index.js +160 -5
- package/lib/dist/resolution/index.js.map +1 -1
- package/lib/dist/resolution/name-matcher.d.ts +25 -0
- package/lib/dist/resolution/name-matcher.d.ts.map +1 -1
- package/lib/dist/resolution/name-matcher.js +59 -0
- package/lib/dist/resolution/name-matcher.js.map +1 -1
- package/lib/dist/resolution/vba-runtime-objects.d.ts +11 -11
- package/lib/dist/resolution/vba-runtime-objects.d.ts.map +1 -1
- package/lib/dist/resolution/vba-runtime-objects.js +18 -38
- package/lib/dist/resolution/vba-runtime-objects.js.map +1 -1
- package/lib/dist/types.d.ts +13 -5
- package/lib/dist/types.d.ts.map +1 -1
- package/lib/dist/types.js +17 -0
- package/lib/dist/types.js.map +1 -1
- package/lib/dist/utils/backtrace-helpers.d.ts +14 -2
- package/lib/dist/utils/backtrace-helpers.d.ts.map +1 -1
- package/lib/dist/utils/backtrace-helpers.js +81 -7
- package/lib/dist/utils/backtrace-helpers.js.map +1 -1
- package/lib/dist/utils/sql-impact-helpers.d.ts.map +1 -1
- package/lib/dist/utils/sql-impact-helpers.js +119 -30
- package/lib/dist/utils/sql-impact-helpers.js.map +1 -1
- package/lib/node_modules/.modules.yaml +1 -1
- package/lib/node_modules/.pnpm-workspace-state-v1.json +1 -1
- package/lib/package.json +3 -1
- package/package.json +1 -1
|
@@ -54,9 +54,16 @@ exports.SqlQueryExtractor = void 0;
|
|
|
54
54
|
* table references), so the data layer is queryable and table usage is
|
|
55
55
|
* traceable. Bracketed names (`[Order Details]`) are unwrapped; a table
|
|
56
56
|
* referenced multiple times in one query produces exactly one node + edge.
|
|
57
|
+
*
|
|
58
|
+
* Issue #203: the table-name regex and reserved-word reject list live in
|
|
59
|
+
* the shared leaf module `src/extraction/sql-table-scan.ts` — the same
|
|
60
|
+
* scanner every other call site (`vba/sql-wrapper.ts`,
|
|
61
|
+
* `vba-form-extractor.ts`) imports, so a SQL reserved word can never
|
|
62
|
+
* be emitted as a table name across the project.
|
|
57
63
|
*/
|
|
58
64
|
const path = __importStar(require("path"));
|
|
59
65
|
const tree_sitter_helpers_1 = require("./tree-sitter-helpers");
|
|
66
|
+
const sql_table_scan_1 = require("./sql-table-scan");
|
|
60
67
|
class SqlQueryExtractor {
|
|
61
68
|
filePath;
|
|
62
69
|
source;
|
|
@@ -67,20 +74,6 @@ class SqlQueryExtractor {
|
|
|
67
74
|
this.filePath = filePath;
|
|
68
75
|
this.source = source;
|
|
69
76
|
}
|
|
70
|
-
/**
|
|
71
|
-
* Table name following `FROM` / `JOIN` / `INTO` / `UPDATE`. Captures an optional
|
|
72
|
-
* bracketed/unbracketed schema prefix followed by `.`, so `FROM dbo.tblCustomers`
|
|
73
|
-
* and `FROM [My Schema].[My Table]` come through as one composite reference.
|
|
74
|
-
* Without the prefix the regex still matches a single identifier (bracketed
|
|
75
|
-
* or bare) byte-identical to the old shape. `\p{L}` covers accented identifiers
|
|
76
|
-
* common in localized schemas.
|
|
77
|
-
*
|
|
78
|
-
* The captured composite goes to `sweepTables`, which strips ALL brackets
|
|
79
|
-
* (including internal ones in the bracketed-schema case) — so the public
|
|
80
|
-
* node name is the unwrapped form `dbo.tblCustomers` / `My Schema.My Table`,
|
|
81
|
-
* matching how plain `[Order Details]` is also unwrapped to `Order Details`.
|
|
82
|
-
*/
|
|
83
|
-
static TABLE_RE = /\b(?:FROM|JOIN|INTO|UPDATE)\s+((?:(?:\[[^\]]+\]|\p{L}[\p{L}\p{N}_]*)\.)?(?:\[[^\]]+\]|\p{L}[\p{L}\p{N}_]*))/giu;
|
|
84
77
|
extract() {
|
|
85
78
|
const startTime = Date.now();
|
|
86
79
|
try {
|
|
@@ -101,6 +94,7 @@ class SqlQueryExtractor {
|
|
|
101
94
|
updatedAt: Date.now(),
|
|
102
95
|
});
|
|
103
96
|
this.sweepTables(queryId);
|
|
97
|
+
this.sweepExternalBackends(queryId);
|
|
104
98
|
}
|
|
105
99
|
catch (error) {
|
|
106
100
|
this.errors.push({
|
|
@@ -141,32 +135,25 @@ class SqlQueryExtractor {
|
|
|
141
135
|
* Scan the SQL for table names and emit one synthetic `class` node + one
|
|
142
136
|
* `references` edge per distinct table. The table node id is line-independent
|
|
143
137
|
* (line 0) so the same table referenced N times collapses to one node.
|
|
138
|
+
*
|
|
139
|
+
* Issue #203: delegates to the shared `scanSqlTables` scanner in
|
|
140
|
+
* `src/extraction/sql-table-scan.ts` so a SQL reserved word can never
|
|
141
|
+
* be emitted as a table name — `WHERE x=1`, `ORDER BY a`, `SET a=1`
|
|
142
|
+
* never become phantom `class` nodes here.
|
|
144
143
|
*/
|
|
145
144
|
sweepTables(queryId) {
|
|
146
145
|
const seen = new Set();
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
while ((m = re.exec(this.source)) !== null) {
|
|
150
|
-
const raw = (m[1] ?? '').trim();
|
|
151
|
-
// Strip ALL brackets (including internal ones in the bracketed-schema case
|
|
152
|
-
// `[My Schema].[My Table]`), so the public node name is the unwrapped form
|
|
153
|
-
// `My Schema.My Table`. Same shape `VbaExtractor.emitSqlTableReferences`
|
|
154
|
-
// already produces. A plain bracketed name `[Order Details]` reduces to
|
|
155
|
-
// `Order Details` here too (no internal brackets), so existing tests are
|
|
156
|
-
// unaffected.
|
|
157
|
-
const table = raw.replace(/[\[\]]/g, '').trim();
|
|
158
|
-
if (!table)
|
|
159
|
-
continue;
|
|
160
|
-
const key = table.toLowerCase();
|
|
146
|
+
for (const row of (0, sql_table_scan_1.scanSqlTables)(this.source)) {
|
|
147
|
+
const key = row.table.toLowerCase();
|
|
161
148
|
if (seen.has(key))
|
|
162
149
|
continue;
|
|
163
150
|
seen.add(key);
|
|
164
|
-
const tableId = (0, tree_sitter_helpers_1.generateNodeId)(this.filePath, 'class', table, 0);
|
|
151
|
+
const tableId = (0, tree_sitter_helpers_1.generateNodeId)(this.filePath, 'class', row.table, 0);
|
|
165
152
|
this.nodes.push({
|
|
166
153
|
id: tableId,
|
|
167
154
|
kind: 'class', // placeholder kind; cross-file resolution re-types at lookup
|
|
168
|
-
name: table,
|
|
169
|
-
qualifiedName: table,
|
|
155
|
+
name: row.table,
|
|
156
|
+
qualifiedName: row.table,
|
|
170
157
|
filePath: this.filePath,
|
|
171
158
|
language: 'sql',
|
|
172
159
|
startLine: 1,
|
|
@@ -186,6 +173,31 @@ class SqlQueryExtractor {
|
|
|
186
173
|
});
|
|
187
174
|
}
|
|
188
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* Issue #256 — a saved query can read from another database file via the
|
|
178
|
+
* Access `IN "<path>"` clause. Emit one `file`-kind node per distinct
|
|
179
|
+
* external backend (keyed on the normalized path, so the same file named
|
|
180
|
+
* from two different queries converges on ONE node) plus a `references`
|
|
181
|
+
* edge from this query, tagged `vba-external-backend`.
|
|
182
|
+
*
|
|
183
|
+
* `scanSqlExternalBackends` already de-duplicates within one query, so no
|
|
184
|
+
* local `seen` set is needed here.
|
|
185
|
+
*/
|
|
186
|
+
sweepExternalBackends(queryId) {
|
|
187
|
+
for (const backendPath of (0, sql_table_scan_1.scanSqlExternalBackends)(this.source)) {
|
|
188
|
+
const node = (0, sql_table_scan_1.buildExternalBackendNode)(backendPath);
|
|
189
|
+
this.nodes.push(node);
|
|
190
|
+
this.edges.push({
|
|
191
|
+
source: queryId,
|
|
192
|
+
target: node.id,
|
|
193
|
+
kind: 'references',
|
|
194
|
+
provenance: 'heuristic',
|
|
195
|
+
metadata: { synthesizedBy: sql_table_scan_1.EXTERNAL_BACKEND_SYNTHESIZED_BY },
|
|
196
|
+
line: 1,
|
|
197
|
+
column: 0,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|
|
189
201
|
}
|
|
190
202
|
exports.SqlQueryExtractor = SqlQueryExtractor;
|
|
191
203
|
//# sourceMappingURL=sql-query-extractor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql-query-extractor.js","sourceRoot":"","sources":["../../src/extraction/sql-query-extractor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA
|
|
1
|
+
{"version":3,"file":"sql-query-extractor.js","sourceRoot":"","sources":["../../src/extraction/sql-query-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* # SQL table-name scanner — leaf module shared by every VBA + SQL
|
|
3
|
+
* table-extraction path (Issue #203).
|
|
4
|
+
*
|
|
5
|
+
* Before this module existed, the same `FROM/JOIN/INTO/UPDATE` capture
|
|
6
|
+
* regex lived in three places:
|
|
7
|
+
*
|
|
8
|
+
* - `src/extraction/sql-query-extractor.ts:57` (saved queries)
|
|
9
|
+
* - `src/extraction/vba/sql-wrapper.ts:80-81` (in-code SQL sweep)
|
|
10
|
+
* - `src/extraction/vba-form-extractor.ts:617-618` (RecordSource/RowSource)
|
|
11
|
+
*
|
|
12
|
+
* The three copies had already started to diverge (`vba-form-extractor`
|
|
13
|
+
* grew a `SQL_PREFIX_RE` the other two never adopted), and every
|
|
14
|
+
* caller was vulnerable to the same silently-wrong captures the issue
|
|
15
|
+
* lists:
|
|
16
|
+
*
|
|
17
|
+
* ```vba
|
|
18
|
+
* getdb().Execute "DELETE FROM " & tabla & " WHERE activo = 1"
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* Today, `collectSqlWrapperChain` silently drops non-literal operands
|
|
22
|
+
* (variables, function calls) and joins surviving literal fragments
|
|
23
|
+
* with a space. The dropped operand leaves a whitespace gap that
|
|
24
|
+
* `\s+` happily crosses, so `DELETE FROM ` + ` ` + ` WHERE activo = 1`
|
|
25
|
+
* becomes `DELETE FROM WHERE activo = 1` — and `SQL_TABLE_RE`
|
|
26
|
+
* captures `WHERE` as a table reference.
|
|
27
|
+
*
|
|
28
|
+
* ## What this module guarantees
|
|
29
|
+
*
|
|
30
|
+
* 1. The shared regex (with optional schema prefix + bracketed
|
|
31
|
+
* identifiers, identical bytes to the old shape) lives in ONE
|
|
32
|
+
* place.
|
|
33
|
+
* 2. `SQL_RESERVED_TABLE_TOKENS` rejects every SQL reserved word that
|
|
34
|
+
* can legitimately appear immediately after a
|
|
35
|
+
* `FROM`/`JOIN`/`INTO`/`UPDATE` keyword in a real statement —
|
|
36
|
+
* `WHERE`, `ORDER`, `GROUP`, `HAVING`, `SET`, `VALUES`, `SELECT`,
|
|
37
|
+
* `INNER`, `LEFT`, `RIGHT`, `OUTER`, `FULL`, `CROSS`, `JOIN`,
|
|
38
|
+
* `ON`, `UNION`, `AS`, `DISTINCT`, `TOP`, `IN`, `EXISTS`. The list
|
|
39
|
+
* is exhaustive for the SQL grammar subset codegraph models.
|
|
40
|
+
* 3. `scanSqlTables` reads a SINGLE joined SQL string. It does NOT
|
|
41
|
+
* know about VBA concatenation — the JOIN-WITH-SPACE shape
|
|
42
|
+
* `collectSqlWrapperChain` produces is its input contract.
|
|
43
|
+
* Operands dropped by `collectSqlWrapperChain` are now replaced
|
|
44
|
+
* with a `?` sentinel (see `vba/sql-wrapper.ts`); the reserved-
|
|
45
|
+
* word reject list catches any `?` keyword bridge the concat could
|
|
46
|
+
* still create.
|
|
47
|
+
* 4. Each row carries the SQL `clause` (`FROM`/`JOIN`/`INTO`/`UPDATE`)
|
|
48
|
+
* so callers can classify `access: 'read' | 'write'` without
|
|
49
|
+
* re-running the SQL classifier.
|
|
50
|
+
*
|
|
51
|
+
* ## Issue #256 — DDL verbs and the Access `IN` clause
|
|
52
|
+
*
|
|
53
|
+
* The clause set also covers `CREATE TABLE`, `ALTER TABLE` and
|
|
54
|
+
* `DROP TABLE`; all three target a table they mutate, so they carry
|
|
55
|
+
* `access: 'write'`. The reserved-word reject list applies to them
|
|
56
|
+
* unchanged.
|
|
57
|
+
*
|
|
58
|
+
* Separately, `scanSqlExternalBackends` captures the Access-specific
|
|
59
|
+
* `IN "<path>"` clause, which points a query at ANOTHER database file.
|
|
60
|
+
* That operand is a file, not a table, so it gets its own scanner and
|
|
61
|
+
* its own node shape (`buildExternalBackendNode`) rather than being
|
|
62
|
+
* folded into the table rows.
|
|
63
|
+
*
|
|
64
|
+
* ## Defense in depth
|
|
65
|
+
*
|
|
66
|
+
* The reserved-word check uses the **unwrapped first identifier
|
|
67
|
+
* component** so schema-qualified inputs like `FROM WHERE.ID` are also
|
|
68
|
+
* rejected (the unwrapped form is `WHERE.ID`, first component is
|
|
69
|
+
* `WHERE`). The check is case-insensitive (SQL keywords are
|
|
70
|
+
* case-insensitive by spec).
|
|
71
|
+
*
|
|
72
|
+
* Returning `[]` for a reserved-word capture is the "silent beats
|
|
73
|
+
* wrong" doctrine the project documents in `CLAUDE.md`: emitting a
|
|
74
|
+
* confident wrong edge ("WHERE is a table that gets written to")
|
|
75
|
+
* pollutes downstream queries far more than emitting no edge at all.
|
|
76
|
+
*/
|
|
77
|
+
import { Node } from '../types';
|
|
78
|
+
export interface SqlTableScanRow {
|
|
79
|
+
/** The unwrapped table name (brackets + surrounding whitespace stripped). */
|
|
80
|
+
table: string;
|
|
81
|
+
/**
|
|
82
|
+
* The SQL clause that introduced the reference. The four DML clauses
|
|
83
|
+
* (`FROM`/`JOIN`/`INTO`/`UPDATE`) were the original set; Issue #256
|
|
84
|
+
* added the three DDL verbs, whose targets are always writes.
|
|
85
|
+
*/
|
|
86
|
+
clause: SqlTableClause;
|
|
87
|
+
/** Whether this row reads or mutates the table — derived from the SQL verb. */
|
|
88
|
+
access: 'read' | 'write';
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Every clause keyword the scanner captures a table name after. The DDL
|
|
92
|
+
* three are two-word keywords normalized to a single interior space
|
|
93
|
+
* (`create table` → `CREATE TABLE`).
|
|
94
|
+
*/
|
|
95
|
+
export type SqlTableClause = 'FROM' | 'JOIN' | 'INTO' | 'UPDATE' | 'CREATE TABLE' | 'ALTER TABLE' | 'DROP TABLE';
|
|
96
|
+
/**
|
|
97
|
+
* Canonical reject list — every SQL reserved word that can appear
|
|
98
|
+
* immediately after `FROM`/`JOIN`/`INTO`/`UPDATE` in a real statement.
|
|
99
|
+
* The list is exported so consumers can introspect it; it is also the
|
|
100
|
+
* authoritative source the scanner consults internally.
|
|
101
|
+
*
|
|
102
|
+
* The list intentionally omits `FROM`/`JOIN`/`INTO`/`UPDATE` itself
|
|
103
|
+
* (those are the capturing keywords) and `ALL` / `ANY` (they are
|
|
104
|
+
* legitimate table-ish tokens in some dialects but rarely appear as
|
|
105
|
+
* the first token after a FROM-style keyword in a well-formed
|
|
106
|
+
* statement).
|
|
107
|
+
*/
|
|
108
|
+
export declare const SQL_RESERVED_TABLE_TOKENS: ReadonlySet<string>;
|
|
109
|
+
/**
|
|
110
|
+
* Scan a SQL string for `FROM` / `JOIN` / `INTO` / `UPDATE` table
|
|
111
|
+
* references. Returns one row per match; the caller is responsible
|
|
112
|
+
* for cross-row deduplication if it wants one node per table.
|
|
113
|
+
*
|
|
114
|
+
* Captures that resolve to a SQL reserved word (Issue #203 — e.g.
|
|
115
|
+
* `FROM WHERE x=1` → `WHERE`) are DROPPED. This encodes
|
|
116
|
+
* "we don't know this table" rather than guessing — matching the
|
|
117
|
+
* "silent beats wrong" / "partial coverage is worse than none"
|
|
118
|
+
* doctrine the project documents in `CLAUDE.md`.
|
|
119
|
+
*
|
|
120
|
+
* Schema-qualified inputs (`FROM WHERE.ID` → `WHERE.ID`) are also
|
|
121
|
+
* dropped: the check inspects the FIRST unwrapped identifier
|
|
122
|
+
* component (everything up to the first `.`), case-insensitive.
|
|
123
|
+
*
|
|
124
|
+
* Empty / whitespace-only / non-DML input returns `[]`.
|
|
125
|
+
*/
|
|
126
|
+
export declare function scanSqlTables(sql: string): SqlTableScanRow[];
|
|
127
|
+
/**
|
|
128
|
+
* Issue #256: the `synthesizedBy` tag stamped on every `references`
|
|
129
|
+
* edge that points at an external backend file. Exported so consumers
|
|
130
|
+
* and tests share one spelling.
|
|
131
|
+
*/
|
|
132
|
+
export declare const EXTERNAL_BACKEND_SYNTHESIZED_BY = "vba-external-backend";
|
|
133
|
+
/**
|
|
134
|
+
* Issue #256: normalize an external-database path so the SAME file named
|
|
135
|
+
* from two different queries converges on ONE node.
|
|
136
|
+
*
|
|
137
|
+
* Access backends are Windows paths: the separator may be `\` or `/`,
|
|
138
|
+
* the case is not significant, and a hand-written path often carries a
|
|
139
|
+
* doubled separator or a trailing one. Normalizing to lowercase
|
|
140
|
+
* forward-slash form makes `C:\Datos\Otra.accdb` and
|
|
141
|
+
* `c:/datos/otra.accdb` the same key.
|
|
142
|
+
*
|
|
143
|
+
* A leading `//` is preserved so a UNC share (`\\SERVIDOR\Datos\x.accdb`)
|
|
144
|
+
* stays distinguishable from an absolute local path.
|
|
145
|
+
*
|
|
146
|
+
* Returns `''` for blank input; callers drop empty paths.
|
|
147
|
+
*/
|
|
148
|
+
export declare function normalizeBackendPath(raw: string): string;
|
|
149
|
+
/**
|
|
150
|
+
* Issue #256: scan a SQL string for Access `IN "<path>"` external-backend
|
|
151
|
+
* clauses. Returns the NORMALIZED paths in first-appearance order, with
|
|
152
|
+
* duplicates collapsed (two spellings of the same file are one entry).
|
|
153
|
+
*
|
|
154
|
+
* Empty / unquoted / value-list `IN` operands yield nothing — the same
|
|
155
|
+
* "silent beats wrong" doctrine the table scanner follows: an operand we
|
|
156
|
+
* cannot key on produces no node rather than a guessed one.
|
|
157
|
+
*/
|
|
158
|
+
export declare function scanSqlExternalBackends(sql: string): string[];
|
|
159
|
+
/**
|
|
160
|
+
* Issue #256: build the graph node for an external backend file.
|
|
161
|
+
*
|
|
162
|
+
* `file` is the honest kind — it IS a file, just not one this index
|
|
163
|
+
* parsed — so no new `NodeKind` is needed, and `metadata.external`
|
|
164
|
+
* keeps it distinguishable from indexed files in every query.
|
|
165
|
+
*
|
|
166
|
+
* Two properties matter and are both deliberate:
|
|
167
|
+
*
|
|
168
|
+
* 1. **Convergence.** The node id is keyed on the normalized path via a
|
|
169
|
+
* synthetic `synthetic:external-db/<path>` file path (the same trick
|
|
170
|
+
* `vba/tempvars.ts` uses for TempVars keys), so the same backend named
|
|
171
|
+
* from two different queries — or from a saved query AND from in-code
|
|
172
|
+
* SQL — collapses to ONE node instead of one per referencing file.
|
|
173
|
+
* 2. **Byte-identity.** Everything on the node derives from the
|
|
174
|
+
* normalized path alone: no line, no column, no per-caller language.
|
|
175
|
+
* Every emitter therefore produces an identical node, so whichever
|
|
176
|
+
* one is written last cannot silently rewrite the others' fields.
|
|
177
|
+
* Per-site position lives on the `references` EDGE, which is where
|
|
178
|
+
* call-site information belongs.
|
|
179
|
+
*
|
|
180
|
+
* The `language` is pinned to `vba` because the node models an Access
|
|
181
|
+
* database file, whichever extractor happened to discover it.
|
|
182
|
+
*/
|
|
183
|
+
export declare function buildExternalBackendNode(normalizedPath: string): Node;
|
|
184
|
+
//# sourceMappingURL=sql-table-scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-table-scan.d.ts","sourceRoot":"","sources":["../../src/extraction/sql-table-scan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2EG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAGhC,MAAM,WAAW,eAAe;IAC9B,6EAA6E;IAC7E,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,MAAM,EAAE,cAAc,CAAC;IACvB,+EAA+E;IAC/E,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,MAAM,GACN,MAAM,GACN,QAAQ,GACR,cAAc,GACd,aAAa,GACb,YAAY,CAAC;AAiBjB;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,yBAAyB,EAAE,WAAW,CAAC,MAAM,CAsBxD,CAAC;AA4BH;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,EAAE,CA2B5D;AA2DD;;;;GAIG;AACH,eAAO,MAAM,+BAA+B,yBAAyB,CAAC;AAEtE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAWxD;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAe7D;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,wBAAwB,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAgBrE"}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EXTERNAL_BACKEND_SYNTHESIZED_BY = exports.SQL_RESERVED_TABLE_TOKENS = void 0;
|
|
4
|
+
exports.scanSqlTables = scanSqlTables;
|
|
5
|
+
exports.normalizeBackendPath = normalizeBackendPath;
|
|
6
|
+
exports.scanSqlExternalBackends = scanSqlExternalBackends;
|
|
7
|
+
exports.buildExternalBackendNode = buildExternalBackendNode;
|
|
8
|
+
const tree_sitter_helpers_1 = require("./tree-sitter-helpers");
|
|
9
|
+
/**
|
|
10
|
+
* The set of clause keywords, in the same order as the regex alternation.
|
|
11
|
+
* Used to validate a capture's clause before it is narrowed to
|
|
12
|
+
* {@link SqlTableClause}.
|
|
13
|
+
*/
|
|
14
|
+
const SQL_TABLE_CLAUSES = new Set([
|
|
15
|
+
'FROM',
|
|
16
|
+
'JOIN',
|
|
17
|
+
'INTO',
|
|
18
|
+
'UPDATE',
|
|
19
|
+
'CREATE TABLE',
|
|
20
|
+
'ALTER TABLE',
|
|
21
|
+
'DROP TABLE',
|
|
22
|
+
]);
|
|
23
|
+
/**
|
|
24
|
+
* Canonical reject list — every SQL reserved word that can appear
|
|
25
|
+
* immediately after `FROM`/`JOIN`/`INTO`/`UPDATE` in a real statement.
|
|
26
|
+
* The list is exported so consumers can introspect it; it is also the
|
|
27
|
+
* authoritative source the scanner consults internally.
|
|
28
|
+
*
|
|
29
|
+
* The list intentionally omits `FROM`/`JOIN`/`INTO`/`UPDATE` itself
|
|
30
|
+
* (those are the capturing keywords) and `ALL` / `ANY` (they are
|
|
31
|
+
* legitimate table-ish tokens in some dialects but rarely appear as
|
|
32
|
+
* the first token after a FROM-style keyword in a well-formed
|
|
33
|
+
* statement).
|
|
34
|
+
*/
|
|
35
|
+
exports.SQL_RESERVED_TABLE_TOKENS = new Set([
|
|
36
|
+
'WHERE',
|
|
37
|
+
'ORDER',
|
|
38
|
+
'GROUP',
|
|
39
|
+
'HAVING',
|
|
40
|
+
'INNER',
|
|
41
|
+
'LEFT',
|
|
42
|
+
'RIGHT',
|
|
43
|
+
'OUTER',
|
|
44
|
+
'FULL',
|
|
45
|
+
'CROSS',
|
|
46
|
+
'JOIN',
|
|
47
|
+
'ON',
|
|
48
|
+
'SET',
|
|
49
|
+
'VALUES',
|
|
50
|
+
'SELECT',
|
|
51
|
+
'UNION',
|
|
52
|
+
'AS',
|
|
53
|
+
'DISTINCT',
|
|
54
|
+
'TOP',
|
|
55
|
+
'IN',
|
|
56
|
+
'EXISTS',
|
|
57
|
+
]);
|
|
58
|
+
/**
|
|
59
|
+
* Shared `FROM` / `JOIN` / `INTO` / `UPDATE <table>` regex. Same
|
|
60
|
+
* shape as the three duplicates this module consolidates: group 1 is
|
|
61
|
+
* the clause keyword (`FROM`/`JOIN`/`INTO`/`UPDATE`), group 2 is the
|
|
62
|
+
* composite identifier — an optional bracketed/unbracketed schema
|
|
63
|
+
* prefix followed by `.`, then a bracketed-or-bare identifier.
|
|
64
|
+
*
|
|
65
|
+
* `FROM dbo.tblCustomers` → m[2] = `dbo.tblCustomers`
|
|
66
|
+
* `FROM [My Schema].[My Table]` → m[2] = `[My Schema].[My Table]`
|
|
67
|
+
* `FROM tblCustomers` → m[2] = `tblCustomers`
|
|
68
|
+
* `FROM [Order Details]` → m[2] = `[Order Details]`
|
|
69
|
+
*
|
|
70
|
+
* Brackets in `m[2]` are stripped by `scanSqlTables`, so the public
|
|
71
|
+
* table name is the unwrapped form (`dbo.tblCustomers` /
|
|
72
|
+
* `My Schema.My Table`) — matching how plain `[Order Details]` is
|
|
73
|
+
* also unwrapped to `Order Details`. `\p{L}` covers accented
|
|
74
|
+
* identifiers common in localized schemas.
|
|
75
|
+
*
|
|
76
|
+
* Keeping the single composite capture (rather than splitting
|
|
77
|
+
* schema/table into separate groups) preserves byte-identity with the
|
|
78
|
+
* three duplicates this module replaces, so every existing
|
|
79
|
+
* regression test continues to apply without rewrites.
|
|
80
|
+
*/
|
|
81
|
+
const TABLE_RE = /\b(FROM|JOIN|INTO|UPDATE|CREATE\s+TABLE|ALTER\s+TABLE|DROP\s+TABLE)\s+((?:(?:\[[^\]]+\]|\p{L}[\p{L}\p{N}_]*)\.)?(?:\[[^\]]+\]|\p{L}[\p{L}\p{N}_]*))/giu;
|
|
82
|
+
/**
|
|
83
|
+
* Scan a SQL string for `FROM` / `JOIN` / `INTO` / `UPDATE` table
|
|
84
|
+
* references. Returns one row per match; the caller is responsible
|
|
85
|
+
* for cross-row deduplication if it wants one node per table.
|
|
86
|
+
*
|
|
87
|
+
* Captures that resolve to a SQL reserved word (Issue #203 — e.g.
|
|
88
|
+
* `FROM WHERE x=1` → `WHERE`) are DROPPED. This encodes
|
|
89
|
+
* "we don't know this table" rather than guessing — matching the
|
|
90
|
+
* "silent beats wrong" / "partial coverage is worse than none"
|
|
91
|
+
* doctrine the project documents in `CLAUDE.md`.
|
|
92
|
+
*
|
|
93
|
+
* Schema-qualified inputs (`FROM WHERE.ID` → `WHERE.ID`) are also
|
|
94
|
+
* dropped: the check inspects the FIRST unwrapped identifier
|
|
95
|
+
* component (everything up to the first `.`), case-insensitive.
|
|
96
|
+
*
|
|
97
|
+
* Empty / whitespace-only / non-DML input returns `[]`.
|
|
98
|
+
*/
|
|
99
|
+
function scanSqlTables(sql) {
|
|
100
|
+
if (!sql)
|
|
101
|
+
return [];
|
|
102
|
+
const out = [];
|
|
103
|
+
const re = new RegExp(TABLE_RE.source, TABLE_RE.flags);
|
|
104
|
+
let m;
|
|
105
|
+
while ((m = re.exec(sql)) !== null) {
|
|
106
|
+
// Normalize the clause keyword: uppercase, and collapse the interior
|
|
107
|
+
// whitespace of the two-word DDL verbs (`create table` →
|
|
108
|
+
// `CREATE TABLE`) so the emitted `clause` is a stable enum value.
|
|
109
|
+
const clauseRaw = (m[1] ?? '').toUpperCase().replace(/\s+/g, ' ');
|
|
110
|
+
if (!SQL_TABLE_CLAUSES.has(clauseRaw))
|
|
111
|
+
continue;
|
|
112
|
+
const clause = clauseRaw;
|
|
113
|
+
// m[2] is the composite (optional schema `.` table) with any
|
|
114
|
+
// combination of brackets. Strip ALL brackets and surrounding
|
|
115
|
+
// whitespace — the public node name is the unwrapped form.
|
|
116
|
+
const table = (m[2] ?? '').replace(/[\[\]]/g, '').trim();
|
|
117
|
+
if (!table)
|
|
118
|
+
continue;
|
|
119
|
+
// Reserved-word rejection — the FIRST identifier component is the
|
|
120
|
+
// canonical SQL keyword to test (handles `WHERE.ID` too).
|
|
121
|
+
const firstId = table.split('.')[0] ?? '';
|
|
122
|
+
if (exports.SQL_RESERVED_TABLE_TOKENS.has(firstId.toUpperCase()))
|
|
123
|
+
continue;
|
|
124
|
+
out.push({ table, clause, access: classifyAccess(sql, clause) });
|
|
125
|
+
}
|
|
126
|
+
return out;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* `access` classifier — ported verbatim from
|
|
130
|
+
* `src/extraction/vba/sql-wrapper.ts:91-96`. Lifted into this leaf
|
|
131
|
+
* module so all three call sites produce identical tagging.
|
|
132
|
+
*
|
|
133
|
+
* The mutating targets are writes: `INSERT INTO <t>`, `UPDATE <t>`,
|
|
134
|
+
* and the `FROM <t>` of a `DELETE` (Access's `DELETE FROM x` makes
|
|
135
|
+
* that FROM the delete target). Every other `FROM`/`JOIN` source
|
|
136
|
+
* table — including the source of an `INSERT ... SELECT` — is a read.
|
|
137
|
+
*
|
|
138
|
+
* Issue #256: the three DDL verbs are unconditional writes. `CREATE
|
|
139
|
+
* TABLE` and `DROP TABLE` change whether the table exists at all, and
|
|
140
|
+
* `ALTER TABLE` rewrites its shape — every one of them is a mutation of
|
|
141
|
+
* the named table, so "who writes to table X" must report them.
|
|
142
|
+
*/
|
|
143
|
+
function classifyAccess(sqlString, clause) {
|
|
144
|
+
if (clause === 'INTO' || clause === 'UPDATE')
|
|
145
|
+
return 'write';
|
|
146
|
+
if (clause === 'CREATE TABLE' || clause === 'ALTER TABLE' || clause === 'DROP TABLE') {
|
|
147
|
+
return 'write';
|
|
148
|
+
}
|
|
149
|
+
if (clause === 'FROM' && /^\s*DELETE\b/i.test(sqlString))
|
|
150
|
+
return 'write';
|
|
151
|
+
return 'read';
|
|
152
|
+
}
|
|
153
|
+
// ---------------------------------------------------------------------------
|
|
154
|
+
// Access `IN "<path>"` — the external-backend clause (Issue #256)
|
|
155
|
+
// ---------------------------------------------------------------------------
|
|
156
|
+
/**
|
|
157
|
+
* Issue #256: Jet/ACE lets a single query read or write a table that
|
|
158
|
+
* lives in ANOTHER database file:
|
|
159
|
+
*
|
|
160
|
+
* ```sql
|
|
161
|
+
* SELECT * FROM TbRemota IN "C:\datos\otra.accdb"
|
|
162
|
+
* ```
|
|
163
|
+
*
|
|
164
|
+
* The `IN` operand is a FILE, not a table, so it needs its own capture
|
|
165
|
+
* and its own representation. Without it a cross-backend access is
|
|
166
|
+
* indistinguishable from a local one, and the second database file is
|
|
167
|
+
* invisible to the graph.
|
|
168
|
+
*
|
|
169
|
+
* Only a QUOTED operand matches. The value-list operator (`WHERE Id IN
|
|
170
|
+
* (1,2)`, `WHERE N IN ("a","b")`) always opens with `(`, so requiring a
|
|
171
|
+
* quote immediately after the keyword separates the two meanings without
|
|
172
|
+
* a parser. `IN ""` — the empty path of the Access ODBC/dBASE
|
|
173
|
+
* connect-string form (`IN "" [ODBC;DSN=x]`) — yields an empty operand
|
|
174
|
+
* and is dropped: that shape names a DSN, not a file we can key on.
|
|
175
|
+
*
|
|
176
|
+
* The first alternative handles the VBA doubled-quote shape. A SQL
|
|
177
|
+
* string built in VBA source (`"… IN ""C:\x.accdb"""`) reaches the
|
|
178
|
+
* scanner with its inner quotes still doubled, because the wrapper
|
|
179
|
+
* regex in `vba/sql-wrapper.ts` captures the first literal verbatim.
|
|
180
|
+
* Matching `""…""` before `"…"` decodes that shape without a
|
|
181
|
+
* whole-string rewrite that could disturb the table scan.
|
|
182
|
+
*/
|
|
183
|
+
const EXTERNAL_BACKEND_RE = /\bIN\s+(?:""([^"]+)""|"([^"]*)"|'([^']*)')/giu;
|
|
184
|
+
/**
|
|
185
|
+
* Issue #256: the `synthesizedBy` tag stamped on every `references`
|
|
186
|
+
* edge that points at an external backend file. Exported so consumers
|
|
187
|
+
* and tests share one spelling.
|
|
188
|
+
*/
|
|
189
|
+
exports.EXTERNAL_BACKEND_SYNTHESIZED_BY = 'vba-external-backend';
|
|
190
|
+
/**
|
|
191
|
+
* Issue #256: normalize an external-database path so the SAME file named
|
|
192
|
+
* from two different queries converges on ONE node.
|
|
193
|
+
*
|
|
194
|
+
* Access backends are Windows paths: the separator may be `\` or `/`,
|
|
195
|
+
* the case is not significant, and a hand-written path often carries a
|
|
196
|
+
* doubled separator or a trailing one. Normalizing to lowercase
|
|
197
|
+
* forward-slash form makes `C:\Datos\Otra.accdb` and
|
|
198
|
+
* `c:/datos/otra.accdb` the same key.
|
|
199
|
+
*
|
|
200
|
+
* A leading `//` is preserved so a UNC share (`\\SERVIDOR\Datos\x.accdb`)
|
|
201
|
+
* stays distinguishable from an absolute local path.
|
|
202
|
+
*
|
|
203
|
+
* Returns `''` for blank input; callers drop empty paths.
|
|
204
|
+
*/
|
|
205
|
+
function normalizeBackendPath(raw) {
|
|
206
|
+
const trimmed = raw.trim();
|
|
207
|
+
if (!trimmed)
|
|
208
|
+
return '';
|
|
209
|
+
const slashed = trimmed.replace(/\\/g, '/');
|
|
210
|
+
const uncPrefix = slashed.startsWith('//') ? '//' : '';
|
|
211
|
+
const body = slashed
|
|
212
|
+
.slice(uncPrefix.length)
|
|
213
|
+
.replace(/\/{2,}/g, '/')
|
|
214
|
+
.replace(/\/+$/, '');
|
|
215
|
+
if (!body)
|
|
216
|
+
return '';
|
|
217
|
+
return (uncPrefix + body).toLowerCase();
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Issue #256: scan a SQL string for Access `IN "<path>"` external-backend
|
|
221
|
+
* clauses. Returns the NORMALIZED paths in first-appearance order, with
|
|
222
|
+
* duplicates collapsed (two spellings of the same file are one entry).
|
|
223
|
+
*
|
|
224
|
+
* Empty / unquoted / value-list `IN` operands yield nothing — the same
|
|
225
|
+
* "silent beats wrong" doctrine the table scanner follows: an operand we
|
|
226
|
+
* cannot key on produces no node rather than a guessed one.
|
|
227
|
+
*/
|
|
228
|
+
function scanSqlExternalBackends(sql) {
|
|
229
|
+
if (!sql)
|
|
230
|
+
return [];
|
|
231
|
+
const out = [];
|
|
232
|
+
const seen = new Set();
|
|
233
|
+
const re = new RegExp(EXTERNAL_BACKEND_RE.source, EXTERNAL_BACKEND_RE.flags);
|
|
234
|
+
let m;
|
|
235
|
+
while ((m = re.exec(sql)) !== null) {
|
|
236
|
+
const raw = m[1] ?? m[2] ?? m[3] ?? '';
|
|
237
|
+
const normalized = normalizeBackendPath(raw);
|
|
238
|
+
if (!normalized)
|
|
239
|
+
continue;
|
|
240
|
+
if (seen.has(normalized))
|
|
241
|
+
continue;
|
|
242
|
+
seen.add(normalized);
|
|
243
|
+
out.push(normalized);
|
|
244
|
+
}
|
|
245
|
+
return out;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Issue #256: build the graph node for an external backend file.
|
|
249
|
+
*
|
|
250
|
+
* `file` is the honest kind — it IS a file, just not one this index
|
|
251
|
+
* parsed — so no new `NodeKind` is needed, and `metadata.external`
|
|
252
|
+
* keeps it distinguishable from indexed files in every query.
|
|
253
|
+
*
|
|
254
|
+
* Two properties matter and are both deliberate:
|
|
255
|
+
*
|
|
256
|
+
* 1. **Convergence.** The node id is keyed on the normalized path via a
|
|
257
|
+
* synthetic `synthetic:external-db/<path>` file path (the same trick
|
|
258
|
+
* `vba/tempvars.ts` uses for TempVars keys), so the same backend named
|
|
259
|
+
* from two different queries — or from a saved query AND from in-code
|
|
260
|
+
* SQL — collapses to ONE node instead of one per referencing file.
|
|
261
|
+
* 2. **Byte-identity.** Everything on the node derives from the
|
|
262
|
+
* normalized path alone: no line, no column, no per-caller language.
|
|
263
|
+
* Every emitter therefore produces an identical node, so whichever
|
|
264
|
+
* one is written last cannot silently rewrite the others' fields.
|
|
265
|
+
* Per-site position lives on the `references` EDGE, which is where
|
|
266
|
+
* call-site information belongs.
|
|
267
|
+
*
|
|
268
|
+
* The `language` is pinned to `vba` because the node models an Access
|
|
269
|
+
* database file, whichever extractor happened to discover it.
|
|
270
|
+
*/
|
|
271
|
+
function buildExternalBackendNode(normalizedPath) {
|
|
272
|
+
const filePath = `synthetic:external-db/${normalizedPath}`;
|
|
273
|
+
return {
|
|
274
|
+
id: (0, tree_sitter_helpers_1.generateNodeId)(filePath, 'file', normalizedPath, 0),
|
|
275
|
+
kind: 'file',
|
|
276
|
+
name: normalizedPath.split('/').filter(Boolean).pop() ?? normalizedPath,
|
|
277
|
+
qualifiedName: normalizedPath,
|
|
278
|
+
filePath,
|
|
279
|
+
language: 'vba',
|
|
280
|
+
startLine: 1,
|
|
281
|
+
endLine: 1,
|
|
282
|
+
startColumn: 0,
|
|
283
|
+
endColumn: normalizedPath.length,
|
|
284
|
+
metadata: { external: true, backendPath: normalizedPath },
|
|
285
|
+
updatedAt: Date.now(),
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
//# sourceMappingURL=sql-table-scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-table-scan.js","sourceRoot":"","sources":["../../src/extraction/sql-table-scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Handles parsing source code and extracting structural information.
|
|
5
5
|
*/
|
|
6
6
|
import { Language, ExtractionResult } from '../types';
|
|
7
|
+
import type { VbaExtractionOptions } from './vba/options';
|
|
7
8
|
export { generateNodeId } from './tree-sitter-helpers';
|
|
8
9
|
/**
|
|
9
10
|
* TreeSitterExtractor - Main extraction class
|
|
@@ -709,6 +710,14 @@ export declare class TreeSitterExtractor {
|
|
|
709
710
|
* just a `file` node. Read from `codegraph.json` via
|
|
710
711
|
* `loadDysflowExportConfig(rootDir)` at the call site and threaded in here
|
|
711
712
|
* so this function stays project-config-agnostic.
|
|
713
|
+
*
|
|
714
|
+
* `vbaOptions` (issue #243) is the object form of every VBA-specific knob and
|
|
715
|
+
* is what in-repo callers pass. The `vbaTargets` / `maxRaiseFanout`
|
|
716
|
+
* positionals are `@deprecated` and kept for one release; when both are
|
|
717
|
+
* supplied the OBJECT WINS per field.
|
|
718
|
+
*
|
|
719
|
+
* @param vbaTargets @deprecated Pass `vbaOptions.targets` instead.
|
|
720
|
+
* @param maxRaiseFanout @deprecated Pass `vbaOptions.maxRaiseFanout` instead.
|
|
712
721
|
*/
|
|
713
|
-
export declare function extractFromSource(filePath: string, source: string, language?: Language, frameworkNames?: string[], vbaTargets?: Record<string, boolean>, maxRaiseFanout?: number, dysflowExport?: boolean): ExtractionResult;
|
|
722
|
+
export declare function extractFromSource(filePath: string, source: string, language?: Language, frameworkNames?: string[], vbaTargets?: Record<string, boolean>, maxRaiseFanout?: number, dysflowExport?: boolean, vbaOptions?: VbaExtractionOptions): ExtractionResult;
|
|
714
723
|
//# sourceMappingURL=tree-sitter.d.ts.map
|