migra icon indicating copy to clipboard operation
migra copied to clipboard

Cannot introspect a function

Open chartpath opened this issue 5 years ago • 1 comments

I'm using migra with a Hasura project. Hasura has an Event Triggers feature that generates SQL trigger functions. Looks like migra can't introspect them, but after trying to add some print statements in the running migra code, I wasn't able to dig into the variables or raise the correct exceptions to see it in the terminal. Any tips on debugging?

Here is a traceback of the error:

Traceback (most recent call last):
  File "/path_to/bin/migra", line 8, in <module>
    sys.exit(do_command())
  File "/path_to/lib/python3.8/site-packages/migra/command.py", line 108, in do_command
    status = run(args)
  File "/path_to/lib/python3.8/site-packages/migra/command.py", line 85, in run
    m.add_all_changes(privileges=args.with_privileges)
  File "/path_to/lib/python3.8/site-packages/migra/migra.py", line 106, in add_all_changes
    self.add(self.changes.non_table_selectable_creations())
  File "/path_to/lib/python3.8/site-packages/migra/changes.py", line 500, in get_selectable_changes
    statements += statements_from_differences(
  File "/path_to/lib/python3.8/site-packages/migra/changes.py", line 128, in statements_from_differences
    statements.append(v.create_statement)
  File "/path_to/lib/python3.8/site-packages/schemainspect/pg/obj.py", line 294, in create_statement
    return self.full_definition + ";"
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'

The offending functions from Hasura look like this:

CREATE FUNCTION hdb_views."notify_hasura_my_event_trigger_name_I"() RETURNS trigger
    LANGUAGE plpgsql
    AS $$
  DECLARE
    _old record;
    _new record;
    _data json;
  BEGIN
    IF TG_OP = 'UPDATE' THEN
      _old := row(OLD );
      _new := row(NEW );
    ELSE
    /* initialize _old and _new with dummy values for INSERT and UPDATE events*/
      _old := row((select 1));
      _new := row((select 1));
    END IF;
    _data := json_build_object(
      'old', NULL,
      'new', row_to_json(NEW )
    );
    BEGIN
      IF (TG_OP <> 'UPDATE') OR (_old <> _new) THEN
        PERFORM hdb_catalog.insert_event_log(CAST(TG_TABLE_SCHEMA AS text), CAST(TG_TABLE_NAME AS text), CAST('my_event_trigger_name' AS text), TG_OP, _data);
      END IF;
      EXCEPTION WHEN undefined_function THEN
        IF (TG_OP <> 'UPDATE') OR (_old *<> _new) THEN
          PERFORM hdb_catalog.insert_event_log(CAST(TG_TABLE_SCHEMA AS text), CAST(TG_TABLE_NAME AS text), CAST('my_event_trigger_name' AS text), TG_OP, _data);
        END IF;
    END;

    RETURN NULL;
  END;
$$;

Happy to try writing a fix if someone can suggest what to look for. Thanks!

chartpath avatar Nov 26 '20 20:11 chartpath

Hey, thanks for filing this issue!

Looks like the correct definition isn't being inspected properly for some reason. Any ideas why? (I'm not a hasura user myself)

I'll look into this when I can and see if I can figure out a fix.

djrobstep avatar Dec 01 '20 09:12 djrobstep