Bug 134300 - databases/postgresql-plruby: PL/ruby corrupts data since Ruby upgrade to 1.8.7
Summary: databases/postgresql-plruby: PL/ruby corrupts data since Ruby upgrade to 1.8.7
Status: Closed FIXED
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: Normal Affects Only Me
Assignee: Akinori MUSHA
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-05-06 20:30 UTC by Peter Much
Modified: 2009-05-26 10:50 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Peter Much 2009-05-06 20:30:05 UTC
Since the Ruby upgrade from 1.8.6.287 to 1.8.7.72 (which is forced
from default values in ports/Mk and therefore should be supposed to
be a stable version) the databases/postgresql-plruby port silently
produces wrong computation results, leading to database corruption.

Functions written in PL/ruby can return either simple values or
database records (SETOF record). The problem appears with functions
returning SETOF record. These functions do now ignore the parameters
given into them and instead compute with whatever value they seem fit,
producing nonsense results.

The problem was tracked down to different compile parameters of
PL/ruby. The PL/ruby package uses an extconf.rb script to create 
the makefiles. This script tests the existence of the ruby function
rb_block_call, and if found, different code will be compiled which
uses that function.

With Ruby 1.8.6.287 that function was not found, with Ruby 1.8.7.72
it is found.

It seems that either this function rb_block_call in the FreeBSD
Ruby installation 1.8.7.72, or the specific code that calls that
function from PL/ruby, is in some way broken.

When upgrading PL/ruby to the newer available version 0.5.3 , the 
malfunction is still present. But this newer version is improved
insofar that it seems to detect a problem with the parameters and
throws an error message, forcing a transaction rollback and 
eliminating the risk of silent data corruption.

I have mailed the author of PL/ruby (after detecting the problem,
before doing thorough analysis), but have not gotten a reply.

Fix: Suppress the use of rb_block_call when compiling PL/ruby,
drop the following patch into /usr/ports/databases/postgresql-plruby/files:



It should be further investigated: where exactly the malfunction happens,
what this function rb_block_call is good for (I have no idea) and why
it seems to have appeared between Ruby 1.8.6 and 1.8.7.

It could also be feasible to upgrade the PL/ruby port to version
0.5.3, as not only the error checking seems to be improved, but it
is also reported that this newer version is necessary when upgrading
PostgresQL to Version 8.3--9I90U65CFE3v8OnaJPlpZPwmbSR5O0RkT7JkAztAAoUgYgIG
Content-Type: text/plain; name="file.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="file.diff"

*** extconf.rb.orig   Tue Sep 19 14:39:28 2006
--- extconf.rb        Wed May  6 19:16:11 2009
***************
*** 152,159 ****
     $CFLAGS += " -DHAVE_RB_INITIALIZE_COPY"
  end
  
- have_func("rb_block_call")
- 
  if version.to_i >= 74
     if !have_header("server/utils/array.h")
        if !have_header("utils/array.h")
--- 152,157 ----
How-To-Repeat: 
Compile the beforementioned versions of ruby and PL/ruby from ports.
Check that "make configure" of "PL/ruby" will report:
	>checking for rb_block_call()... yes

Testing for the presence of the malfunction can be done in the
following way:

1. Have a running postgresQL database
2. Enable PL/ruby within that database as explained in
   the PKGMESSAGE of the PL/ruby port. 
3. Create the following PL/ruby function within the database:

create function ev_test(boolean)
returns setof record as
'if args[0]
yield [1]
end
if !args[0]
yield [2]
end'
LANGUAGE 'plruby' STABLE;

4. Call this function twice:

SELECT * FROM ev_test(true) AS (a int4);
SELECT * FROM ev_test(false) AS (a int4);

If both calls show the same result, the malfunction is present.
(When using PL/ruby 0.5.3, there will be no results shown, instead
an error message will report incompatible type of argv or something
similar.)

The test-suite contained with PL/ruby will also show the problem.
Comment 1 Edwin Groothuis freebsd_committer 2009-05-18 23:33:06 UTC
Responsible Changed
From-To: freebsd-ports-bugs->knu

Over to maintainer (via the GNATS Auto Assign Tool)
Comment 2 Akinori MUSHA freebsd_committer 2009-05-25 06:58:58 UTC
State Changed
From-To: open->feedback

Hi, thanks for the report. 

Would you try this patch?  It should fix the problem with args. 

http://github.com/knu/postgresql-plruby/commit/3b3cc0786b0814eaa792cec65cedd54e1e43e9bd 

P.S. The original author passed away last year, and I am taking over his projects.
Comment 3 Akinori MUSHA 2009-05-25 07:32:59 UTC
I should really have put this URL instead:

http://github.com/knu/postgresql-plruby/commit/3b3cc0786b0814eaa792cec65cedd54e1e43e9bd.patch

-- 
Akinori MUSHA / http://akinori.org/
Comment 4 dfilter service freebsd_committer 2009-05-26 10:42:11 UTC
knu         2009-05-26 09:42:02 UTC

  FreeBSD ports repository

  Modified files:
    databases/postgresql-plruby Makefile distinfo pkg-plist 
  Log:
  Add a patch to fix a problem that a wrong value is set to "args" when
  compiled with Ruby 1.8.7 or later.
  
  PR:             ports/134300
  Submitted by:   Peter Much <pmc@citylink.dinoex.sub.org>
  
  Revision  Changes    Path
  1.37      +5 -0      ports/databases/postgresql-plruby/Makefile
  1.21      +3 -0      ports/databases/postgresql-plruby/distinfo
  1.15      +88 -88    ports/databases/postgresql-plruby/pkg-plist
_______________________________________________
cvs-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/cvs-all
To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
Comment 5 Akinori MUSHA freebsd_committer 2009-05-26 10:42:17 UTC
State Changed
From-To: feedback->closed

My patch has been committed.  If you still have the problem, 
please let me know.  Thanks for the detailed report!