pganalyze / libpg_query

C library for accessing the PostgreSQL parser outside of the server environment
BSD 3-Clause "New" or "Revised" License
1.21k stars 182 forks source link

Unknown variable errors parsing plpgsql functions referencing composite type attributes #260

Open pauldzy opened 2 months ago

pauldzy commented 2 months ago

Hi all,

When testing with pglast, it seems the library is unable to parse PLPgSQL functions returning a composite type attribute https://github.com/lelit/pglast/issues/156

Just to copy/paste over lele's answer from that thread, the following creates a simple type and function using that type

 CREATE TYPE public.dz_sumthing
  AS(sumattribute INTEGER);

  CREATE FUNCTION public.dz_sumfunc(
      IN  p_in  INTEGER
     ,OUT p_out public.dz_sumthing
  )
  AS $BODY$ 
  DECLARE
  BEGIN
     p_out.sumattribute := p_in;
  END;
  $BODY$
  LANGUAGE plpgsql;

  SELECT * FROM public.dz_sumfunc(123);

When libpg_query attempts to parse the function, it fails with ParseError: "p_out.sumattribute" is not a known variable:

#include <pg_query.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
  PgQueryPlpgsqlParseResult result;

  result = pg_query_parse_plpgsql(" \
    CREATE FUNCTION public.dz_sumfunc(\
        IN  p_in  INTEGER\
       ,OUT p_out public.dz_sumthing\
    )\
    AS $BODY$\
    DECLARE\
    BEGIN\
       p_out.sumattribute := p_in;\
    END;\
    $BODY$\
    LANGUAGE plpgsql;");

  if (result.error) {
    printf("error: %s at %d\n", result.error->message, result.error->cursorpos);
  } else {
    printf("%s\n", result.plpgsql_funcs);
  }

  pg_query_free_plpgsql_parse_result(result);

  // Optional, this ensures all memory is freed upon program exit (useful when running Valgrind)
  pg_query_exit();

  return 0;
}

I was interested if libpg_query supports composite types and/or if the problematic variable check could be bypassed.

Thanks