From ed4a7b96d45410110316e382a613e4ae157a0884 Mon Sep 17 00:00:00 2001 From: tianqijiuyun-latiao <69459608+tianqijiuyun-latiao@users.noreply.github.com> Date: Fri, 27 Mar 2026 18:39:09 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix(query):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=8D=83=E4=B8=87=E7=BA=A7=E8=A1=A8=E6=9F=A5=E8=AF=A2=E8=B6=85?= =?UTF-8?q?=E6=97=B6=E3=80=81=E8=A1=A8=E5=A4=B4=E5=A4=87=E6=B3=A8=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E4=B8=8D=E6=98=BE=E7=A4=BA=E5=8F=8Adatetime=20INSERT?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E9=97=AE=E9=A2=98=20refs=20#307?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - QueryEditor: SQL编辑器查询 timeout 下限设为 120s,防止大表全量查询被 30s 超时取消 - QueryEditor: 放宽表名提取正则,支持 SELECT col1,col2 FROM table 形式,修复表头备注/类型不显示 - DataGrid: handleCopyInsert 对 datetime 值调用 normalizeDateTimeString,消除 RFC3339 格式中的 T 和时区后缀 --- frontend/src/components/DataGrid.tsx | 3 ++- frontend/src/components/QueryEditor.tsx | 15 ++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/frontend/src/components/DataGrid.tsx b/frontend/src/components/DataGrid.tsx index 0ec7de6..ab5f5d6 100644 --- a/frontend/src/components/DataGrid.tsx +++ b/frontend/src/components/DataGrid.tsx @@ -3504,7 +3504,8 @@ const DataGrid: React.FC = ({ const values = orderedCols.map(c => { const v = r[c]; if (v === null || v === undefined) return 'NULL'; - const escaped = String(v).replace(/'/g, "''"); + const str = typeof v === 'string' ? normalizeDateTimeString(v) : String(v); + const escaped = str.replace(/'/g, "''"); return `'${escaped}'`; }); const targetTable = tableName || 'table'; diff --git a/frontend/src/components/QueryEditor.tsx b/frontend/src/components/QueryEditor.tsx index 7d2fbe5..fbc0b52 100644 --- a/frontend/src/components/QueryEditor.tsx +++ b/frontend/src/components/QueryEditor.tsx @@ -1586,13 +1586,14 @@ const QueryEditor: React.FC<{ tab: TabData }> = ({ tab }) => { return; } - const config = { - ...conn.config, + const config = { + ...conn.config, port: Number(conn.config.port), password: conn.config.password || "", database: conn.config.database || "", useSSH: conn.config.useSSH || false, - ssh: conn.config.ssh || { host: "", port: 22, user: "", password: "", keyPath: "" } + ssh: conn.config.ssh || { host: "", port: 22, user: "", password: "", keyPath: "" }, + timeout: Math.max(Number(conn.config.timeout) || 30, 120), }; try { @@ -1842,8 +1843,12 @@ const QueryEditor: React.FC<{ tab: TabData }> = ({ tab }) => { let simpleTableName: string | undefined = undefined; if (rawStatement) { - // 支持多行 SQL:SELECT * FROM [schema.]table [WHERE...] [ORDER BY...] [LIMIT...] 等 - const tableMatch = rawStatement.match(/^\s*SELECT\s+\*\s+FROM\s+(?:[\w`"]+\.)?[`"]?(\w+)[`"]?\s*(?:$|[\s;])/im); + // 支持多行 SQL:SELECT [cols] FROM [schema.]table [WHERE...] [ORDER BY...] [LIMIT...] 等 + // JOIN 查询表名歧义,不提取 + const hasJoin = /\bJOIN\b/i.test(rawStatement); + const tableMatch = !hasJoin + ? rawStatement.match(/^\s*SELECT\s+.+?\s+FROM\s+(?:[\w`"\[\].]+\.)?[`"\[]?(\w+)[`"\]]?\s*(?:$|[\s;])/im) + : null; if (tableMatch) { simpleTableName = tableMatch[1]; if (!forceReadOnlyResult) {