🐛 fix(sql-parser): 修复尾随注释导致事务与只读判定异常

- 过滤分号后的纯注释语句并保留数据库可执行版本注释
- 前后端按数据库方言统一处理双横线、井号与块注释
- 修复事务选择、只读保护、SQL 审计及 AI 风险分析误判
- 补充流式 SQL、事务执行与方言解析回归测试
This commit is contained in:
Syngnat
2026-07-13 12:52:56 +08:00
parent 00473e7ac0
commit 1ae2b74279
21 changed files with 559 additions and 72 deletions

View File

@@ -7495,6 +7495,45 @@ describe('QueryEditor external SQL save', () => {
expect(textContent(renderer!.root)).not.toContain('未提交');
});
it('keeps DML with a trailing line comment in a pending managed transaction', async () => {
backendApp.DBQueryMultiTransactional.mockResolvedValueOnce({
success: true,
transactionId: 'tx-comment',
transactionPending: true,
data: [
{ columns: ['affectedRows'], rows: [{ affectedRows: 1 }], statementIndex: 1 },
],
});
let renderer!: ReactTestRenderer;
await act(async () => {
renderer = create(<QueryEditor tab={createTab({
query: 'DELETE FROM users WHERE id = 1; -- keep this operation pending',
})} />);
});
await act(async () => {
await findButton(renderer!, '运行').props.onClick();
});
await act(async () => {
await Promise.resolve();
await Promise.resolve();
});
expect(backendApp.DBQueryMultiTransactional).toHaveBeenCalledWith(
expect.anything(),
'main',
'DELETE FROM users WHERE id = 1',
'query-1',
);
expect(backendApp.DBQueryMulti).not.toHaveBeenCalled();
expect(storeState.sqlEditorPendingTransactions['tab-1']).toMatchObject({
id: 'tx-comment',
dbType: 'mysql',
statements: ['DELETE FROM users WHERE id = 1'],
});
});
it('keeps TDengine insert on the regular query path because it has no managed transaction support', async () => {
storeState.connections[0].config.type = 'tdengine';
backendApp.DBQueryMulti.mockResolvedValueOnce({