Thread

  1. Re: [PATCH] Add NESTED_STATEMENTS option to EXPLAIN

    Zsolt Parragi <zsolt.parragi@percona.com> — 2026-05-16T11:15:34Z

    Hello!
    
    With some initial testing I was able to find 2 server crashes with the patch.
    
    1: error during explain
    
    CREATE OR REPLACE FUNCTION divz_plpgsql(x int) RETURNS int LANGUAGE
    plpgsql AS $$
    DECLARE r int;
    BEGIN
      SELECT 1/x INTO r;
      RETURN r;
    END;
    $$;
    -- error during explain
    EXPLAIN (ANALYZE, NESTED_STATEMENTS) SELECT divz_plpgsql(0);
    -- run another explain
    EXPLAIN (ANALYZE, NESTED_STATEMENTS) SELECT 1;
    -- any next query crashes the server
    SELECT 1;
    
    2: any nested explain
    
    CREATE FUNCTION f() RETURNS void LANGUAGE plpgsql AS $$
    DECLARE r record;
    BEGIN
      FOR r IN EXECUTE 'EXPLAIN (ANALYZE, NESTED_STATEMENTS) SELECT 1'
      LOOP NULL; END LOOP;
    END;
    $$;
    
    EXPLAIN (ANALYZE, NESTED_STATEMENTS) SELECT f();
    
    
    +		/*
    +		 * Switch to TopMemoryContext so the captured plan text survives
    +		 * until we print it.
    +		 */
    +		oldcxt = MemoryContextSwitchTo(TopMemoryContext);
    ...
    +		ExplainBeginOutput(nes);
    +		ExplainPrintPlan(nes, queryDesc);
    +		ExplainEndOutput(nes);
    ...
    +		plan_info->query_text = queryDesc->sourceText ?
    +			pstrdup(queryDesc->sourceText) : pstrdup("<unknown>");
    
    When is queryDesc freed? This seems like a memory leak.