Re: BackgroundPsql swallowing errors on windows
От | Arseniy Mukhin |
---|---|
Тема | Re: BackgroundPsql swallowing errors on windows |
Дата | |
Msg-id | CAE7r3MJwj2hMmHK-Fv87uGRkHM4ZFhAMCMk+wciU8+T50iFLGA@mail.gmail.com обсуждение исходный текст |
Ответ на | Re: BackgroundPsql swallowing errors on windows (Tom Lane <tgl@sss.pgh.pa.us>) |
Список | pgsql-hackers |
Hi, I think I encountered the bug that relates to the patch from this thread so I decided to write a report here. version(): PostgreSQL 19devel on x86_64-linux, compiled by gcc-13.3.0, 64-bit. (master) While writing a TAP test I noticed that background_psql hangs on a simple query without any reason. The most simple reproducer I came up with: my $psql = $node->background_psql('postgres', timeout => 3); $psql->query(q(\warn AAAAA)); $psql->query("select 1"); Here $psql->query("select 1;") hangs until timeout. Here what I managed to understand after some investigation: Just to remind how banner and banner_match look like: my $banner = "background_psql: QUERY_SEPARATOR $query_cnt:"; my $banner_match = qr/(^|\n)$banner\r?\n/; psql->query() hangs in an endless loop in pump_until() as the termination condition (last if $$stream =~ /$until/) is never met. Unfortunately, logs don't show the reason why we are stuck here (maybe I do something wrong but it seems that [0] explains why pump_until() timeout diag code doesn't work), so to get more information we need to add some additional logging in pump_until(). If we add logging of $$stream and $until then we can see next lines for pump_until() stderr call: STREAM: AAAAAbackground_psql: QUERY_SEPARATOR 2: UNTIL: (?^:(^|\n)background_psql: QUERY_SEPARATOR 2:\r?\n) STREAM here is what we have in stderr and UNTIL is just a banner_match. You can see that we have stderr from the previous query ('AAAAA') concatenated with the banner on the same line. So it doesn't match what we have in $until pattern as it requires (^|\n) to be before the banner. This way we have an endless loop. It seems that the reason we don't have line separator after 'AAAAA' is a difference between how we inject and remove the banner: Here is a how we inject banner: $self->{stdin} .= "$query\n;\n\\echo $banner\n\\warn $banner\n"; How we remove banner from stderr $self->{stderr} =~ s/$banner_match//; We remove from stderr not only the banner we previously injected with warn, but also the line separator before the banner. [0] https://www.postgresql.org/message-id/flat/1100715.1712265845@sss.pgh.pa.us Best regards, Arseniy Mukhin
В списке pgsql-hackers по дате отправления: