On Mon, May 23, 2011 at 14:59, Greg Sabino Mullane <g...@endpoint.com> wrote: > I've not been able to duplicate this in a standalone script yet, > but in the guts of Bucardo is a trigger function called validate_goat() > that is giving this error on 9.1 HEAD, but not on previous versions: > > "Failed to add table "public.pgbench_tellers": DBD::Pg::st execute > failed: ERROR: Modification of non-creatable hash value attempted, > subscript "pkey" at line 4."
> ... > Some Googling suggests it might > be because we are using &PL_sv_undef instead of a proper > newSV(0). Yep. Per http://search.cpan.org/~jesse/perl-5.14.0/pod/perlguts.pod#AVs,_HVs_and_undefined_values |...For example, intuition tells you that this XS code: | | AV *av = newAV(); | av_store( av, 0, &PL_sv_undef ); | | is equivalent to this Perl code: | | my @av; | $av[0] = undef; | Unfortunately, this isn't true. AVs use &PL_sv_undef as a marker for indicating that an array element has not yet been initialized. We have a few places that have that pattern :-(. I was able to reproduce it fairly easily(1) by passing in NULL values explicitly. Fixed in the attached. I looked at 9.0 and below and they did this correctly. This code path was heavily re-factored in 9.1 for better array and composite type support . As noted in perlguts using &PL_sv_undef follows your intuition, but its wrong :-(. Classic perl xs I suppose. Greg, can you confirm the attached fixes it for you? -- [1] => create or replace function td() returns trigger language plperlu as $bc$ $_TD->{new}{a} = 1; return 'MODIFY'; $bc$; CREATE FUNCTION => create table trig_test(a int); CREATE TABLE => create trigger test_trig before insert on trig_test for each row execute procedure td(); CREATE TRIGGER => insert into trig_test values (NULL); CONTEXT: PL/Perl function "td" ERROR: Modification of non-creatable hash value attempted, subscript "a" at line 2.
*** a/src/pl/plperl/plperl.c --- b/src/pl/plperl/plperl.c *************** *** 1357,1363 **** make_array_ref(plperl_array_info *info, int first, int last) for (i = first; i < last; i++) { if (info->nulls[i]) ! av_push(result, &PL_sv_undef); else { Datum itemvalue = info->elements[i]; --- 1357,1366 ---- for (i = first; i < last; i++) { if (info->nulls[i]) ! { ! /* We cant use &PL_sv_undef here... see perlguts */ ! av_push(result, newSV(0)); ! } else { Datum itemvalue = info->elements[i]; *************** *** 2639,2646 **** plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc) if (isnull) { ! /* Store (attname => undef) and move on. */ ! hv_store_string(hv, attname, &PL_sv_undef); continue; } --- 2642,2652 ---- if (isnull) { ! /* ! * Store (attname => undef) and move on. Note, we cant use ! * &PL_sv_undef here... see perlguts for more ! */ ! hv_store_string(hv, attname, newSV(0)); continue; }
-- Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-bugs