citusdata / citusdata/citus

PG19 Beta3: fix nested psql COPY transaction in intermediate_results

Open Beginner friendly
#8,793 0 comments 0 reactions 0 assignees View on GitHub
type/bug
Dominant language
C
Stars
12.8k
Forks
794
Avg merge
2d 14h
Merged PRs (30d)
31

Description

## Problem

The PostgreSQL 19 Beta3 integration run exposes a distinct failure in `intermediate_results`: an outer `COPY (...) TO PROGRAM` starts a child `psql` using one `-c` argument containing:

```sql
BEGIN;
COPY squares FROM STDIN WITH (FORMAT binary);
CREATE TABLE squares AS SELECT * FROM read_intermediate_result('squares', 'binary') AS res (x int, x2 int);
END;
```

The outer COPY streams binary rows to the child process. Under PostgreSQL 19 Beta3, the child `psql` exits with status 2, the outer program reports failure, and the `squares` table is absent.

## Evidence

Observed in the PostgreSQL 19 Beta3 integration run and artifacts:

- child command: one `psql -c` containing `BEGIN; COPY ... FROM STDIN; CREATE TABLE ...; END;`
- child exit status: 2
- outer `COPY (...) TO PROGRAM`: fails because the child program failed
- postcondition: `squares` does not exist

## Why this is separate from #8781

#8781 handles psql's new draining behavior after an inline `COPY ... FROM STDIN` is rejected before COPY mode starts. This failure occurs in a nested child psql process whose COPY succeeds far enough to consume the outer program's stdin, but whose single multi-statement `-c` invocation no longer preserves the intended COPY-then-CREATE execution. The two failures may originate from the same upstream psql transition, but their failure boundaries and fixes are different.

## Proposed minimal fix

Keep one child psql process and transaction atomicity, but invoke it as:

```text
psql -1 -c "COPY squares FROM STDIN WITH (FORMAT binary)" -c "CREATE TABLE squares AS ..."
```

This lets COPY consume the program stdin and then executes `CREATE TABLE` in the same transaction. Prefer this unconditional cross-version form if it works on PostgreSQL 16-19, without version gates or alternative expected-output files.

## Acceptance criteria

- `intermediate_results` passes on PostgreSQL 19 Beta3, Beta2, and PostgreSQL 18.4.
- The owning full schedule passes on those versions.
- Existing transaction atomicity and assertions remain intact.
- Scope stays limited to `intermediate_results` SQL and canonical expected output unless validation proves otherwise.

Contributor guide

Open the contributing guide

Research direction

Find the integration SQL for intermediate_results and its canonical expected output, then inspect how the nested psql command is assembled. Run the intermediate_results test first and validate the proposed transaction behavior on PostgreSQL 16-19; done means the test and owning full schedule pass while transaction atomicity and assertions remain unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
postgresql, sql
Domain
databases, testing
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.