PL/Ruby segfaults

J

Jeremy Henty

I have installed plruby, but it segfaults on the simplest example.
I'd really appreciate any help debugging this. Details follow.

Thanks in advance,

Jeremy Henty


----


Using Linux 2.4.31 , Ruby 1.8.3 , Postgres 8.0.3, plruby-0.4.5 .

--- begin db_create.sql

create database test;
\c test

create function plruby_call_handler()
returns language_handler
as '/usr/lib/ruby/site_ruby/1.8/i586-linux/plruby.so'
language 'C';

create trusted language 'plruby'
handler plruby_call_handler
lancompiler 'PL/Ruby';

--- end db_create.sql

-bash-2.05b# su - postgres
-su-2.05b$ cd /tmp/PL_Ruby/
-su-2.05b$ psql -f db_create.sql template1
CREATE DATABASE
You are now connected to database "test".
CREATE FUNCTION
CREATE LANGUAGE

--- begin schema_create.sql

create function test_update()
returns trigger as '
PL::OK
' language 'plruby';

create table test ( foo text );

create trigger test_update_trigger
after insert or update or delete
on test
execute procedure
test_update();

insert into test ( foo )
values ('');

--- end schema_create.sql

-bash-2.05b$ psql -f schema_create.sql -d test
CREATE FUNCTION
CREATE TABLE
CREATE TRIGGER
psql:schema_create.sql:16: server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
psql:schema_create.sql:16: connection to server was lost

-bash-2.05b# tail -20 /var/pgsql/data/log
<snip>
(eval):4: [BUG] Segmentation fault
ruby 1.8.3 (2005-09-21) [i586-linux]

LOG: server process (PID 18749) was terminated by signal 6
LOG: terminating any other active server processes
LOG: all server processes terminated; reinitializing
LOG: database system was interrupted at 2005-10-04 20:57:59 BST
LOG: checkpoint record is at 0/228AF00
LOG: redo record is at 0/228AF00; undo record is at 0/0; shutdown FALSE
LOG: next transaction ID: 9889; next OID: 99292
LOG: database system was not properly shut down; automatic recovery in progress
LOG: redo starts at 0/228AF3C
LOG: record with zero length at 0/22C82D0
LOG: redo done at 0/22C82A8
LOG: database system is ready
 
T

ts

J> create trigger test_update_trigger
J> after insert or update or delete
J> on test

FOR EACH ROW

J> execute procedure
J> test_update();

svg% psql plruby_test
Welcome to psql 8.0.1, the PostgreSQL interactive terminal.

Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit

plruby_test=# create function test_update()
plruby_test-# returns trigger as '
plruby_test'# PL::OK
plruby_test'# ' language 'plruby';
CREATE FUNCTION
plruby_test=# create table test ( foo text );
CREATE TABLE
plruby_test=# create trigger test_update_trigger
plruby_test-# after insert or update or delete
plruby_test-# on test
plruby_test-# FOR EACH ROW
plruby_test-# execute procedure
plruby_test-# test_update();
CREATE TRIGGER
plruby_test=# insert into test ( foo )
plruby_test-# values ('');
INSERT 34166 1
plruby_test=# \q
svg%


I'll add the test for the next version


Guy Decoux
 
J

Jeremy Henty

J> create trigger test_update_trigger
J> after insert or update or delete
J> on test

FOR EACH ROW

J> execute procedure
J> test_update();
[snip]
I'll add the test for the next version

I specifically want a FOR EACH STATEMENT trigger .

next_version_will_support_this? ? "Cool!" : "What needs to be done to
support this?"

Thanks for your reply,

Jeremy Henty
 
T

ts

J> I specifically want a FOR EACH STATEMENT trigger .

I hope that know that, in this case, you don't have access to old, new and
normally you must *ONLY* return false

J> next_version_will_support_this? ? "Cool!" : "What needs to be done to
J> support this?"

vg% diff -u plruby.c~ plruby.c
--- plruby.c~ 2005-06-06 17:38:38.000000000 +0200
+++ plruby.c 2005-10-05 15:33:54.000000000 +0200
@@ -1203,24 +1203,32 @@
rb_raise(pl_ePLruby, "unknown LEVEL event (%u)", trigdata->tg_event);
}

+ tg_old = Qnil;
+ tg_new = Qnil;
+ rettup = NULL;
if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) {
rb_hash_aset(TG, rb_str_freeze_new2("op"), INT2FIX(TG_INSERT));
- tg_new = plruby_build_tuple(trigdata->tg_trigtuple, tupdesc, RET_HASH);
- tg_old = rb_hash_new();
- rettup = trigdata->tg_trigtuple;
+ if (TRIGGER_FIRED_FOR_ROW(trigdata->tg_event)) {
+ tg_new = plruby_build_tuple(trigdata->tg_trigtuple, tupdesc, RET_HASH);
+ tg_old = rb_hash_new();
+ rettup = trigdata->tg_trigtuple;
+ }
}
else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)) {
rb_hash_aset(TG, rb_str_freeze_new2("op"), INT2FIX(TG_DELETE));
- tg_old = plruby_build_tuple(trigdata->tg_trigtuple, tupdesc, RET_HASH);
- tg_new = rb_hash_new();
-
- rettup = trigdata->tg_trigtuple;
+ if (TRIGGER_FIRED_FOR_ROW(trigdata->tg_event)) {
+ tg_old = plruby_build_tuple(trigdata->tg_trigtuple, tupdesc, RET_HASH);
+ tg_new = rb_hash_new();
+ rettup = trigdata->tg_trigtuple;
+ }
}
else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) {
rb_hash_aset(TG, rb_str_freeze_new2("op"), INT2FIX(TG_UPDATE));
- tg_new = plruby_build_tuple(trigdata->tg_newtuple, tupdesc, RET_HASH);
- tg_old = plruby_build_tuple(trigdata->tg_trigtuple, tupdesc, RET_HASH);
- rettup = trigdata->tg_newtuple;
+ if (TRIGGER_FIRED_FOR_ROW(trigdata->tg_event)) {
+ tg_new = plruby_build_tuple(trigdata->tg_newtuple, tupdesc, RET_HASH);
+ tg_old = plruby_build_tuple(trigdata->tg_trigtuple, tupdesc, RET_HASH);
+ rettup = trigdata->tg_newtuple;
+ }
}
else {
rb_raise(pl_ePLruby, "unknown OP event (%u)", trigdata->tg_event);
@@ -1276,6 +1284,10 @@
break;
}

+ if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event)) {
+ rb_raise(pl_ePLruby, "Invalid return value for per-statement trigger");
+ }
+
modattrs = ALLOCA_N(int, tupdesc->natts);
modvalues = ALLOCA_N(Datum, tupdesc->natts);
for (i = 0; i < tupdesc->natts; i++) {
svg%



Guy Decoux
 
J

Jeremy Henty

J> I specifically want a FOR EACH STATEMENT trigger .

[snip patch]

/me dances a little jig - it works! Thanks again for your help. BUT
.... I'd like the trigger to "require" a Ruby library and I get "ERROR:
Insecure operation - require". How do I workaround this? Even
"require"-ing the library while connected to Postgres as the postgres
user doesn't work! Or maybe there's a way to "require" the library at
startup?

Cheers,

Jeremy Henty
 
J

Jeremy Henty

* plruby run under the uid of postgres

Hmm, that's definitely *not* what I want. I suspect I'm going about
this the wrong way. What I *want* is for some userspace programs to
get pinged whenever certain database tables change, so they can
regenerate some config files using information from the database.
This should happen under my userid, not postgres. What's a good way
to do that?

Cheers,

Jeremy Henty
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top