Repository navigation
test: pytest 集成测试套件 + BEGIN/CREATE 类语句的 CommandComplete 修复 - #6
Merged
Merged
Conversation
DuckDB surfaces a 1-column 'Success' result for statements like BEGIN, CREATE, DROP, SET, etc. Previously we treated any statement with columns (and not an obviously DML one) as a SELECT and forwarded a RowDescription + DataRow to the client. libpq then tagged the result as PGRES_TUPLES_OK, which breaks drivers that use it as the signal between tuple-producing and command-complete statements — notably psycopg2 when autocommit is off (the implicit 'BEGIN;' sent before the user query). Now we forward rows only for SELECT / EXPLAIN / EXECUTE / CALL statement types; everything else emits a plain CommandComplete. Add PREPARE / EXECUTE tags to statement_tag_for so psycopg2 can consume server-side PREPARE ... ; EXECUTE ... sequences correctly. Co-authored-by: fanvanzh <fanvanzh@users.noreply.github.com>
The test/ directory contains a self-contained integration suite: - conftest.py spins up a real postduck binary on a random port with a temp data directory (or reuses a server pointed to by POSTDUCK_URL), and hands out psycopg2 connections/cursors to the tests. - test_basic.py — simple query protocol, DDL/DML, multi-statement. - test_extended.py — extended query protocol: parameter binding, NULL handling, executemany, fetchmany, server-side PREPARE/EXECUTE. - test_types.py — PG-OID round trips for int/float/bool/text/date/ timestamp/decimal/null/negative numbers. - test_transactions.py — autocommit, commit/rollback, aborted-txn recovery, SET of unknown GUCs as no-ops. - test_errors.py — syntax / catalog / conversion errors surface as proper ErrorResponse and don't poison the connection. Run with 'pytest test/' or 'test/run_tests.sh'. 39 tests, all pass against the current build. Co-authored-by: fanvanzh <fanvanzh@users.noreply.github.com>
fanvanzh
marked this pull request as ready for review
April 21, 2026 05:52
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
承接已合入的 PR #4,这里补上两件事:一套基于 pytest + psycopg2 的端到端测试,以及一个在写测试时暴露出来的协议层小 bug 的修复。
1.
fix(protocol): BEGIN / CREATE / SET 这类语句必须回 CommandComplete,不能回 RowsDuckDB 对
BEGIN/CREATE/DROP/SET等语句会返回一个 1 列、名为Success的结果。之前代码里is_select = has_columns && !is_dml的判断把它们当 SELECT 处理,于是发了RowDescription+DataRow给客户端。libpq 收到后把整个结果标成PGRES_TUPLES_OK("这条语句产出了元组"),这会让 psycopg2 在autocommit=False时报:因为 psycopg2 在 autocommit 关闭时会在用户第一条语句之前偷偷发一个
BEGIN;,此时 server 的"假结果"直接把客户端的状态机带坏了。改法很窄:只对
SELECT/EXPLAIN/EXECUTE/CALL这几类语句真的回发 rows,其它统一只发CommandComplete。顺手给statement_tag_for补了PREPARE和EXECUTE两种 tag(EXECUTE按它承载的 SELECT 计数,返回SELECT n)。2.
test/: pytest + psycopg2 集成测试按要求在仓库根建了
test/目录,里面的 fixture 会:$POSTDUCK_BIN→<repo>/build/postduck→$PATH里找可执行文件;postduck进程;psycopg2连接交给每个测试用例;POSTDUCK_URL,就跳过启动,直接连已有实例——方便对接真实环境做回归。目录结构:
运行
结果
冲突说明
原分支
cursor/pg-protocol-compat-ef99在 PR #4 被 squash-merge 进 main 后,所有 4 个 feat/docs commit 被压成了一个 squash commit(8d4ddda),导致原分支相对 main 的历史对不上。这里重新
git checkout -b cursor/pg-protocol-tests-ef99 origin/main之后,把 #4 合入之后新增的两个 commit(fix(protocol): emit CommandComplete...和test: add pytest integration suite...)cherry-pick 过来,干净应用、无冲突,只改动src/session.cpp与新增的test/目录。