合并查询的预览不再被标成「查询已达行数上限」:合并结果没有截断、只是预览存了前几行时记为「此处仅为预览」,表格脚注写「显示前 5 / 6 行」;只有合并结果本身超过上限才说截断

This commit is contained in:
ThearchyHelios
2026-10-04 02:18:32 +08:00
parent 0c65b4bea6
commit adcde155e1
4 changed files with 21 additions and 5 deletions
+3 -2
View File
@@ -1854,8 +1854,9 @@ export function ResultTable({ table, artifact, title, full = false, highlight, m
<div className="flex flex-wrap items-center gap-x-2 gap-y-0.5 border-t px-1.5 py-1 text-2xs leading-relaxed text-dim">
<span className="tnum">
{[
rows.length < table.rows.length
? `显示前 ${formatNumber(rows.length)} / ${formatNumber(table.rows.length)} 行`
// total:结果一共几行(预览只存了前几行时比 rows 多,比如合并查询 6 行只预览 5 行)
rows.length < Math.max(table.total ?? 0, table.rows.length)
? `显示前 ${formatNumber(rows.length)} / ${formatNumber(Math.max(table.total ?? 0, table.rows.length))} 行`
: `${formatNumber(table.rows.length)} 行`,
hiddenCols > 0 ? `显示前 ${cols.length} / ${table.columns.length} 列` : null,
].filter(Boolean).join(' · ')}
+10 -3
View File
@@ -441,8 +441,10 @@ export interface ResultTable {
rows: unknown[][]
/** 查询本身撞了行数上限——数据库里还有更多,是 guard 没让它全取回来 */
truncated: boolean
/** 这份预览被按字符数切断了——取回来的行数比这里显示的多,只是没存下来 */
/** 这份预览被按字符数切断了,或者本来就只存了前几行——实际的行数比这里显示的多,只是没存下来 */
clipped?: boolean
/** 实际一共几行(结果里的 row_count)。比 rows 多时,表格脚注写「显示前 5 / 6 行」 */
total?: number
}
/**
@@ -477,7 +479,9 @@ function tryTable(text: string): ResultTable | null {
try {
const data = JSON.parse(text)
if (Array.isArray(data?.columns) && Array.isArray(data?.rows)) {
return { columns: data.columns, rows: data.rows, truncated: !!data.truncated }
const total = typeof data.row_count === 'number' && data.row_count > data.rows.length ? data.row_count : undefined
return { columns: data.columns, rows: data.rows, truncated: !!data.truncated,
...(data.clipped === true || total != null ? { clipped: true } : {}), ...(total != null ? { total } : {}) }
}
} catch {
/* 交给调用方决定要不要修 */
@@ -2187,8 +2191,11 @@ export function decodeRun(events: RunEvent[], final?: RunFinal, opts?: DecodeOpt
...(warnings ? { level: 'warn' as const, sub: MERGE_TEXT.warnings(warnings) } : {}),
title: MERGE_TEXT.stepTitle(inputs.map((i) => i.alias)),
detail: typeof d.sql === 'string' && d.sql ? d.sql : undefined,
// 预览只存了前几行:那是「此处仅为预览」(clipped),不是「查询已达行数上限」(truncated)。
// 合并结果本身超过上限才是 truncated;row_count 记全部行数,表格脚注写「显示前 5 / 6 行」
result: Array.isArray(d.columns)
? JSON.stringify({ columns: d.columns, rows: preview, truncated: rows != null && rows > preview.length })
? JSON.stringify({ columns: d.columns, rows: preview, truncated: !!d.truncated,
clipped: rows != null && rows > preview.length, ...(rows != null ? { row_count: rows } : {}) })
: undefined,
meta: [rows != null ? MERGE_TEXT.rows(rows) : '', dur(ms) ?? ''].filter(Boolean).join(' · ') || undefined,
ms,
+4
View File
@@ -123,6 +123,10 @@ await section('合并查询', async () => {
check('标题说合并的是哪几个输入', m?.title === '合并 s、v 的查询结果', m?.title)
check('合并 SQL 留在详情里', m?.detail === synthetic.MERGE_SQL)
check('预览按查询结果的形状给出,能画成表格', !!mod.parseQueryResult(m?.result ?? '')?.columns?.includes('到店人数'))
// 合并结果 8 行、预览只存了 5 行:这是「此处仅为预览」,不是「查询已达行数上限」(A3)
const table = mod.parseQueryResult(m?.result ?? '')
check('预览只存了前几行:记为预览(clipped),不记为查询撞了行数上限(truncated),并带上一共几行', table?.truncated === false
&& table?.clipped === true && table?.total === 8 && table?.rows.length === 5, JSON.stringify({ t: table?.truncated, c: table?.clipped, n: table?.total }))
check('输入、行数、数据源都在', m?.merge?.inputs?.length === 2 && m.merge.inputs[1].source === 'members'
&& m.merge.inputs[0].label === '门店销售' && m.merge.rows === 8)
check('行数和耗时写在行尾', !!m?.meta?.includes('8 行'), m?.meta)
+4
View File
@@ -709,6 +709,10 @@ await section('合并查询:输入、合并 SQL、结果预览,警告各占
check('合并 SQL 有标签、带复制', (await row.innerText()).includes('合并 SQL')
&& await row.getByRole('button', { name: '复制合并 SQL' }).count() === 1)
check('结果预览画成表格(列是合并结果的列)', (await row.locator('table th').allInnerTexts()).some((t) => t.includes('到店人数')))
// 合并结果 8 行、预览只存了 5 行:说「此处仅为预览」和「显示前 5 / 8 行」,不说「查询已达行数上限」(A3)
const foot = (await row.innerText().catch(() => '')).replace(/\s+/g, ' ')
check('预览只存了前几行:写「显示前 5 / 8 行」和「仅为预览」,不说查询已达行数上限', foot.includes('显示前 5 / 8 行')
&& foot.includes('此处仅为预览') && !foot.includes('查询已达行数上限'), foot.slice(-120))
check('输入写在合并 SQL 前面:先看合并的是什么,再看怎么合并', await row.evaluate((el) => {
const m = el.querySelector('[data-step-merge]')
const pre = el.querySelector('pre')