合并查询的截断口径对齐查询层:取满上限之后确实还有下一行才算截断,恰好取满的完整结果不再被下游拒收

This commit is contained in:
ThearchyHelios
2026-10-03 10:28:59 +08:00
parent 98ebba384f
commit ab1f42d2ce
2 changed files with 14 additions and 5 deletions
+7 -5
View File
@@ -343,21 +343,23 @@ def _authorize(action: int, *_args: Any) -> int:
def _read(conn: sqlite3.Connection, stmt: str, limits: QueryLimits) -> tuple[list[str], list[list[Any]], bool]:
"""逐行读、边读边判上限:和查询层(data.engine.run_query)同一个口径,到了行数或字节上限就停,记 truncated。"""
"""逐行读、边读边判上限:和查询层(data.engine.run_query)同一个口径——到了行数或字节上限之后
确实还有下一行才记 truncated,恰好取满不算(截断的合并结果下游会拒收,误报就是拒了完整的结果)。"""
cursor = conn.execute(stmt)
columns = [str(d[0]) for d in cursor.description or []]
if not columns:
raise MergeError("合并 SQL 没有返回任何列")
rows: list[list[Any]] = []
size = 0
truncated = False
truncated = full = False
for row in cursor:
if full:
truncated = True
break
values = [_jsonable(v) for v in row]
rows.append(values)
size += len(json.dumps(values, ensure_ascii=False, default=str))
if len(rows) >= limits.max_rows or size >= limits.max_bytes:
truncated = True
break
full = len(rows) >= limits.max_rows or size >= limits.max_bytes
return columns, rows, truncated
+7
View File
@@ -213,6 +213,13 @@ def test_result_over_the_row_limit_is_truncated_and_warned():
assert "result_truncated" in [w["code"] for w in out.warnings]
def test_exactly_full_result_is_not_truncated():
"""恰好取满上限、后面没有了:和查询层同一个口径,不算截断——截断的合并结果下游会拒收,误报就是把完整的结果拒了。"""
out = execute([sales(), visits()], "SELECT * FROM s CROSS JOIN v", limits=QueryLimits(max_rows=16))
assert out.truncated is False and len(out.rows) == 16
assert "result_truncated" not in [w["code"] for w in out.warnings]
def test_byte_limit_matches_the_query_layer():
out = execute([sales(), visits()], "SELECT * FROM s CROSS JOIN v", limits=QueryLimits(max_bytes=100))
assert out.truncated is True and 0 < len(out.rows) < 16