The second expansion in matrix_out happens outside the function, so inside there is only the one expansion for both matrix_nvals and the assignment. Thank you! All my tests continue to pass and the change seems to work well.
Hmm, well I spoke to soon looking at the wrong function without an assignment, I've been down in gdb a bit too much and I got mixed up, here's another function that wraps it and does an assignment, and it looks like there is another expansion happening after the nvals but before the assignment:
create or replace function test_expand_expand(graph matrix) returns matrix language plpgsql as $$ declare nvals bigint = nvals(graph); begin graph = test_expand(graph); return test_expand(graph); end; $$;
So going back on the assumption I'm somehow not returning the right pointer, but digging into the array code I'm pretty sure I'm following the same pattern and tracing my code path is calling EOHPGetRWDatum when I return the object, I can't get it to stop on DeleteExpandedObject, so I don't think plpgsql is deleting it, I'm going to keep investigating, sorry for the noise.