diff --git a/frontend/src/components/QueryEditor.external-sql-save.test.tsx b/frontend/src/components/QueryEditor.external-sql-save.test.tsx
index 99963ff..2548ee1 100644
--- a/frontend/src/components/QueryEditor.external-sql-save.test.tsx
+++ b/frontend/src/components/QueryEditor.external-sql-save.test.tsx
@@ -522,8 +522,20 @@ describe('QueryEditor external SQL save', () => {
backendApp.DBGetDatabases.mockResolvedValue({ success: true, data: [] });
backendApp.DBGetTables.mockResolvedValue({ success: true, data: [] });
backendApp.GenerateQueryID.mockResolvedValue('query-1');
- storeState.connections[0].config.type = 'mysql';
- storeState.connections[0].config.database = 'main';
+ storeState.connections = [
+ {
+ id: 'conn-1',
+ name: 'local',
+ config: {
+ type: 'mysql',
+ host: '127.0.0.1',
+ port: 3306,
+ user: 'root',
+ password: '',
+ database: 'main',
+ },
+ },
+ ];
storeState.appearance.uiVersion = 'legacy';
autoFetchState.visible = false;
dataGridState.latestProps = null;
@@ -1508,6 +1520,79 @@ describe('QueryEditor external SQL save', () => {
);
});
+ it('formats postgres cast syntax after switching to another query tab connection', async () => {
+ let renderer!: ReactTestRenderer;
+ storeState.connections = [
+ {
+ id: 'conn-1',
+ name: 'mysql-local',
+ config: {
+ type: 'mysql',
+ host: '127.0.0.1',
+ port: 3306,
+ user: 'root',
+ password: '',
+ database: 'main',
+ },
+ },
+ {
+ id: 'conn-2',
+ name: 'pg-local',
+ config: {
+ type: 'postgres',
+ host: '127.0.0.1',
+ port: 5432,
+ user: 'postgres',
+ password: '',
+ database: 'main',
+ },
+ },
+ ];
+ const pgSql = [
+ 'SELECT',
+ ' *,',
+ ' is_del = 0',
+ 'FROM',
+ ' wm_stock',
+ 'WHERE',
+ ' 1 = 1',
+ ' AND is_del = 0',
+ " and create_date > '2025-06-25'::date;",
+ ].join('\n');
+
+ await act(async () => {
+ renderer = create();
+ });
+
+ await act(async () => {
+ renderer.update(
+ ,
+ );
+ });
+
+ const formatButton = findButton(renderer, '美化');
+ await act(async () => {
+ await formatButton.props.onClick();
+ });
+
+ expect(messageApi.error).not.toHaveBeenCalled();
+ expect(editorState.editor.executeEdits).toHaveBeenCalledWith(
+ 'gonavi-format-sql',
+ expect.arrayContaining([
+ expect.objectContaining({
+ text: expect.stringContaining("'2025-06-25'::date;"),
+ }),
+ ]),
+ );
+ });
+
it('shows object info via editor ctrl+q action', async () => {
editorState.value = 'select users.id from users';
autoFetchState.visible = true;
diff --git a/frontend/src/components/QueryEditor.tsx b/frontend/src/components/QueryEditor.tsx
index 7385696..c2dac12 100644
--- a/frontend/src/components/QueryEditor.tsx
+++ b/frontend/src/components/QueryEditor.tsx
@@ -2047,6 +2047,19 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
currentDbRef.current = currentDb;
}, [currentDb]);
+ useEffect(() => {
+ const nextConnectionId = String(tab.connectionId || '').trim();
+ const nextDb = String(tab.dbName || '').trim();
+ if (nextConnectionId !== currentConnectionIdRef.current) {
+ currentConnectionIdRef.current = nextConnectionId;
+ setCurrentConnectionId(nextConnectionId);
+ }
+ if (nextDb !== currentDbRef.current) {
+ currentDbRef.current = nextDb;
+ setCurrentDb(nextDb);
+ }
+ }, [tab.id, tab.connectionId, tab.dbName]);
+
useEffect(() => {
if (isExternalSQLFileTab) return;
const currentDraft = getQueryTabDraft(tab.id, query);
@@ -3704,7 +3717,13 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
const handleFormat = () => {
try {
- const formatterLanguage = resolveQueryEditorFormatterLanguage(connections.find(c => c.id === currentConnectionId));
+ const activeConnectionId = String(currentConnectionIdRef.current || '').trim();
+ const tabConnectionId = String(tab.connectionId || '').trim();
+ const conn = connectionsRef.current.find(c => c.id === activeConnectionId)
+ || (tabConnectionId && tabConnectionId !== activeConnectionId
+ ? connectionsRef.current.find(c => c.id === tabConnectionId)
+ : undefined);
+ const formatterLanguage = resolveQueryEditorFormatterLanguage(conn);
const formatted = format(getCurrentQuery(), { language: formatterLanguage, keywordCase: sqlFormatOptions.keywordCase });
const editor = editorRef.current;
const monaco = monacoRef.current;