diff --git a/packages/cli/src/sql.test.ts b/packages/cli/src/sql.test.ts index b1c6041f..51cfe920 100644 --- a/packages/cli/src/sql.test.ts +++ b/packages/cli/src/sql.test.ts @@ -32,13 +32,8 @@ function makeIo(options: { isTTY?: boolean } = {}) { function makeSqlAnalysis(result: Awaited>): SqlAnalysisPort { return { - analyzeForFingerprint: vi.fn(async () => ({ - fingerprint: 'select-from-orders', - normalizedSql: 'select id, status from orders', - tablesTouched: ['orders'], - literalSlots: [], - })), - analyzeBatch: vi.fn(), + analyzeForFingerprint: vi.fn(), + analyzeBatch: vi.fn(async () => new Map([['cli-sql', { tablesTouched: ['orders'], columnsByClause: {} }]])), validateReadOnly: vi.fn(async () => result), }; } diff --git a/packages/cli/src/sql.ts b/packages/cli/src/sql.ts index e4b83c0f..1b15f92e 100644 --- a/packages/cli/src/sql.ts +++ b/packages/cli/src/sql.ts @@ -65,6 +65,19 @@ function queryVerb(sql: string): 'select' | 'explain' | 'show' | 'with' | 'other return 'other'; } +async function safeReferencedTableCount( + port: SqlAnalysisPort, + sql: string, + dialect: SqlAnalysisDialect, +): Promise { + try { + const results = await port.analyzeBatch([{ id: 'cli-sql', sql }], dialect); + return results.get('cli-sql')?.tablesTouched.length ?? 0; + } catch { + return 0; + } +} + function formatValue(value: unknown): string { if (value === null || value === undefined) return ''; if (typeof value === 'string') return value; @@ -157,7 +170,7 @@ export async function runKtxSql(args: KtxSqlArgs, io: KtxCliIo = process, deps: if (!validation.ok) { throw new Error(validation.error ?? 'SQL is not read-only.'); } - const analysis = await analysisPort.analyzeForFingerprint(args.sql, dialect); + const referencedTableCount = await safeReferencedTableCount(analysisPort, args.sql, dialect); const createScanConnector = deps.createScanConnector ?? createKtxCliScanConnector; let connector: KtxScanConnector | null = null; @@ -184,7 +197,7 @@ export async function runKtxSql(args: KtxSqlArgs, io: KtxCliIo = process, deps: driver, isDemoConnection: demoConnection, queryVerb: queryVerb(args.sql), - referencedTableCount: analysis.tablesTouched.length, + referencedTableCount, durationMs: Math.max(0, performance.now() - startedAt), outcome: 'ok', },