pg_duckdb icon indicating copy to clipboard operation
pg_duckdb copied to clipboard

Backend crash on Not implemented Error: SAVEPOINT is not supported in DuckDB

Open ggnmstr opened this issue 7 months ago • 1 comments

What happens?

With duckdb.force_execution set to TRUE, this query crashes user backend:

DO $$
DECLARE
    objtype text;
BEGIN
    FOR objtype IN VALUES ('toast table'), ('index column'), ('sequence column'),
        ('toast table column'), ('view column'), ('materialized view column')
    LOOP
        BEGIN
            PERFORM pg_get_object_address(objtype, '{one}', '{}');
        EXCEPTION WHEN invalid_parameter_value THEN
            RAISE WARNING 'error for %: %', objtype, sqlerrm;
        END;
    END LOOP;
END;
$$; 

Result:

psql:orig.sql:18: FATAL:  (PGDuckDB/DuckdbSubXactCallback_Cpp) Not implemented Error: SAVEPOINT is not supported in DuckDB
CONTEXT:  PL/pgSQL function inline_code_block line 8 during statement block entry
psql:orig.sql:18: server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
psql:orig.sql:18: error: connection to server was lost

This seems to be happening only in PostgreSQL 17+ versions due to this change that treats any error in subtransaction as fatal.

In PostgreSQL 16, for instance, we won't get backend crash:

ERROR:  (PGDuckDB/DuckdbSubXactCallback_Cpp) Not implemented Error: SAVEPOINT is not supported in DuckDB
CONTEXT:  PL/pgSQL function inline_code_block line 8 during statement block entry 

This may look as expected behavior in PostgreSQL 17+, the question is if we really want to get backend crashed in these situations or we may find some way to handle unsupported SAVEPOINTS without causing backend crash.

To Reproduce

  1. Start a fresh server with pg_duckdb and duckdb.force_execution set to TRUE
  2. Run this query:
DO $$
DECLARE
    objtype text;
BEGIN
    FOR objtype IN VALUES ('toast table'), ('index column'), ('sequence column'),
        ('toast table column'), ('view column'), ('materialized view column')
    LOOP
        BEGIN
            PERFORM pg_get_object_address(objtype, '{one}', '{}');
        EXCEPTION WHEN invalid_parameter_value THEN
            RAISE WARNING 'error for %: %', objtype, sqlerrm;
        END;
    END LOOP;
END;
$$; 
  1. Get a backend crash

OS:

Linux

pg_duckdb Version (if built from source use commit hash):

cbc28da57aa943066af41ffa520c631a39046cf1

Postgres Version (if built from source use commit hash):

17

Hardware:

No response

Full Name:

Jora Babayan

Affiliation:

Postgres Professional

What is the latest build you tested with? If possible, we recommend testing with the latest nightly build.

I have tested with a source build

Did you include all relevant data sets for reproducing the issue?

No - Other reason (please specify in the issue body)

Did you include all code required to reproduce the issue?

  • [x] Yes, I have

Did you include all relevant configuration (e.g., CPU architecture, Linux distribution) to reproduce the issue?

  • [x] Yes, I have

ggnmstr avatar May 07 '25 05:05 ggnmstr

I left some thoughts on PR #763 about fixing this.

But I'm going to postpone addressing this until after 1.0. Since this is a backend FATAL error, and not a full Postgres process-tree crash. And it can easily be avoided by the user, by simply not using savepoints.

JelteF avatar May 07 '25 14:05 JelteF