@rawsql-ts/ztd-cli 0.20.0 → 0.20.2
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/LICENSE +21 -0
- package/dist/commands/agents.d.ts +2 -0
- package/dist/commands/agents.js +68 -0
- package/dist/commands/agents.js.map +1 -0
- package/dist/commands/checkContract.d.ts +46 -0
- package/dist/commands/checkContract.js +359 -0
- package/dist/commands/checkContract.js.map +1 -0
- package/dist/commands/connectionOptions.d.ts +12 -0
- package/dist/commands/connectionOptions.js +22 -0
- package/dist/commands/connectionOptions.js.map +1 -0
- package/dist/commands/ddl.d.ts +7 -0
- package/dist/commands/ddl.js +145 -0
- package/dist/commands/ddl.js.map +1 -0
- package/dist/commands/describe.d.ts +23 -0
- package/dist/commands/describe.js +399 -0
- package/dist/commands/describe.js.map +1 -0
- package/dist/commands/diff.d.ts +24 -0
- package/dist/commands/diff.js +73 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/genEntities.d.ts +14 -0
- package/dist/commands/genEntities.js +58 -0
- package/dist/commands/genEntities.js.map +1 -0
- package/dist/commands/init.d.ts +104 -0
- package/dist/commands/init.js +1480 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/lint.d.ts +89 -0
- package/dist/commands/lint.js +501 -0
- package/dist/commands/lint.js.map +1 -0
- package/dist/commands/modelGen.d.ts +60 -0
- package/dist/commands/modelGen.js +572 -0
- package/dist/commands/modelGen.js.map +1 -0
- package/dist/commands/options.d.ts +9 -0
- package/dist/commands/options.js +48 -0
- package/dist/commands/options.js.map +1 -0
- package/dist/commands/perf.d.ts +9 -0
- package/dist/commands/perf.js +374 -0
- package/dist/commands/perf.js.map +1 -0
- package/dist/commands/pull.d.ts +21 -0
- package/dist/commands/pull.js +115 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/query.d.ts +9 -0
- package/dist/commands/query.js +377 -0
- package/dist/commands/query.js.map +1 -0
- package/dist/commands/testEvidence.d.ts +237 -0
- package/dist/commands/testEvidence.js +1220 -0
- package/dist/commands/testEvidence.js.map +1 -0
- package/dist/commands/ztdConfig.d.ts +30 -0
- package/dist/commands/ztdConfig.js +224 -0
- package/dist/commands/ztdConfig.js.map +1 -0
- package/dist/commands/ztdConfigCommand.d.ts +18 -0
- package/dist/commands/ztdConfigCommand.js +268 -0
- package/dist/commands/ztdConfigCommand.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +127 -0
- package/dist/index.js.map +1 -0
- package/dist/perf/benchmark.d.ts +277 -0
- package/dist/perf/benchmark.js +2186 -0
- package/dist/perf/benchmark.js.map +1 -0
- package/dist/perf/sandbox.d.ts +73 -0
- package/dist/perf/sandbox.js +492 -0
- package/dist/perf/sandbox.js.map +1 -0
- package/dist/query/analysis.d.ts +20 -0
- package/dist/query/analysis.js +192 -0
- package/dist/query/analysis.js.map +1 -0
- package/dist/query/analyzeColumnUsage.d.ts +10 -0
- package/dist/query/analyzeColumnUsage.js +451 -0
- package/dist/query/analyzeColumnUsage.js.map +1 -0
- package/dist/query/analyzeTableUsage.d.ts +10 -0
- package/dist/query/analyzeTableUsage.js +318 -0
- package/dist/query/analyzeTableUsage.js.map +1 -0
- package/dist/query/execute.d.ts +40 -0
- package/dist/query/execute.js +784 -0
- package/dist/query/execute.js.map +1 -0
- package/dist/query/format.d.ts +1 -0
- package/dist/query/format.js +9 -0
- package/dist/query/format.js.map +1 -0
- package/dist/query/lint.d.ts +29 -0
- package/dist/query/lint.js +340 -0
- package/dist/query/lint.js.map +1 -0
- package/dist/query/location.d.ts +18 -0
- package/dist/query/location.js +204 -0
- package/dist/query/location.js.map +1 -0
- package/dist/query/patch.d.ts +21 -0
- package/dist/query/patch.js +151 -0
- package/dist/query/patch.js.map +1 -0
- package/dist/query/planner.d.ts +31 -0
- package/dist/query/planner.js +134 -0
- package/dist/query/planner.js.map +1 -0
- package/dist/query/report.d.ts +7 -0
- package/dist/query/report.js +19 -0
- package/dist/query/report.js.map +1 -0
- package/dist/query/scalarFilterAnalysis.d.ts +6 -0
- package/dist/query/scalarFilterAnalysis.js +212 -0
- package/dist/query/scalarFilterAnalysis.js.map +1 -0
- package/dist/query/slice.d.ts +17 -0
- package/dist/query/slice.js +204 -0
- package/dist/query/slice.js.map +1 -0
- package/dist/query/structure.d.ts +24 -0
- package/dist/query/structure.js +135 -0
- package/dist/query/structure.js.map +1 -0
- package/dist/query/targets.d.ts +2 -0
- package/dist/query/targets.js +6 -0
- package/dist/query/targets.js.map +1 -0
- package/dist/query/types.d.ts +97 -0
- package/dist/query/types.js +3 -0
- package/dist/query/types.js.map +1 -0
- package/dist/specs/sql/activeOrders.catalog.d.ts +12 -0
- package/dist/specs/sql/activeOrders.catalog.js +36 -0
- package/dist/specs/sql/activeOrders.catalog.js.map +1 -0
- package/dist/specs/sql/usersList.catalog.d.ts +8 -0
- package/dist/specs/sql/usersList.catalog.js +14 -0
- package/dist/specs/sql/usersList.catalog.js.map +1 -0
- package/dist/specs/sqlCatalogDefinition.d.ts +20 -0
- package/dist/specs/sqlCatalogDefinition.js +10 -0
- package/dist/specs/sqlCatalogDefinition.js.map +1 -0
- package/dist/utils/agentCli.d.ts +23 -0
- package/dist/utils/agentCli.js +84 -0
- package/dist/utils/agentCli.js.map +1 -0
- package/dist/utils/agentSafety.d.ts +4 -0
- package/dist/utils/agentSafety.js +50 -0
- package/dist/utils/agentSafety.js.map +1 -0
- package/dist/utils/agents.d.ts +31 -0
- package/dist/utils/agents.js +362 -0
- package/dist/utils/agents.js.map +1 -0
- package/dist/utils/collectSqlFiles.d.ts +9 -0
- package/dist/utils/collectSqlFiles.js +58 -0
- package/dist/utils/collectSqlFiles.js.map +1 -0
- package/dist/utils/connectionSummary.d.ts +3 -0
- package/dist/utils/connectionSummary.js +29 -0
- package/dist/utils/connectionSummary.js.map +1 -0
- package/dist/utils/dbConnection.d.ts +31 -0
- package/dist/utils/dbConnection.js +151 -0
- package/dist/utils/dbConnection.js.map +1 -0
- package/dist/utils/fs.d.ts +1 -0
- package/dist/utils/fs.js +12 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/modelGenBinder.d.ts +8 -0
- package/dist/utils/modelGenBinder.js +31 -0
- package/dist/utils/modelGenBinder.js.map +1 -0
- package/dist/utils/modelGenRender.d.ts +29 -0
- package/dist/utils/modelGenRender.js +158 -0
- package/dist/utils/modelGenRender.js.map +1 -0
- package/dist/utils/modelGenScanner.d.ts +24 -0
- package/dist/utils/modelGenScanner.js +196 -0
- package/dist/utils/modelGenScanner.js.map +1 -0
- package/dist/utils/modelProbe.d.ts +14 -0
- package/dist/utils/modelProbe.js +121 -0
- package/dist/utils/modelProbe.js.map +1 -0
- package/dist/utils/normalizePulledSchema.d.ts +12 -0
- package/dist/utils/normalizePulledSchema.js +213 -0
- package/dist/utils/normalizePulledSchema.js.map +1 -0
- package/dist/utils/optionalDependencies.d.ts +43 -0
- package/dist/utils/optionalDependencies.js +134 -0
- package/dist/utils/optionalDependencies.js.map +1 -0
- package/dist/utils/pgDump.d.ts +12 -0
- package/dist/utils/pgDump.js +58 -0
- package/dist/utils/pgDump.js.map +1 -0
- package/dist/utils/queryFingerprint.d.ts +14 -0
- package/dist/utils/queryFingerprint.js +34 -0
- package/dist/utils/queryFingerprint.js.map +1 -0
- package/dist/utils/sqlCatalogDiscovery.d.ts +44 -0
- package/dist/utils/sqlCatalogDiscovery.js +166 -0
- package/dist/utils/sqlCatalogDiscovery.js.map +1 -0
- package/dist/utils/sqlCatalogStatements.d.ts +20 -0
- package/dist/utils/sqlCatalogStatements.js +23 -0
- package/dist/utils/sqlCatalogStatements.js.map +1 -0
- package/dist/utils/sqlLintHelpers.d.ts +18 -0
- package/dist/utils/sqlLintHelpers.js +270 -0
- package/dist/utils/sqlLintHelpers.js.map +1 -0
- package/dist/utils/telemetry.d.ts +71 -0
- package/dist/utils/telemetry.js +597 -0
- package/dist/utils/telemetry.js.map +1 -0
- package/dist/utils/typeMapper.d.ts +4 -0
- package/dist/utils/typeMapper.js +79 -0
- package/dist/utils/typeMapper.js.map +1 -0
- package/dist/utils/ztdProjectConfig.d.ts +41 -0
- package/dist/utils/ztdProjectConfig.js +182 -0
- package/dist/utils/ztdProjectConfig.js.map +1 -0
- package/package.json +19 -20
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.assertSupportedStatement = assertSupportedStatement;
|
|
4
|
+
exports.analyzeStatement = analyzeStatement;
|
|
5
|
+
exports.detectQueryType = detectQueryType;
|
|
6
|
+
exports.buildDependencyMap = buildDependencyMap;
|
|
7
|
+
exports.collectRootDependencies = collectRootDependencies;
|
|
8
|
+
exports.collectReachableCtes = collectReachableCtes;
|
|
9
|
+
exports.collectDependencyClosure = collectDependencyClosure;
|
|
10
|
+
exports.collectDirectSources = collectDirectSources;
|
|
11
|
+
exports.isSelectStatement = isSelectStatement;
|
|
12
|
+
exports.uniquePreservingOrder = uniquePreservingOrder;
|
|
13
|
+
const rawsql_ts_1 = require("rawsql-ts");
|
|
14
|
+
function assertSupportedStatement(parsed, commandName) {
|
|
15
|
+
if (parsed instanceof rawsql_ts_1.SimpleSelectQuery ||
|
|
16
|
+
parsed instanceof rawsql_ts_1.BinarySelectQuery ||
|
|
17
|
+
parsed instanceof rawsql_ts_1.ValuesQuery ||
|
|
18
|
+
parsed instanceof rawsql_ts_1.InsertQuery ||
|
|
19
|
+
parsed instanceof rawsql_ts_1.UpdateQuery ||
|
|
20
|
+
parsed instanceof rawsql_ts_1.DeleteQuery) {
|
|
21
|
+
return parsed;
|
|
22
|
+
}
|
|
23
|
+
throw new Error(`${commandName} supports SELECT/INSERT/UPDATE/DELETE statements only.`);
|
|
24
|
+
}
|
|
25
|
+
function analyzeStatement(statement) {
|
|
26
|
+
const cteCollector = new rawsql_ts_1.CTECollector();
|
|
27
|
+
const ctes = cteCollector.collect(statement);
|
|
28
|
+
const cteNames = ctes.map((cte) => cte.aliasExpression.table.name);
|
|
29
|
+
const dependencyMap = buildDependencyMap(statement, ctes);
|
|
30
|
+
const rootDependencies = collectRootDependencies(statement, cteNames);
|
|
31
|
+
return {
|
|
32
|
+
statement,
|
|
33
|
+
ctes,
|
|
34
|
+
cteNames,
|
|
35
|
+
dependencyMap,
|
|
36
|
+
rootDependencies
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function detectQueryType(statement) {
|
|
40
|
+
if (statement instanceof rawsql_ts_1.InsertQuery) {
|
|
41
|
+
return 'INSERT';
|
|
42
|
+
}
|
|
43
|
+
if (statement instanceof rawsql_ts_1.UpdateQuery) {
|
|
44
|
+
return 'UPDATE';
|
|
45
|
+
}
|
|
46
|
+
if (statement instanceof rawsql_ts_1.DeleteQuery) {
|
|
47
|
+
return 'DELETE';
|
|
48
|
+
}
|
|
49
|
+
return 'SELECT';
|
|
50
|
+
}
|
|
51
|
+
function buildDependencyMap(statement, ctes) {
|
|
52
|
+
const cteNames = ctes.map((cte) => cte.aliasExpression.table.name);
|
|
53
|
+
if (statement instanceof rawsql_ts_1.SimpleSelectQuery) {
|
|
54
|
+
const analyzer = new rawsql_ts_1.CTEDependencyAnalyzer();
|
|
55
|
+
analyzer.analyzeDependencies(statement);
|
|
56
|
+
return new Map(cteNames.map((name) => [name, analyzer.getDependencies(name).filter((dependency) => cteNames.includes(dependency))]));
|
|
57
|
+
}
|
|
58
|
+
const collector = new rawsql_ts_1.CTETableReferenceCollector();
|
|
59
|
+
const cteNameSet = new Set(cteNames);
|
|
60
|
+
return new Map(ctes.map((cte) => {
|
|
61
|
+
const references = collector.collect(cte.query).map((source) => source.table.name);
|
|
62
|
+
const dependencies = Array.from(new Set(references.filter((reference) => cteNameSet.has(reference) && reference !== cte.aliasExpression.table.name)));
|
|
63
|
+
return [cte.aliasExpression.table.name, dependencies];
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
function collectRootDependencies(statement, cteNames) {
|
|
67
|
+
const cteNameSet = new Set(cteNames);
|
|
68
|
+
if (isSelectStatement(statement)) {
|
|
69
|
+
return collectReferencedCteNames(cteNameSet, statement);
|
|
70
|
+
}
|
|
71
|
+
if (statement instanceof rawsql_ts_1.InsertQuery) {
|
|
72
|
+
return statement.selectQuery
|
|
73
|
+
? collectReferencedCteNames(cteNameSet, assertSelectStatement(statement.selectQuery))
|
|
74
|
+
: [];
|
|
75
|
+
}
|
|
76
|
+
if (statement instanceof rawsql_ts_1.UpdateQuery) {
|
|
77
|
+
return collectReferencedCteNames(cteNameSet, statement.updateClause.source, statement.fromClause, statement.whereClause);
|
|
78
|
+
}
|
|
79
|
+
return collectReferencedCteNames(cteNameSet, statement.deleteClause.source, statement.usingClause, statement.whereClause);
|
|
80
|
+
}
|
|
81
|
+
function collectReachableCtes(rootDependencies, dependencyMap, stopSet = new Set()) {
|
|
82
|
+
var _a;
|
|
83
|
+
const visited = new Set();
|
|
84
|
+
const queue = [...rootDependencies];
|
|
85
|
+
while (queue.length > 0) {
|
|
86
|
+
const current = queue.shift();
|
|
87
|
+
if (!current || visited.has(current)) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
visited.add(current);
|
|
91
|
+
// Treat already-satisfied CTEs as traversal stops so downstream slices stay minimal.
|
|
92
|
+
if (stopSet.has(current)) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
for (const dependency of (_a = dependencyMap.get(current)) !== null && _a !== void 0 ? _a : []) {
|
|
96
|
+
if (!visited.has(dependency)) {
|
|
97
|
+
queue.push(dependency);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return visited;
|
|
102
|
+
}
|
|
103
|
+
function collectDependencyClosure(targetName, dependencyMap, stopSet = new Set()) {
|
|
104
|
+
const ordered = [];
|
|
105
|
+
const visiting = new Set();
|
|
106
|
+
const visited = new Set();
|
|
107
|
+
function visit(name) {
|
|
108
|
+
var _a;
|
|
109
|
+
if (visited.has(name) || visiting.has(name)) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
visiting.add(name);
|
|
113
|
+
// Preserve the stop node itself, but do not recurse into its upstream dependencies.
|
|
114
|
+
if (!stopSet.has(name)) {
|
|
115
|
+
for (const dependency of (_a = dependencyMap.get(name)) !== null && _a !== void 0 ? _a : []) {
|
|
116
|
+
visit(dependency);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
visiting.delete(name);
|
|
120
|
+
visited.add(name);
|
|
121
|
+
ordered.push(name);
|
|
122
|
+
}
|
|
123
|
+
visit(targetName);
|
|
124
|
+
return ordered;
|
|
125
|
+
}
|
|
126
|
+
function collectDirectSources(statement) {
|
|
127
|
+
var _a, _b;
|
|
128
|
+
if (isSelectStatement(statement)) {
|
|
129
|
+
return collectSelectSources(statement);
|
|
130
|
+
}
|
|
131
|
+
if (statement instanceof rawsql_ts_1.InsertQuery) {
|
|
132
|
+
return statement.selectQuery
|
|
133
|
+
? collectDirectSources(assertSelectStatement(statement.selectQuery))
|
|
134
|
+
: [statement.insertClause.source];
|
|
135
|
+
}
|
|
136
|
+
if (statement instanceof rawsql_ts_1.UpdateQuery) {
|
|
137
|
+
return [statement.updateClause.source, ...collectSourcesFromFromClause(statement.fromClause)];
|
|
138
|
+
}
|
|
139
|
+
return [statement.deleteClause.source, ...((_b = (_a = statement.usingClause) === null || _a === void 0 ? void 0 : _a.getSources()) !== null && _b !== void 0 ? _b : [])];
|
|
140
|
+
}
|
|
141
|
+
function isSelectStatement(statement) {
|
|
142
|
+
return statement instanceof rawsql_ts_1.SimpleSelectQuery || statement instanceof rawsql_ts_1.BinarySelectQuery || statement instanceof rawsql_ts_1.ValuesQuery;
|
|
143
|
+
}
|
|
144
|
+
function collectReferencedCteNames(cteNameSet, ...components) {
|
|
145
|
+
const collector = new rawsql_ts_1.CTETableReferenceCollector();
|
|
146
|
+
const names = components.flatMap((component) => {
|
|
147
|
+
if (!component) {
|
|
148
|
+
return [];
|
|
149
|
+
}
|
|
150
|
+
return collector.collect(component).map((source) => source.table.name);
|
|
151
|
+
});
|
|
152
|
+
return uniquePreservingOrder(names.filter((name) => cteNameSet.has(name)));
|
|
153
|
+
}
|
|
154
|
+
function uniquePreservingOrder(values) {
|
|
155
|
+
const seen = new Set();
|
|
156
|
+
const result = [];
|
|
157
|
+
for (const value of values) {
|
|
158
|
+
if (seen.has(value)) {
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
seen.add(value);
|
|
162
|
+
result.push(value);
|
|
163
|
+
}
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
function collectSelectSources(statement) {
|
|
167
|
+
if (statement instanceof rawsql_ts_1.BinarySelectQuery) {
|
|
168
|
+
return [
|
|
169
|
+
...collectSelectSources(assertSelectStatement(statement.left)),
|
|
170
|
+
...collectSelectSources(assertSelectStatement(statement.right))
|
|
171
|
+
];
|
|
172
|
+
}
|
|
173
|
+
if (statement instanceof rawsql_ts_1.ValuesQuery) {
|
|
174
|
+
return [];
|
|
175
|
+
}
|
|
176
|
+
return collectSourcesFromFromClause(statement.fromClause);
|
|
177
|
+
}
|
|
178
|
+
function assertSelectStatement(statement) {
|
|
179
|
+
if (statement instanceof rawsql_ts_1.SimpleSelectQuery ||
|
|
180
|
+
statement instanceof rawsql_ts_1.BinarySelectQuery ||
|
|
181
|
+
statement instanceof rawsql_ts_1.ValuesQuery) {
|
|
182
|
+
return statement;
|
|
183
|
+
}
|
|
184
|
+
throw new Error('Expected a SELECT-compatible statement.');
|
|
185
|
+
}
|
|
186
|
+
function collectSourcesFromFromClause(fromClause) {
|
|
187
|
+
if (!fromClause) {
|
|
188
|
+
return [];
|
|
189
|
+
}
|
|
190
|
+
return fromClause.getSources();
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=analysis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analysis.js","sourceRoot":"","sources":["../../src/query/analysis.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CatalogStatement } from '../utils/sqlCatalogStatements';
|
|
2
|
+
import type { QueryUsageAnalyzerResult, QueryUsageMode, QueryUsageTarget } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Analyze column usage for a single statement using AST traversal with explicit uncertainty labeling.
|
|
5
|
+
*/
|
|
6
|
+
export declare function analyzeColumnUsage(params: {
|
|
7
|
+
statement: CatalogStatement;
|
|
8
|
+
target: QueryUsageTarget;
|
|
9
|
+
mode: QueryUsageMode;
|
|
10
|
+
}): QueryUsageAnalyzerResult;
|
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.analyzeColumnUsage = analyzeColumnUsage;
|
|
4
|
+
const rawsql_ts_1 = require("rawsql-ts");
|
|
5
|
+
const location_1 = require("./location");
|
|
6
|
+
/**
|
|
7
|
+
* Analyze column usage for a single statement using AST traversal with explicit uncertainty labeling.
|
|
8
|
+
*/
|
|
9
|
+
function analyzeColumnUsage(params) {
|
|
10
|
+
let parsed;
|
|
11
|
+
try {
|
|
12
|
+
parsed = rawsql_ts_1.SqlParser.parse(params.statement.statementText);
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
return {
|
|
16
|
+
matches: [],
|
|
17
|
+
warnings: [
|
|
18
|
+
{
|
|
19
|
+
catalog_id: params.statement.catalogId,
|
|
20
|
+
query_id: params.statement.queryId,
|
|
21
|
+
sql_file: params.statement.sqlFile,
|
|
22
|
+
code: 'parse-failed',
|
|
23
|
+
message: error instanceof Error ? error.message : String(error)
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const occurrences = collectColumnOccurrences(parsed, params.target, params.mode);
|
|
29
|
+
return {
|
|
30
|
+
matches: occurrences.map((occurrence) => toColumnMatch(params.statement, occurrence)),
|
|
31
|
+
warnings: []
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function collectColumnOccurrences(parsed, target, mode, context = {}) {
|
|
35
|
+
var _a, _b, _c, _d;
|
|
36
|
+
if (parsed instanceof rawsql_ts_1.SimpleSelectQuery) {
|
|
37
|
+
const matches = [];
|
|
38
|
+
if (parsed.withClause) {
|
|
39
|
+
for (const table of parsed.withClause.tables) {
|
|
40
|
+
matches.push(...collectColumnOccurrences(table.query, target, mode, { inCte: true }));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const scope = buildScope((_a = parsed.fromClause) !== null && _a !== void 0 ? _a : undefined, target, mode);
|
|
44
|
+
if (parsed.fromClause) {
|
|
45
|
+
matches.push(...collectNestedSourceQueryMatches(parsed.fromClause.source, target, mode));
|
|
46
|
+
}
|
|
47
|
+
for (const item of parsed.selectClause.items) {
|
|
48
|
+
matches.push(...collectSelectItemMatches(item, target, mode, scope, context));
|
|
49
|
+
}
|
|
50
|
+
if (parsed.whereClause) {
|
|
51
|
+
matches.push(...collectExpressionMatches(parsed.whereClause.condition, target, mode, scope, context, 'where', []));
|
|
52
|
+
}
|
|
53
|
+
if (parsed.groupByClause) {
|
|
54
|
+
for (const group of parsed.groupByClause.grouping) {
|
|
55
|
+
matches.push(...collectExpressionMatches(group, target, mode, scope, context, 'group-by', []));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (parsed.havingClause) {
|
|
59
|
+
matches.push(...collectExpressionMatches(parsed.havingClause.condition, target, mode, scope, context, 'having', []));
|
|
60
|
+
}
|
|
61
|
+
if (parsed.orderByClause) {
|
|
62
|
+
for (const order of parsed.orderByClause.order) {
|
|
63
|
+
matches.push(...collectExpressionMatches(order instanceof rawsql_ts_1.OrderByItem ? order.value : order, target, mode, scope, context, 'order-by', []));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if ((_b = parsed.fromClause) === null || _b === void 0 ? void 0 : _b.joins) {
|
|
67
|
+
for (const join of parsed.fromClause.joins) {
|
|
68
|
+
matches.push(...collectNestedSourceQueryMatches(join.source, target, mode));
|
|
69
|
+
matches.push(...collectJoinMatches(join, target, mode, scope, context));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return matches;
|
|
73
|
+
}
|
|
74
|
+
if (parsed instanceof rawsql_ts_1.UpdateQuery) {
|
|
75
|
+
const matches = [];
|
|
76
|
+
if (parsed.withClause) {
|
|
77
|
+
for (const table of parsed.withClause.tables) {
|
|
78
|
+
matches.push(...collectColumnOccurrences(table.query, target, mode, { inCte: true }));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const scope = buildScope((_c = parsed.fromClause) !== null && _c !== void 0 ? _c : undefined, target, mode, parsed.updateClause.source);
|
|
82
|
+
for (const item of parsed.setClause.items) {
|
|
83
|
+
if (matchesColumnName(item.column.name, target)) {
|
|
84
|
+
matches.push(buildExplicitOccurrence(item.column.name, mode, 'update-set', [], context));
|
|
85
|
+
}
|
|
86
|
+
matches.push(...collectExpressionMatches(item.value, target, mode, scope, context, 'update-set', []));
|
|
87
|
+
}
|
|
88
|
+
if (parsed.whereClause) {
|
|
89
|
+
matches.push(...collectExpressionMatches(parsed.whereClause.condition, target, mode, scope, context, 'where', []));
|
|
90
|
+
}
|
|
91
|
+
if (parsed.returningClause) {
|
|
92
|
+
for (const item of parsed.returningClause.items) {
|
|
93
|
+
matches.push(...collectSelectItemMatches(item, target, mode, scope, context, 'returning'));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if ((_d = parsed.fromClause) === null || _d === void 0 ? void 0 : _d.joins) {
|
|
97
|
+
for (const join of parsed.fromClause.joins) {
|
|
98
|
+
matches.push(...collectJoinMatches(join, target, mode, scope, context));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return matches;
|
|
102
|
+
}
|
|
103
|
+
if (parsed instanceof rawsql_ts_1.DeleteQuery) {
|
|
104
|
+
const matches = [];
|
|
105
|
+
if (parsed.withClause) {
|
|
106
|
+
for (const table of parsed.withClause.tables) {
|
|
107
|
+
matches.push(...collectColumnOccurrences(table.query, target, mode, { inCte: true }));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const scope = buildScope(undefined, target, mode, parsed.deleteClause.source);
|
|
111
|
+
if (parsed.whereClause) {
|
|
112
|
+
matches.push(...collectExpressionMatches(parsed.whereClause.condition, target, mode, scope, context, 'where', []));
|
|
113
|
+
}
|
|
114
|
+
if (parsed.returningClause) {
|
|
115
|
+
for (const item of parsed.returningClause.items) {
|
|
116
|
+
matches.push(...collectSelectItemMatches(item, target, mode, scope, context, 'returning'));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return matches;
|
|
120
|
+
}
|
|
121
|
+
if (parsed instanceof rawsql_ts_1.InsertQuery) {
|
|
122
|
+
const scope = buildScope(undefined, target, mode, parsed.insertClause.source);
|
|
123
|
+
const matches = [];
|
|
124
|
+
if (parsed.insertClause.columns) {
|
|
125
|
+
for (const column of parsed.insertClause.columns) {
|
|
126
|
+
if (matchesColumnName(column.name, target)) {
|
|
127
|
+
matches.push(buildExplicitOccurrence(column.name, mode, 'insert-column', [], context));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (parsed.selectQuery) {
|
|
132
|
+
matches.push(...collectColumnOccurrences(parsed.selectQuery, target, mode, { inSubquery: true }));
|
|
133
|
+
}
|
|
134
|
+
if (parsed.returningClause) {
|
|
135
|
+
for (const item of parsed.returningClause.items) {
|
|
136
|
+
matches.push(...collectSelectItemMatches(item, target, mode, scope, context, 'returning'));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return matches;
|
|
140
|
+
}
|
|
141
|
+
return [];
|
|
142
|
+
}
|
|
143
|
+
function buildScope(fromClause, target, mode, primarySource) {
|
|
144
|
+
const scope = {
|
|
145
|
+
targetTablePresent: mode === 'any-schema-any-table',
|
|
146
|
+
aliases: new Set()
|
|
147
|
+
};
|
|
148
|
+
if (primarySource) {
|
|
149
|
+
collectScopeFromSource(primarySource, target, mode, scope);
|
|
150
|
+
}
|
|
151
|
+
if (fromClause) {
|
|
152
|
+
collectScopeFromSource(fromClause.source, target, mode, scope);
|
|
153
|
+
if (fromClause.joins) {
|
|
154
|
+
for (const join of fromClause.joins) {
|
|
155
|
+
collectScopeFromSource(join.source, target, mode, scope);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return scope;
|
|
160
|
+
}
|
|
161
|
+
function collectScopeFromSource(source, target, mode, scope) {
|
|
162
|
+
var _a;
|
|
163
|
+
if (!(source.datasource instanceof rawsql_ts_1.TableSource)) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const schema = ((_a = source.datasource.namespaces) === null || _a === void 0 ? void 0 : _a.map((value) => value.name).join('.')) || undefined;
|
|
167
|
+
const table = source.datasource.table.name;
|
|
168
|
+
const matches = mode === 'exact'
|
|
169
|
+
? target.schema !== undefined && target.table !== undefined && `${schema}.${table}`.toLowerCase() === `${target.schema}.${target.table}`.toLowerCase()
|
|
170
|
+
: mode === 'any-schema'
|
|
171
|
+
? target.table !== undefined && table.toLowerCase() === target.table.toLowerCase()
|
|
172
|
+
: true;
|
|
173
|
+
if (!matches) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
scope.targetTablePresent = true;
|
|
177
|
+
if (source.aliasExpression) {
|
|
178
|
+
scope.aliases.add(source.aliasExpression.table.name.toLowerCase());
|
|
179
|
+
}
|
|
180
|
+
scope.aliases.add(table.toLowerCase());
|
|
181
|
+
if (schema) {
|
|
182
|
+
scope.aliases.add(`${schema}.${table}`.toLowerCase());
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function collectSelectItemMatches(item, target, mode, scope, context, rootUsageKind = 'select') {
|
|
186
|
+
return collectExpressionMatches(item.value, target, mode, scope, context, rootUsageKind, ['projection']);
|
|
187
|
+
}
|
|
188
|
+
function collectJoinMatches(join, target, mode, scope, context) {
|
|
189
|
+
if (!join.condition) {
|
|
190
|
+
return [];
|
|
191
|
+
}
|
|
192
|
+
if (join.condition instanceof rawsql_ts_1.JoinOnClause) {
|
|
193
|
+
return collectExpressionMatches(join.condition.condition, target, mode, scope, context, 'join-on', []);
|
|
194
|
+
}
|
|
195
|
+
if (join.condition instanceof rawsql_ts_1.JoinUsingClause) {
|
|
196
|
+
return collectExpressionMatches(join.condition.condition, target, mode, scope, context, 'join-using', []);
|
|
197
|
+
}
|
|
198
|
+
return [];
|
|
199
|
+
}
|
|
200
|
+
function collectNestedSourceQueryMatches(source, target, mode) {
|
|
201
|
+
let current = source.datasource;
|
|
202
|
+
while (current instanceof rawsql_ts_1.ParenSource) {
|
|
203
|
+
current = current.source;
|
|
204
|
+
}
|
|
205
|
+
if (current instanceof rawsql_ts_1.SubQuerySource) {
|
|
206
|
+
return collectColumnOccurrences(current.query, target, mode, { inSubquery: true });
|
|
207
|
+
}
|
|
208
|
+
return [];
|
|
209
|
+
}
|
|
210
|
+
function collectExpressionMatches(value, target, mode, scope, context, rootUsageKind, exprHints) {
|
|
211
|
+
if (value instanceof rawsql_ts_1.ColumnReference) {
|
|
212
|
+
return collectColumnReferenceMatch(value, target, mode, scope, context, rootUsageKind, exprHints);
|
|
213
|
+
}
|
|
214
|
+
if (value instanceof rawsql_ts_1.BinaryExpression) {
|
|
215
|
+
return [
|
|
216
|
+
...collectExpressionMatches(value.left, target, mode, scope, context, rootUsageKind, [...exprHints, 'comparison']),
|
|
217
|
+
...collectExpressionMatches(value.right, target, mode, scope, context, rootUsageKind, [...exprHints, 'comparison'])
|
|
218
|
+
];
|
|
219
|
+
}
|
|
220
|
+
if (value instanceof rawsql_ts_1.UnaryExpression) {
|
|
221
|
+
return collectExpressionMatches(value.expression, target, mode, scope, context, rootUsageKind, exprHints);
|
|
222
|
+
}
|
|
223
|
+
if (value instanceof rawsql_ts_1.FunctionCall) {
|
|
224
|
+
const nestedHints = [...exprHints, 'function'];
|
|
225
|
+
const functionName = value.name instanceof rawsql_ts_1.IdentifierString ? value.name.name : value.name.value;
|
|
226
|
+
if (['count', 'sum', 'avg', 'min', 'max'].includes(functionName.toLowerCase())) {
|
|
227
|
+
nestedHints.push('aggregate');
|
|
228
|
+
}
|
|
229
|
+
const matches = [];
|
|
230
|
+
if (value.argument) {
|
|
231
|
+
matches.push(...collectExpressionMatches(value.argument, target, mode, scope, context, rootUsageKind, nestedHints));
|
|
232
|
+
}
|
|
233
|
+
if (value.filterCondition) {
|
|
234
|
+
matches.push(...collectExpressionMatches(value.filterCondition, target, mode, scope, context, rootUsageKind, nestedHints));
|
|
235
|
+
}
|
|
236
|
+
if (value.internalOrderBy) {
|
|
237
|
+
for (const order of value.internalOrderBy.order) {
|
|
238
|
+
matches.push(...collectExpressionMatches(order instanceof rawsql_ts_1.OrderByItem ? order.value : order, target, mode, scope, context, rootUsageKind, nestedHints));
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return matches;
|
|
242
|
+
}
|
|
243
|
+
if (value instanceof rawsql_ts_1.CastExpression) {
|
|
244
|
+
return collectExpressionMatches(value.input, target, mode, scope, context, rootUsageKind, [...exprHints, 'cast']);
|
|
245
|
+
}
|
|
246
|
+
if (value instanceof rawsql_ts_1.ParenExpression) {
|
|
247
|
+
return collectExpressionMatches(value.expression, target, mode, scope, context, rootUsageKind, exprHints);
|
|
248
|
+
}
|
|
249
|
+
if (value instanceof rawsql_ts_1.InlineQuery) {
|
|
250
|
+
return collectColumnOccurrences(value.selectQuery, target, mode, { inSubquery: true });
|
|
251
|
+
}
|
|
252
|
+
if (value instanceof rawsql_ts_1.ArrayQueryExpression) {
|
|
253
|
+
return collectColumnOccurrences(value.query, target, mode, { inSubquery: true });
|
|
254
|
+
}
|
|
255
|
+
if (value instanceof rawsql_ts_1.ArrayExpression) {
|
|
256
|
+
return collectExpressionMatches(value.expression, target, mode, scope, context, rootUsageKind, exprHints);
|
|
257
|
+
}
|
|
258
|
+
if (value instanceof rawsql_ts_1.ArraySliceExpression) {
|
|
259
|
+
return [
|
|
260
|
+
...collectExpressionMatches(value.array, target, mode, scope, context, rootUsageKind, exprHints),
|
|
261
|
+
...(value.startIndex ? collectExpressionMatches(value.startIndex, target, mode, scope, context, rootUsageKind, exprHints) : []),
|
|
262
|
+
...(value.endIndex ? collectExpressionMatches(value.endIndex, target, mode, scope, context, rootUsageKind, exprHints) : [])
|
|
263
|
+
];
|
|
264
|
+
}
|
|
265
|
+
if (value instanceof rawsql_ts_1.ArrayIndexExpression) {
|
|
266
|
+
return [
|
|
267
|
+
...collectExpressionMatches(value.array, target, mode, scope, context, rootUsageKind, exprHints),
|
|
268
|
+
...collectExpressionMatches(value.index, target, mode, scope, context, rootUsageKind, exprHints)
|
|
269
|
+
];
|
|
270
|
+
}
|
|
271
|
+
if (value instanceof rawsql_ts_1.ValueList) {
|
|
272
|
+
return value.values.flatMap((entry) => collectExpressionMatches(entry, target, mode, scope, context, rootUsageKind, exprHints));
|
|
273
|
+
}
|
|
274
|
+
if (value instanceof rawsql_ts_1.BetweenExpression) {
|
|
275
|
+
return [
|
|
276
|
+
...collectExpressionMatches(value.expression, target, mode, scope, context, rootUsageKind, [...exprHints, 'comparison']),
|
|
277
|
+
...collectExpressionMatches(value.lower, target, mode, scope, context, rootUsageKind, [...exprHints, 'comparison']),
|
|
278
|
+
...collectExpressionMatches(value.upper, target, mode, scope, context, rootUsageKind, [...exprHints, 'comparison'])
|
|
279
|
+
];
|
|
280
|
+
}
|
|
281
|
+
if (value instanceof rawsql_ts_1.CaseExpression) {
|
|
282
|
+
return [
|
|
283
|
+
...(value.condition ? collectExpressionMatches(value.condition, target, mode, scope, context, rootUsageKind, exprHints) : []),
|
|
284
|
+
...collectExpressionMatches(value.switchCase, target, mode, scope, context, rootUsageKind, exprHints)
|
|
285
|
+
];
|
|
286
|
+
}
|
|
287
|
+
if (value instanceof rawsql_ts_1.SwitchCaseArgument) {
|
|
288
|
+
return [
|
|
289
|
+
...value.cases.flatMap((item) => collectExpressionMatches(item, target, mode, scope, context, rootUsageKind, exprHints)),
|
|
290
|
+
...(value.elseValue ? collectExpressionMatches(value.elseValue, target, mode, scope, context, rootUsageKind, exprHints) : [])
|
|
291
|
+
];
|
|
292
|
+
}
|
|
293
|
+
if (value instanceof rawsql_ts_1.CaseKeyValuePair) {
|
|
294
|
+
return [
|
|
295
|
+
...collectExpressionMatches(value.key, target, mode, scope, context, rootUsageKind, exprHints),
|
|
296
|
+
...collectExpressionMatches(value.value, target, mode, scope, context, rootUsageKind, exprHints)
|
|
297
|
+
];
|
|
298
|
+
}
|
|
299
|
+
if (value instanceof rawsql_ts_1.TupleExpression) {
|
|
300
|
+
return value.values.flatMap((entry) => collectExpressionMatches(entry, target, mode, scope, context, rootUsageKind, exprHints));
|
|
301
|
+
}
|
|
302
|
+
if (value instanceof rawsql_ts_1.StringSpecifierExpression || value instanceof rawsql_ts_1.IdentifierString || value instanceof rawsql_ts_1.RawString) {
|
|
303
|
+
return [];
|
|
304
|
+
}
|
|
305
|
+
return [];
|
|
306
|
+
}
|
|
307
|
+
function collectColumnReferenceMatch(value, target, mode, scope, context, rootUsageKind, exprHints) {
|
|
308
|
+
var _a;
|
|
309
|
+
const usageKind = context.inCte ? 'cte' : context.inSubquery ? 'subquery' : rootUsageKind;
|
|
310
|
+
const notes = new Set();
|
|
311
|
+
const hints = new Set(exprHints);
|
|
312
|
+
let confidence = mode === 'exact' ? 'high' : 'low';
|
|
313
|
+
let searchTerms = [];
|
|
314
|
+
const namespace = (_a = value.namespaces) === null || _a === void 0 ? void 0 : _a.map((entry) => entry.name).join('.').toLowerCase();
|
|
315
|
+
const columnName = value.column.name;
|
|
316
|
+
const wildcard = columnName === '*';
|
|
317
|
+
if (wildcard) {
|
|
318
|
+
hints.add('wildcard');
|
|
319
|
+
notes.add('wildcard-select');
|
|
320
|
+
confidence = 'low';
|
|
321
|
+
if (!scope.targetTablePresent) {
|
|
322
|
+
return [];
|
|
323
|
+
}
|
|
324
|
+
searchTerms = [namespace ? `${namespace}.*` : '*'];
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
if (!matchesColumnName(columnName, target)) {
|
|
328
|
+
return [];
|
|
329
|
+
}
|
|
330
|
+
if (usageKind === 'join-using') {
|
|
331
|
+
notes.add('join-using-column');
|
|
332
|
+
confidence = 'low';
|
|
333
|
+
}
|
|
334
|
+
if (!namespace) {
|
|
335
|
+
notes.add('unqualified-column');
|
|
336
|
+
confidence = 'low';
|
|
337
|
+
if (!scope.targetTablePresent && mode !== 'any-schema-any-table') {
|
|
338
|
+
return [];
|
|
339
|
+
}
|
|
340
|
+
searchTerms = [columnName];
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
const matchesNamespace = mode === 'any-schema-any-table' ||
|
|
344
|
+
scope.aliases.has(namespace) ||
|
|
345
|
+
(target.table ? namespace === target.table.toLowerCase() : false) ||
|
|
346
|
+
(target.schema && target.table ? namespace === `${target.schema}.${target.table}`.toLowerCase() : false);
|
|
347
|
+
if (!matchesNamespace) {
|
|
348
|
+
return [];
|
|
349
|
+
}
|
|
350
|
+
searchTerms = [`${namespace}.${columnName}`, columnName];
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
if (context.inSubquery && rootUsageKind === 'select') {
|
|
354
|
+
notes.add('subquery-projection');
|
|
355
|
+
}
|
|
356
|
+
if (context.inCte && rootUsageKind === 'select') {
|
|
357
|
+
notes.add('cte-projection');
|
|
358
|
+
}
|
|
359
|
+
if (mode !== 'exact') {
|
|
360
|
+
notes.add('relaxed-match-any-schema');
|
|
361
|
+
if (mode === 'any-schema-any-table') {
|
|
362
|
+
notes.add('relaxed-match-any-table');
|
|
363
|
+
}
|
|
364
|
+
confidence = 'low';
|
|
365
|
+
}
|
|
366
|
+
return [{
|
|
367
|
+
usageKind,
|
|
368
|
+
searchTerms,
|
|
369
|
+
confidence,
|
|
370
|
+
notes: Array.from(notes),
|
|
371
|
+
exprHints: Array.from(hints),
|
|
372
|
+
clauseAnchor: resolveClauseAnchor(usageKind)
|
|
373
|
+
}];
|
|
374
|
+
}
|
|
375
|
+
function buildExplicitOccurrence(columnName, mode, usageKind, exprHints, context) {
|
|
376
|
+
const notes = new Set();
|
|
377
|
+
if (mode !== 'exact') {
|
|
378
|
+
notes.add('relaxed-match-any-schema');
|
|
379
|
+
if (mode === 'any-schema-any-table') {
|
|
380
|
+
notes.add('relaxed-match-any-table');
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
return {
|
|
384
|
+
usageKind: context.inCte ? 'cte' : context.inSubquery ? 'subquery' : usageKind,
|
|
385
|
+
searchTerms: [columnName],
|
|
386
|
+
confidence: notes.size > 0 ? 'low' : 'high',
|
|
387
|
+
notes: Array.from(notes),
|
|
388
|
+
exprHints,
|
|
389
|
+
clauseAnchor: resolveClauseAnchor(context.inCte ? 'cte' : context.inSubquery ? 'subquery' : usageKind)
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
function matchesColumnName(columnName, target) {
|
|
393
|
+
return target.column !== undefined && columnName.toLowerCase() === target.column.toLowerCase();
|
|
394
|
+
}
|
|
395
|
+
function toColumnMatch(statement, occurrence) {
|
|
396
|
+
const located = (0, location_1.locateUsageText)({
|
|
397
|
+
statementText: statement.statementText,
|
|
398
|
+
statementStartOffsetInFile: statement.statementStartOffsetInFile,
|
|
399
|
+
candidates: occurrence.searchTerms,
|
|
400
|
+
clauseAnchor: occurrence.clauseAnchor
|
|
401
|
+
});
|
|
402
|
+
const notes = [...occurrence.notes];
|
|
403
|
+
let confidence = occurrence.confidence;
|
|
404
|
+
if (located.ambiguous && !notes.includes('ambiguous-multiple-occurrences')) {
|
|
405
|
+
notes.push('ambiguous-multiple-occurrences');
|
|
406
|
+
confidence = 'low';
|
|
407
|
+
}
|
|
408
|
+
return {
|
|
409
|
+
kind: 'detail',
|
|
410
|
+
catalog_id: statement.catalogId,
|
|
411
|
+
query_id: statement.queryId,
|
|
412
|
+
statement_fingerprint: statement.statementFingerprint,
|
|
413
|
+
sql_file: statement.sqlFile,
|
|
414
|
+
usage_kind: occurrence.usageKind,
|
|
415
|
+
exprHints: occurrence.exprHints.length > 0 ? occurrence.exprHints.sort() : undefined,
|
|
416
|
+
location: located.location,
|
|
417
|
+
snippet: located.snippet,
|
|
418
|
+
confidence,
|
|
419
|
+
notes: notes.sort(),
|
|
420
|
+
source: 'ast'
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
function resolveClauseAnchor(usageKind) {
|
|
424
|
+
switch (usageKind) {
|
|
425
|
+
case 'where':
|
|
426
|
+
return { kind: usageKind, tokens: ['WHERE'] };
|
|
427
|
+
case 'order-by':
|
|
428
|
+
return { kind: usageKind, tokens: ['ORDER', 'BY'] };
|
|
429
|
+
case 'group-by':
|
|
430
|
+
return { kind: usageKind, tokens: ['GROUP', 'BY'] };
|
|
431
|
+
case 'having':
|
|
432
|
+
return { kind: usageKind, tokens: ['HAVING'] };
|
|
433
|
+
case 'returning':
|
|
434
|
+
return { kind: usageKind, tokens: ['RETURNING'] };
|
|
435
|
+
case 'update-set':
|
|
436
|
+
return { kind: usageKind, tokens: ['SET'] };
|
|
437
|
+
case 'join-on':
|
|
438
|
+
return { kind: usageKind, tokens: ['ON'] };
|
|
439
|
+
case 'join-using':
|
|
440
|
+
return { kind: usageKind, tokens: ['USING'] };
|
|
441
|
+
case 'insert-column':
|
|
442
|
+
return { kind: usageKind, tokens: ['INSERT', 'INTO'] };
|
|
443
|
+
case 'select':
|
|
444
|
+
case 'subquery':
|
|
445
|
+
case 'cte':
|
|
446
|
+
case 'unknown':
|
|
447
|
+
default:
|
|
448
|
+
return { kind: usageKind, tokens: ['SELECT'] };
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
//# sourceMappingURL=analyzeColumnUsage.js.map
|