From 66d2c01a4c9e95775d770e1eea5bac0217ba0bb3 Mon Sep 17 00:00:00 2001 From: Hans de Graaff Date: Sun, 27 Jun 2010 09:38:51 +0200 Subject: [PATCH 01/15] Link explicitly to the ruby18 library to avoid issues when other ruby implementations or versions are the default ruby library. --- extconf.rb | 2 ++ src/conversions/basic/extconf.rb | 1 + src/conversions/bitstring/extconf.rb | 1 + src/conversions/datetime/extconf.rb | 1 + src/conversions/geometry/extconf.rb | 1 + src/conversions/network/extconf.rb | 1 + 6 files changed, 7 insertions(+) diff --git a/extconf.rb b/extconf.rb index 06a6284..f8c04e9 100755 --- a/extconf.rb +++ b/extconf.rb @@ -156,6 +156,8 @@ def rule(target, clean = nil) $CFLAGS += " -DPG_PL_TRYCATCH" end +have_library('pq', 'PQconnectdb') + enable_conversion = false if enable_conversion = enable_config("conversion", true) $CFLAGS += " -DPLRUBY_ENABLE_CONVERSION" diff --git a/src/conversions/basic/extconf.rb b/src/conversions/basic/extconf.rb index d4833b8..f788d9c 100644 --- a/src/conversions/basic/extconf.rb +++ b/src/conversions/basic/extconf.rb @@ -4,4 +4,5 @@ !enable_config("plruby-shared") $LIBRUBYARG = "" end +have_library('ruby18', 'ruby_init') create_makefile('plruby/plruby_basic') diff --git a/src/conversions/bitstring/extconf.rb b/src/conversions/bitstring/extconf.rb index e980c1e..b6f89d3 100644 --- a/src/conversions/bitstring/extconf.rb +++ b/src/conversions/bitstring/extconf.rb @@ -4,4 +4,5 @@ !enable_config("plruby-shared") $LIBRUBYARG = "" end +have_library('ruby18', 'ruby_init') create_makefile('plruby/plruby_bitstring') diff --git a/src/conversions/datetime/extconf.rb b/src/conversions/datetime/extconf.rb index c5de23b..caeebea 100644 --- a/src/conversions/datetime/extconf.rb +++ b/src/conversions/datetime/extconf.rb @@ -4,4 +4,5 @@ !enable_config("plruby-shared") $LIBRUBYARG = "" end +have_library('ruby18', 'ruby_init') create_makefile('plruby/plruby_datetime') diff --git a/src/conversions/geometry/extconf.rb b/src/conversions/geometry/extconf.rb index 9fcf48e..74655b3 100644 --- a/src/conversions/geometry/extconf.rb +++ b/src/conversions/geometry/extconf.rb @@ -4,4 +4,5 @@ !enable_config("plruby-shared") $LIBRUBYARG = "" end +have_library('ruby18', 'ruby_init') create_makefile('plruby/plruby_geometry') diff --git a/src/conversions/network/extconf.rb b/src/conversions/network/extconf.rb index 29952ee..612e7fa 100644 --- a/src/conversions/network/extconf.rb +++ b/src/conversions/network/extconf.rb @@ -4,4 +4,5 @@ !enable_config("plruby-shared") $LIBRUBYARG = "" end +have_library('ruby18', 'ruby_init') create_makefile('plruby/plruby_network') From abc39ddd4e068d244aea0c1ce7926526863c48a1 Mon Sep 17 00:00:00 2001 From: tfoldi Date: Sun, 26 Sep 2010 13:21:08 +0200 Subject: [PATCH 02/15] With this patch PLRuby supports SFRM_ValuePerCall return mode. Now it is possible to return SETOF types in contexts, which does not supports SFRM_Materialize. This was required to support functions which returns multiple SETOF records from a single function calls in column definitions, eg.: test1=# SELECT ruby_function(column); ruby_function -------------------------------- (value,2) (value2,1) (2 rows) where ruby function returns 'setof custom_type'. A minor modification also added to avoid warning message with ruby19 --- extconf.rb | 1 + src/plpl.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/plruby.c | 3 +- src/plruby.h | 6 ++- 4 files changed, 129 insertions(+), 4 deletions(-) diff --git a/extconf.rb b/extconf.rb index 06a6284..9e97cb6 100755 --- a/extconf.rb +++ b/extconf.rb @@ -141,6 +141,7 @@ def rule(target, clean = nil) end have_func("rb_block_call") +have_header("ruby/st.h") have_header("st.h") if version >= 74 diff --git a/src/plpl.c b/src/plpl.c index 8105c75..0ee2b63 100644 --- a/src/plpl.c +++ b/src/plpl.c @@ -359,7 +359,7 @@ pl_tuple_s_new(PG_FUNCTION_ARGS, pl_proc_desc *prodesc) GetTuple(res, tpl); tpl->cxt = rsi->econtext->ecxt_per_query_memory; tpl->dsc = rsi->expectedDesc; - tpl->att = TupleDescGetAttInMetadata(rsi->expectedDesc); + tpl->att = TupleDescGetAttInMetadata(tpl->dsc); tpl->pro = prodesc; rb_thread_local_aset(rb_thread_current(), id_thr, res); return res; @@ -706,6 +706,15 @@ pl_tuple_put(VALUE c, VALUE tuple) return Qnil; } +static VALUE +pl_ary_collect(VALUE c, VALUE ary) +{ + PLRUBY_BEGIN_PROTECT(1); + rb_ary_push(ary,c); + PLRUBY_END_PROTECT; + return Qnil; +} + static Datum pl_tuple_datum(VALUE c, VALUE tuple) { @@ -1388,7 +1397,117 @@ plruby_return_value(struct pl_thread_st *plth, pl_proc_desc *prodesc, rb_raise(pl_ePLruby, "no description given"); } rsi = (ReturnSetInfo *)fcinfo->resultinfo; - if ((rsi->allowedModes & SFRM_Materialize) && rsi->expectedDesc) { + if (prodesc->result_is_setof && !rsi->expectedDesc) { + VALUE res, retary, arg; + struct pl_arg *args; + TupleDesc tupdesc; + FuncCallContext *funcctx; + Datum result; + + arg = Data_Make_Struct(rb_cObject, struct pl_arg, pl_arg_mark, free, args); + args->id = rb_intern(RSTRING_PTR(value_proname)); + args->ary = ary; +#if PG_PL_VERSION >= 75 + args->named = prodesc->named_args; +#endif + + if (SRF_IS_FIRSTCALL()) + { + MemoryContext oldcontext; + + funcctx = SRF_FIRSTCALL_INIT(); + + oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); + + /* Build a tuple descriptor for our result type */ + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("function returning record called in context " + "that cannot accept type record"))); + /* + * generate attribute metadata needed later to produce tuples from raw + * C strings + */ + funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc); + + MemoryContextSwitchTo(oldcontext); + + retary = rb_ary_new(); +#if HAVE_RB_BLOCK_CALL + if (args->named) { + res = rb_block_call(pl_mPLtemp, args->id, + RARRAY_LEN(args->ary), + RARRAY_PTR(args->ary), + pl_ary_collect, retary); + } + else { + res = rb_block_call(pl_mPLtemp, args->id, + 1, &args->ary, + pl_ary_collect, retary); + } +#else + res = rb_iterate(pl_func, arg, pl_ary_collect, retary); +#endif + elog(NOTICE, "returned array len is: %ld", RARRAY_LEN(retary) ); + + funcctx->max_calls = RARRAY_LEN(retary) ; + funcctx->user_fctx = (void *)retary; + + } + funcctx = SRF_PERCALL_SETUP(); + + retary = (VALUE)funcctx->user_fctx; + + if (funcctx->call_cntr < funcctx->max_calls) /* do when there is more left to send */ + { + char ** values; + HeapTuple tuple; + size_t idx; + VALUE resary; + + resary = RARRAY_PTR(retary)[funcctx->call_cntr]; + values = (char **)palloc(RARRAY_LEN(resary) * sizeof(char *)); + + for ( idx = 0; idx < RARRAY_LEN(resary); idx++ ) + { + VALUE str = rb_ary_entry( resary, idx ); + if (TYPE(str) != T_STRING) { + str = rb_obj_as_string(str); + } + values[idx] = pstrdup( StringValueCStr( str ) ); + } + + /* build a tuple */ + tuple = BuildTupleFromCStrings(funcctx->attinmeta, values); + + /* make the tuple into a datum */ + result = HeapTupleGetDatum(tuple); + } + + PLRUBY_BEGIN_PROTECT(1); + { + MemoryContext oldcxt; + int rc; + + oldcxt = MemoryContextSwitchTo(plruby_spi_context); + if ((rc = SPI_finish()) != SPI_OK_FINISH) { + elog(ERROR, "SPI_finish() failed : %d", rc); + } + MemoryContextSwitchTo(oldcxt); + } + PLRUBY_END_PROTECT; + + if ( funcctx->call_cntr < funcctx->max_calls ) + { + SRF_RETURN_NEXT(funcctx, result); + } + else + { + SRF_RETURN_DONE(funcctx); + } + + } else if ((rsi->allowedModes & SFRM_Materialize) && rsi->expectedDesc) { VALUE tuple, res, arg; struct pl_arg *args; struct pl_tuple *tpl; diff --git a/src/plruby.c b/src/plruby.c index 69c493b..3d71a6c 100644 --- a/src/plruby.c +++ b/src/plruby.c @@ -958,7 +958,8 @@ pl_compile(struct pl_thread_st *plth, int istrigger) break; } } - + + prodesc->result_is_setof = procStruct->proretset; if (procStruct->proretset) { Oid funcid, functypeid; char functyptype; diff --git a/src/plruby.h b/src/plruby.h index 10cb107..cf57fdf 100644 --- a/src/plruby.h +++ b/src/plruby.h @@ -4,6 +4,7 @@ #include "postgres.h" #include "executor/spi.h" +#include "executor/executor.h" #include "commands/trigger.h" #include "utils/elog.h" #include "utils/builtins.h" @@ -37,7 +38,9 @@ #include "package.h" #include -#if HAVE_ST_H +#if HAVE_RUBY_ST_H +#include +#elif HAVE_ST_H #include #endif @@ -214,6 +217,7 @@ typedef struct pl_proc_desc int result_len; bool result_is_array; bool result_val; + bool result_is_setof; char result_align; int nargs; #if PG_PL_VERSION >= 75 From 6cdc3404d587e485f2cbbc75b6becaf2d78fe33d Mon Sep 17 00:00:00 2001 From: Daniel Berger Date: Thu, 24 Mar 2011 08:55:30 -0600 Subject: [PATCH 03/15] Cleaned up most warnings and removed an unused function in plpl.c. --- src/plpl.c | 28 +--------------------------- src/plruby.c | 1 - 2 files changed, 1 insertion(+), 28 deletions(-) diff --git a/src/plpl.c b/src/plpl.c index 0ee2b63..eecc7c9 100644 --- a/src/plpl.c +++ b/src/plpl.c @@ -547,32 +547,6 @@ struct each_st { TupleDesc tup; }; -static VALUE -pl_each(VALUE obj, struct each_st *st) -{ - VALUE key, value; - char *column; - int attn; - - key = rb_ary_entry(obj, 0); - value = rb_ary_entry(obj, 1); - key = plruby_to_s(key); - column = RSTRING_PTR(key); - attn = SPI_fnumber(st->tup, column); - if (attn <= 0 || st->tup->attrs[attn - 1]->attisdropped) { - rb_raise(pl_ePLruby, "Invalid column name '%s'", column); - } - attn -= 1; - if (TYPE(st->res) != T_ARRAY || !RARRAY_PTR(st->res)) { - rb_raise(pl_ePLruby, "expected an Array"); - } - if (attn >= RARRAY_LEN(st->res)) { - rb_raise(pl_ePLruby, "Invalid column position '%d'", attn); - } - RARRAY_PTR(st->res)[attn] = value; - return Qnil; -} - static HeapTuple pl_tuple_heap(VALUE c, VALUE tuple) { @@ -850,7 +824,7 @@ pl_warn(argc, argv, obj) rb_raise(pl_ePLruby, "invalid syntax"); } PLRUBY_BEGIN_PROTECT(1); - elog(level, RSTRING_PTR(res)); + elog(level, "%s", RSTRING_PTR(res)); PLRUBY_END_PROTECT; return Qnil; } diff --git a/src/plruby.c b/src/plruby.c index 3d71a6c..7ea5843 100644 --- a/src/plruby.c +++ b/src/plruby.c @@ -703,7 +703,6 @@ pl_validator_handler(struct pl_thread_st *plth) Datum PLRUBY_CALL_HANDLER(PG_FUNCTION_ARGS) { - VALUE result; struct pl_thread_st plth; plth.fcinfo = fcinfo; From 3c02339db4c31b7791e929d53b4edd068c9b2145 Mon Sep 17 00:00:00 2001 From: Daniel Berger Date: Mon, 23 May 2011 10:27:49 -0600 Subject: [PATCH 04/15] Re-add Rakefile and gemspec that got lost somehow. --- Rakefile | 48 +++++++++++++++++++++++++++++++++++++++++ postgres-plruby.gemspec | 27 +++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 Rakefile create mode 100644 postgres-plruby.gemspec diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..390e8db --- /dev/null +++ b/Rakefile @@ -0,0 +1,48 @@ +require 'rake' +require 'rake/testtask' +require 'rake/clean' +require 'rbconfig' +include Config + +# TODO: Reorganize code to use Rake compiler. + +CLEAN.include( + '**/*.gem', # Gem files + '**/*.rbc', # Rubinius + '**/*.o', # C object file + '**/*.log', # Ruby extension build log + '**/Makefile', # C Makefile + '**/conftest.dSYM', # OS X build directory + "**/*.#{CONFIG['DLEXT']}" # C shared object +) + +desc 'Build the postgresql-plruby source code' +task :build => [:clean] do + ruby "extconf.rb" + sh "make" +end + +namespace :gem do + desc 'Create the gem' + task :create => [:clean] do + spec = eval(IO.read('postgresql-plruby.gemspec')) + Gem::Builder.new(spec).build + end + + desc 'Install the gem' + task :install => [:create] do + file = Dir["*.gem"].first + sh "gem install #{file}" + end +end + +# TODO: Reorganize tests to make them work. +Rake::TestTask.new do |t| + task :test => [:build] + t.libs << 'ext' + t.test_files = FileList['test/**/*.rb'] + t.warning = true + t.verbose = true +end + +task :default => :test diff --git a/postgres-plruby.gemspec b/postgres-plruby.gemspec new file mode 100644 index 0000000..0e416fc --- /dev/null +++ b/postgres-plruby.gemspec @@ -0,0 +1,27 @@ +require 'rubygems' + +Gem::Specification.new do |spec| + spec.name = 'postgresql-plruby' + spec.version = '0.5.4' + spec.authors = ['Akinori MUSHA', 'Guy Decoux'] + spec.license = 'Ruby' + spec.email = 'akinori@musha.org' + spec.homepage = 'https://github.com/knu/postgresql-plruby' + spec.summary = 'Enable Ruby for use as a procedural language within PostgreSQL' + spec.test_files = Dir['test/test*'] + spec.extensions = ['extconf.rb'] + spec.files = Dir['**/*'].reject{ |f| f.include?('git') || f.include?('tmp') } + + spec.rubyforge_project = 'plruby' + + spec.extra_rdoc_files = [ + 'README.markdown', + 'Changes' + ] + Dir['ext/*.c'] + + spec.description = <<-EOF + PL/Ruby is a loadable procedural language for the PostgreSQL database + system that enables the Ruby language to create functions and trigger + procedures. + EOF +end From 1eefb7c342522c09c8067c02dfb428d23babf0f9 Mon Sep 17 00:00:00 2001 From: Daniel Berger Date: Mon, 23 May 2011 11:14:34 -0600 Subject: [PATCH 05/15] Fixed gemspec name. --- postgres-plruby.gemspec => postgresql-plruby.gemspec | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename postgres-plruby.gemspec => postgresql-plruby.gemspec (100%) diff --git a/postgres-plruby.gemspec b/postgresql-plruby.gemspec similarity index 100% rename from postgres-plruby.gemspec rename to postgresql-plruby.gemspec From 68c1dc2b21b1dfca9645fa5f19324a02946ecb26 Mon Sep 17 00:00:00 2001 From: Daniel Berger Date: Mon, 23 May 2011 14:43:34 -0600 Subject: [PATCH 06/15] Added a post install message to the gemspec. --- postgresql-plruby.gemspec | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/postgresql-plruby.gemspec b/postgresql-plruby.gemspec index 0e416fc..550537d 100644 --- a/postgresql-plruby.gemspec +++ b/postgresql-plruby.gemspec @@ -1,4 +1,5 @@ require 'rubygems' +require 'rbconfig' Gem::Specification.new do |spec| spec.name = 'postgresql-plruby' @@ -24,4 +25,32 @@ Gem::Specification.new do |spec| system that enables the Ruby language to create functions and trigger procedures. EOF + + plruby_bin = 'plruby.' + Config::CONFIG['DLEXT'] + plruby_dir = File.join('postgresql-plruby-' + spec.version.to_s, 'src') + path_to_binary = File.join(Gem.dir, 'gems', plruby_dir, plruby_bin) + + possible_paths = Gem.path.map{ |path| + File.join(path, 'gems', plruby_dir, plruby_bin) + } + + spec.post_install_message = <<-EOF + + Now run the following commands from within a postgresql shell in order + to create the plruby language on in database server: + + create function plruby_call_handler() returns language_handler + as '#{path_to_binary}' + language 'C'; + + create trusted language 'plruby' + handler plruby_call_handler + lancompiler 'PL/Ruby'; + + NOTE: Your actual path to #{plruby_bin} may be different. Possible + paths to the plruby binary are: + + #{possible_paths.join("\n ")} + + EOF end From 496ee5ffd900f3e518987f141774f7bc58e2c65c Mon Sep 17 00:00:00 2001 From: Daniel Berger Date: Mon, 23 May 2011 14:56:17 -0600 Subject: [PATCH 07/15] Updated README to include gem installation and a sample function. --- README.markdown | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/README.markdown b/README.markdown index 4e7c549..7401a4f 100644 --- a/README.markdown +++ b/README.markdown @@ -9,17 +9,25 @@ PL/ruby Prerequisite ------------ -> * ruby 1.8.7 or later (maybe 1.8.6 too) +> * ruby 1.8.7 or later > * postgresql >= 7.3 - All PostgreSQL headers need to be installed. Command (see `INSTALL` in the - directory postgresql-7.x.y) + All PostgreSQL development headers need to be installed. If you installed + using a package manager of some sort, be sure to install the "dev" package. + + If you built from source you can run the following command: make install-all-headers Installation ------------ + If you're installing the gem: + + gem install postgresql-plruby + + If you're doing things the old fashioned way: + ruby extconf.rb make make install @@ -102,6 +110,18 @@ Test (and examples) absolutely safe, because there is nothing a normal user can do with PL/Ruby, to get around access restrictions he/she has. +Sample Function +--------------- + CREATE FUNCTION ruby_max(int4, int4) RETURNS int4 AS ' + if args[0] > args[1] + return args[0] + else + return args[1] + end + ' LANGUAGE 'plruby'; + + select ruby_max(1,2); + Documentation ------------- From 5227fa74f3762b9f5bc6a8c967e2b2cbb6189e3c Mon Sep 17 00:00:00 2001 From: Daniel Berger Date: Tue, 24 May 2011 10:23:58 -0600 Subject: [PATCH 08/15] Updated the gem installation instructions and added another example. --- README.markdown | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/README.markdown b/README.markdown index 7401a4f..0864a93 100644 --- a/README.markdown +++ b/README.markdown @@ -26,6 +26,10 @@ Installation gem install postgresql-plruby + If you want to allow the ability to require external libraries: + + gem install postgresql-plruby -- --with-safe-level=0 + If you're doing things the old fashioned way: ruby extconf.rb @@ -110,8 +114,8 @@ Test (and examples) absolutely safe, because there is nothing a normal user can do with PL/Ruby, to get around access restrictions he/she has. -Sample Function ---------------- +Sample Functions +---------------- CREATE FUNCTION ruby_max(int4, int4) RETURNS int4 AS ' if args[0] > args[1] return args[0] @@ -122,6 +126,12 @@ Sample Function select ruby_max(1,2); + CREATE FUNCTION ruby_max2(x int4, y int4) RETURNS int4 AS ' + return x > y ? x : y + ' LANGUAGE 'plruby'; + + select ruby_max2(7,8); + Documentation ------------- From b25da0a3daf7b11df81baa0474ccc4c8430085f3 Mon Sep 17 00:00:00 2001 From: Daniel Berger Date: Tue, 24 May 2011 10:27:34 -0600 Subject: [PATCH 09/15] Added 'globegit' as prefix to gem name. --- postgresql-plruby.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/postgresql-plruby.gemspec b/postgresql-plruby.gemspec index 550537d..2e42c3f 100644 --- a/postgresql-plruby.gemspec +++ b/postgresql-plruby.gemspec @@ -2,7 +2,7 @@ require 'rubygems' require 'rbconfig' Gem::Specification.new do |spec| - spec.name = 'postgresql-plruby' + spec.name = 'globegit-postgresql-plruby' spec.version = '0.5.4' spec.authors = ['Akinori MUSHA', 'Guy Decoux'] spec.license = 'Ruby' From e834e863f97f309a071f461274e51b3b192ee956 Mon Sep 17 00:00:00 2001 From: Daniel Berger Date: Tue, 24 May 2011 15:23:09 -0600 Subject: [PATCH 10/15] Updated post install message to display proper installation directory (forgot 'globegit' as part of name). --- postgresql-plruby.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/postgresql-plruby.gemspec b/postgresql-plruby.gemspec index 2e42c3f..637283c 100644 --- a/postgresql-plruby.gemspec +++ b/postgresql-plruby.gemspec @@ -27,7 +27,7 @@ Gem::Specification.new do |spec| EOF plruby_bin = 'plruby.' + Config::CONFIG['DLEXT'] - plruby_dir = File.join('postgresql-plruby-' + spec.version.to_s, 'src') + plruby_dir = File.join(spec.name + '-' + spec.version.to_s, 'src') path_to_binary = File.join(Gem.dir, 'gems', plruby_dir, plruby_bin) possible_paths = Gem.path.map{ |path| From 5902376a8af1f1158488c0f419e74c62ed898bde Mon Sep 17 00:00:00 2001 From: David Salisbury Date: Tue, 27 Sep 2011 22:53:38 +0000 Subject: [PATCH 11/15] editing extconf.rb to add --shared argument to the C compiler --- extconf.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/extconf.rb b/extconf.rb index 86cfc58..596efcf 100755 --- a/extconf.rb +++ b/extconf.rb @@ -86,6 +86,9 @@ def rule(target, clean = nil) include_dir = `#{pg_config} --includedir`.strip $CFLAGS << " -I" << include_dir $CFLAGS << " -I" << `#{pg_config} --includedir-server`.strip +# das addition below +$CFLAGS << " --shared" + if safe = with_config("safe-level") safe = Integer(safe) From 5818d6a141b42dc35ed0f0aea966a369d92b294e Mon Sep 17 00:00:00 2001 From: Ying Tsen Hong Date: Thu, 6 Oct 2011 14:35:33 -0600 Subject: [PATCH 12/15] Remove the lancompiler option from "create trusted language" statement. The lancompiler option was only valid in postgres 7 and even there, it was not used --- README.markdown | 3 +-- extconf.rb | 3 +-- postgresql-plruby.gemspec | 3 +-- test/conv_bitstring/b.rb | 3 +-- test/conv_geometry/b.rb | 3 +-- test/conv_network/b.rb | 3 +-- test/plp/b.rb | 3 +-- test/plt/b.rb | 3 +-- test/range/b.rb | 3 +-- 9 files changed, 9 insertions(+), 18 deletions(-) diff --git a/README.markdown b/README.markdown index 0864a93..e501dc5 100644 --- a/README.markdown +++ b/README.markdown @@ -104,8 +104,7 @@ Test (and examples) language 'C'; create trusted language 'plruby' - handler plruby_call_handler - lancompiler 'PL/Ruby'; + handler plruby_call_handler; The `trusted` keyword on `create language` tells PostgreSQL, diff --git a/extconf.rb b/extconf.rb index 596efcf..836f63c 100755 --- a/extconf.rb +++ b/extconf.rb @@ -56,8 +56,7 @@ def create_lang(version = 74, suffix = '', safe = 0) language '#{language}'; create #{trusted} language 'plruby#{suffix}' - handler plruby#{suffix}_call_handler - lancompiler 'PL/Ruby#{suffix}'; + handler plruby#{suffix}_call_handler; ======================================================================== EOT diff --git a/postgresql-plruby.gemspec b/postgresql-plruby.gemspec index 637283c..c423e7f 100644 --- a/postgresql-plruby.gemspec +++ b/postgresql-plruby.gemspec @@ -44,8 +44,7 @@ Gem::Specification.new do |spec| language 'C'; create trusted language 'plruby' - handler plruby_call_handler - lancompiler 'PL/Ruby'; + handler plruby_call_handler; NOTE: Your actual path to #{plruby_bin} may be different. Possible paths to the plruby binary are: diff --git a/test/conv_bitstring/b.rb b/test/conv_bitstring/b.rb index 6310536..a0c7b2b 100755 --- a/test/conv_bitstring/b.rb +++ b/test/conv_bitstring/b.rb @@ -36,8 +36,7 @@ language '#{language}'; create trusted procedural language 'plruby#{suffix}' - handler plruby#{suffix}_call_handler - lancompiler 'PL/Ruby'; + handler plruby#{suffix}_call_handler; EOF f.close rescue diff --git a/test/conv_geometry/b.rb b/test/conv_geometry/b.rb index 6310536..a0c7b2b 100755 --- a/test/conv_geometry/b.rb +++ b/test/conv_geometry/b.rb @@ -36,8 +36,7 @@ language '#{language}'; create trusted procedural language 'plruby#{suffix}' - handler plruby#{suffix}_call_handler - lancompiler 'PL/Ruby'; + handler plruby#{suffix}_call_handler; EOF f.close rescue diff --git a/test/conv_network/b.rb b/test/conv_network/b.rb index 6310536..a0c7b2b 100755 --- a/test/conv_network/b.rb +++ b/test/conv_network/b.rb @@ -36,8 +36,7 @@ language '#{language}'; create trusted procedural language 'plruby#{suffix}' - handler plruby#{suffix}_call_handler - lancompiler 'PL/Ruby'; + handler plruby#{suffix}_call_handler; EOF f.close rescue diff --git a/test/plp/b.rb b/test/plp/b.rb index 778a624..c4d5956 100755 --- a/test/plp/b.rb +++ b/test/plp/b.rb @@ -25,8 +25,7 @@ language '#{language}'; create trusted procedural language 'plruby#{suffix}' - handler plruby#{suffix}_call_handler - lancompiler 'PL/Ruby'; + handler plruby#{suffix}_call_handler; EOF f.close rescue diff --git a/test/plt/b.rb b/test/plt/b.rb index 778a624..c4d5956 100755 --- a/test/plt/b.rb +++ b/test/plt/b.rb @@ -25,8 +25,7 @@ language '#{language}'; create trusted procedural language 'plruby#{suffix}' - handler plruby#{suffix}_call_handler - lancompiler 'PL/Ruby'; + handler plruby#{suffix}_call_handler; EOF f.close rescue diff --git a/test/range/b.rb b/test/range/b.rb index 6310536..a0c7b2b 100755 --- a/test/range/b.rb +++ b/test/range/b.rb @@ -36,8 +36,7 @@ language '#{language}'; create trusted procedural language 'plruby#{suffix}' - handler plruby#{suffix}_call_handler - lancompiler 'PL/Ruby'; + handler plruby#{suffix}_call_handler; EOF f.close rescue From 1c5e3f4b367df01e2cca09d7290addd6b84a5d52 Mon Sep 17 00:00:00 2001 From: Ying Tsen Hong Date: Thu, 6 Oct 2011 14:36:46 -0600 Subject: [PATCH 13/15] Removed invalid --shared flag. No such thing. --- extconf.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/extconf.rb b/extconf.rb index 836f63c..cb97dc8 100755 --- a/extconf.rb +++ b/extconf.rb @@ -85,8 +85,6 @@ def rule(target, clean = nil) include_dir = `#{pg_config} --includedir`.strip $CFLAGS << " -I" << include_dir $CFLAGS << " -I" << `#{pg_config} --includedir-server`.strip -# das addition below -$CFLAGS << " --shared" if safe = with_config("safe-level") From d887b41f2a80b173a09e32f7292515eaf31d35c5 Mon Sep 17 00:00:00 2001 From: Ying Tsen Hong Date: Fri, 7 Oct 2011 15:37:58 -0600 Subject: [PATCH 14/15] fix bitstring names for postgres 9.1 --- src/conversions/bitstring/plruby_bitstring.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/conversions/bitstring/plruby_bitstring.c b/src/conversions/bitstring/plruby_bitstring.c index fdb2253..3d74617 100644 --- a/src/conversions/bitstring/plruby_bitstring.c +++ b/src/conversions/bitstring/plruby_bitstring.c @@ -195,8 +195,14 @@ name_(VALUE obj, VALUE a) \ } BIT_OPERATOR(pl_bit_add, bitcat); +#if PG_PL_VERSION >= 91 +/* avoid the names bitand and bitor, since they are C++ keywords */ +BIT_OPERATOR(pl_bit_and, bit_and); +BIT_OPERATOR(pl_bit_or, bit_or); +#else BIT_OPERATOR(pl_bit_and, bitand); BIT_OPERATOR(pl_bit_or, bitor); +#endif BIT_OPERATOR(pl_bit_xor, bitxor); static VALUE From 2de7efd2543952fdbb4507bc263d7811ce243d28 Mon Sep 17 00:00:00 2001 From: Ying Tsen Hong Date: Fri, 7 Oct 2011 15:38:48 -0600 Subject: [PATCH 15/15] add expected output file for bitstring postgres 9.1 --- test/conv_network/test.expected.91 | 237 +++++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 test/conv_network/test.expected.91 diff --git a/test/conv_network/test.expected.91 b/test/conv_network/test.expected.91 new file mode 100644 index 0000000..35c52b1 --- /dev/null +++ b/test/conv_network/test.expected.91 @@ -0,0 +1,237 @@ +create table pl_inet ( + host text, abbrev text, masklen int, + network inet, netmask inet, first inet, last inet +); +create or replace function inet_val(inet) returns pl_inet as ' + a = args[0] + [a.host, a.abbrev, a.masklen, a.network, a.netmask, + a.first, a.last] + ' language 'plruby'; +select * from inet_val('192.168.1'::cidr); + host | abbrev | masklen | network | netmask | first | last +-------------+----------------+---------+----------------+---------------+----------------+--------------- + 192.168.1.0 | 192.168.1.0/24 | 24 | 192.168.1.0/24 | 255.255.255.0 | 192.168.1.0/24 | 192.168.1.255 +(1 row) + +select * from inet_val('192.168.1.226/24'::inet); + host | abbrev | masklen | network | netmask | first | last +---------------+------------------+---------+----------------+---------------+----------------+--------------- + 192.168.1.226 | 192.168.1.226/24 | 24 | 192.168.1.0/24 | 255.255.255.0 | 192.168.1.0/24 | 192.168.1.255 +(1 row) + +select * from inet_val('192.168.1.0/24'::cidr); + host | abbrev | masklen | network | netmask | first | last +-------------+----------------+---------+----------------+---------------+----------------+--------------- + 192.168.1.0 | 192.168.1.0/24 | 24 | 192.168.1.0/24 | 255.255.255.0 | 192.168.1.0/24 | 192.168.1.255 +(1 row) + +select * from inet_val('192.168.1.226'::inet); + host | abbrev | masklen | network | netmask | first | last +---------------+---------------+---------+---------------+-----------------+---------------+--------------- + 192.168.1.226 | 192.168.1.226 | 32 | 192.168.1.226 | 255.255.255.255 | 192.168.1.226 | 192.168.1.226 +(1 row) + +select * from inet_val('192.168.1'::cidr); + host | abbrev | masklen | network | netmask | first | last +-------------+----------------+---------+----------------+---------------+----------------+--------------- + 192.168.1.0 | 192.168.1.0/24 | 24 | 192.168.1.0/24 | 255.255.255.0 | 192.168.1.0/24 | 192.168.1.255 +(1 row) + +select * from inet_val('192.168.1.0/24'::inet); + host | abbrev | masklen | network | netmask | first | last +-------------+----------------+---------+----------------+---------------+----------------+--------------- + 192.168.1.0 | 192.168.1.0/24 | 24 | 192.168.1.0/24 | 255.255.255.0 | 192.168.1.0/24 | 192.168.1.255 +(1 row) + +select * from inet_val('192.168.1'::cidr); + host | abbrev | masklen | network | netmask | first | last +-------------+----------------+---------+----------------+---------------+----------------+--------------- + 192.168.1.0 | 192.168.1.0/24 | 24 | 192.168.1.0/24 | 255.255.255.0 | 192.168.1.0/24 | 192.168.1.255 +(1 row) + +select * from inet_val('192.168.1.0/25'::inet); + host | abbrev | masklen | network | netmask | first | last +-------------+----------------+---------+----------------+-----------------+----------------+--------------- + 192.168.1.0 | 192.168.1.0/25 | 25 | 192.168.1.0/25 | 255.255.255.128 | 192.168.1.0/25 | 192.168.1.127 +(1 row) + +select * from inet_val('192.168.1'::cidr); + host | abbrev | masklen | network | netmask | first | last +-------------+----------------+---------+----------------+---------------+----------------+--------------- + 192.168.1.0 | 192.168.1.0/24 | 24 | 192.168.1.0/24 | 255.255.255.0 | 192.168.1.0/24 | 192.168.1.255 +(1 row) + +select * from inet_val('192.168.1.255/24'::inet); + host | abbrev | masklen | network | netmask | first | last +---------------+------------------+---------+----------------+---------------+----------------+--------------- + 192.168.1.255 | 192.168.1.255/24 | 24 | 192.168.1.0/24 | 255.255.255.0 | 192.168.1.0/24 | 192.168.1.255 +(1 row) + +select * from inet_val('192.168.1'::cidr); + host | abbrev | masklen | network | netmask | first | last +-------------+----------------+---------+----------------+---------------+----------------+--------------- + 192.168.1.0 | 192.168.1.0/24 | 24 | 192.168.1.0/24 | 255.255.255.0 | 192.168.1.0/24 | 192.168.1.255 +(1 row) + +select * from inet_val('192.168.1.255/25'::inet); + host | abbrev | masklen | network | netmask | first | last +---------------+------------------+---------+------------------+-----------------+------------------+--------------- + 192.168.1.255 | 192.168.1.255/25 | 25 | 192.168.1.128/25 | 255.255.255.128 | 192.168.1.128/25 | 192.168.1.255 +(1 row) + +select * from inet_val('10'::cidr); + host | abbrev | masklen | network | netmask | first | last +----------+------------+---------+------------+-----------+------------+---------------- + 10.0.0.0 | 10.0.0.0/8 | 8 | 10.0.0.0/8 | 255.0.0.0 | 10.0.0.0/8 | 10.255.255.255 +(1 row) + +select * from inet_val('10.1.2.3/8'::inet); + host | abbrev | masklen | network | netmask | first | last +----------+------------+---------+------------+-----------+------------+---------------- + 10.1.2.3 | 10.1.2.3/8 | 8 | 10.0.0.0/8 | 255.0.0.0 | 10.0.0.0/8 | 10.255.255.255 +(1 row) + +select * from inet_val('10.0.0.0'::cidr); + host | abbrev | masklen | network | netmask | first | last +----------+----------+---------+----------+-----------------+----------+---------- + 10.0.0.0 | 10.0.0.0 | 32 | 10.0.0.0 | 255.255.255.255 | 10.0.0.0 | 10.0.0.0 +(1 row) + +select * from inet_val('10.1.2.3/8'::inet); + host | abbrev | masklen | network | netmask | first | last +----------+------------+---------+------------+-----------+------------+---------------- + 10.1.2.3 | 10.1.2.3/8 | 8 | 10.0.0.0/8 | 255.0.0.0 | 10.0.0.0/8 | 10.255.255.255 +(1 row) + +select * from inet_val('10.1.2.3'::cidr); + host | abbrev | masklen | network | netmask | first | last +----------+----------+---------+----------+-----------------+----------+---------- + 10.1.2.3 | 10.1.2.3 | 32 | 10.1.2.3 | 255.255.255.255 | 10.1.2.3 | 10.1.2.3 +(1 row) + +select * from inet_val('10.1.2.3/32'::inet); + host | abbrev | masklen | network | netmask | first | last +----------+----------+---------+----------+-----------------+----------+---------- + 10.1.2.3 | 10.1.2.3 | 32 | 10.1.2.3 | 255.255.255.255 | 10.1.2.3 | 10.1.2.3 +(1 row) + +select * from inet_val('10.1.2'::cidr); + host | abbrev | masklen | network | netmask | first | last +----------+-------------+---------+-------------+---------------+-------------+------------ + 10.1.2.0 | 10.1.2.0/24 | 24 | 10.1.2.0/24 | 255.255.255.0 | 10.1.2.0/24 | 10.1.2.255 +(1 row) + +select * from inet_val('10.1.2.3/24'::inet); + host | abbrev | masklen | network | netmask | first | last +----------+-------------+---------+-------------+---------------+-------------+------------ + 10.1.2.3 | 10.1.2.3/24 | 24 | 10.1.2.0/24 | 255.255.255.0 | 10.1.2.0/24 | 10.1.2.255 +(1 row) + +select * from inet_val('10.1'::cidr); + host | abbrev | masklen | network | netmask | first | last +----------+-------------+---------+-------------+-------------+-------------+-------------- + 10.1.0.0 | 10.1.0.0/16 | 16 | 10.1.0.0/16 | 255.255.0.0 | 10.1.0.0/16 | 10.1.255.255 +(1 row) + +select * from inet_val('10.1.2.3/16'::inet); + host | abbrev | masklen | network | netmask | first | last +----------+-------------+---------+-------------+-------------+-------------+-------------- + 10.1.2.3 | 10.1.2.3/16 | 16 | 10.1.0.0/16 | 255.255.0.0 | 10.1.0.0/16 | 10.1.255.255 +(1 row) + +select * from inet_val('10'::cidr); + host | abbrev | masklen | network | netmask | first | last +----------+------------+---------+------------+-----------+------------+---------------- + 10.0.0.0 | 10.0.0.0/8 | 8 | 10.0.0.0/8 | 255.0.0.0 | 10.0.0.0/8 | 10.255.255.255 +(1 row) + +select * from inet_val('10.1.2.3/8'::inet); + host | abbrev | masklen | network | netmask | first | last +----------+------------+---------+------------+-----------+------------+---------------- + 10.1.2.3 | 10.1.2.3/8 | 8 | 10.0.0.0/8 | 255.0.0.0 | 10.0.0.0/8 | 10.255.255.255 +(1 row) + +select * from inet_val('10'::cidr); + host | abbrev | masklen | network | netmask | first | last +----------+------------+---------+------------+-----------+------------+---------------- + 10.0.0.0 | 10.0.0.0/8 | 8 | 10.0.0.0/8 | 255.0.0.0 | 10.0.0.0/8 | 10.255.255.255 +(1 row) + +select * from inet_val('11.1.2.3/8'::inet); + host | abbrev | masklen | network | netmask | first | last +----------+------------+---------+------------+-----------+------------+---------------- + 11.1.2.3 | 11.1.2.3/8 | 8 | 11.0.0.0/8 | 255.0.0.0 | 11.0.0.0/8 | 11.255.255.255 +(1 row) + +select * from inet_val('10'::cidr); + host | abbrev | masklen | network | netmask | first | last +----------+------------+---------+------------+-----------+------------+---------------- + 10.0.0.0 | 10.0.0.0/8 | 8 | 10.0.0.0/8 | 255.0.0.0 | 10.0.0.0/8 | 10.255.255.255 +(1 row) + +select * from inet_val('9.1.2.3/8'::inet); + host | abbrev | masklen | network | netmask | first | last +---------+-----------+---------+-----------+-----------+-----------+--------------- + 9.1.2.3 | 9.1.2.3/8 | 8 | 9.0.0.0/8 | 255.0.0.0 | 9.0.0.0/8 | 9.255.255.255 +(1 row) + +select * from inet_val('10:23::f1'::cidr); + host | abbrev | masklen | network | netmask | first | last +-----------+-----------+---------+-----------+-----------------------------------------+-----------+----------- + 10:23::f1 | 10:23::f1 | 128 | 10:23::f1 | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff | 10:23::f1 | 10:23::f1 +(1 row) + +select * from inet_val('10:23::f1/64'::inet); + host | abbrev | masklen | network | netmask | first | last +-----------+--------------+---------+------------+-----------------------+------------+---------------------------- + 10:23::f1 | 10:23::f1/64 | 64 | 10:23::/64 | ffff:ffff:ffff:ffff:: | 10:23::/64 | 10:23::ffff:ffff:ffff:ffff +(1 row) + +select * from inet_val('10:23::8000/113'::cidr); + host | abbrev | masklen | network | netmask | first | last +-------------+-----------------+---------+-----------------+-----------------------------------------+-----------------+------------- + 10:23::8000 | 10:23::8000/113 | 113 | 10:23::8000/113 | ffff:ffff:ffff:ffff:ffff:ffff:ffff:8000 | 10:23::8000/113 | 10:23::ffff +(1 row) + +select * from inet_val('10:23::ffff'::inet); + host | abbrev | masklen | network | netmask | first | last +-------------+-------------+---------+-------------+-----------------------------------------+-------------+------------- + 10:23::ffff | 10:23::ffff | 128 | 10:23::ffff | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff | 10:23::ffff | 10:23::ffff +(1 row) + +select * from inet_val('::ffff:1.2.3.4'::cidr); + host | abbrev | masklen | network | netmask | first | last +----------------+----------------+---------+----------------+-----------------------------------------+----------------+---------------- + ::ffff:1.2.3.4 | ::ffff:1.2.3.4 | 128 | ::ffff:1.2.3.4 | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff | ::ffff:1.2.3.4 | ::ffff:1.2.3.4 +(1 row) + +select * from inet_val('::4.3.2.1/24'::inet); + host | abbrev | masklen | network | netmask | first | last +-----------+--------------+---------+---------+-------------+-------+------------------------------------ + ::4.3.2.1 | ::4.3.2.1/24 | 24 | ::/24 | ffff:ff00:: | ::/24 | 0:ff:ffff:ffff:ffff:ffff:ffff:ffff +(1 row) + +create or replace function mac_cmp(macaddr, macaddr) returns int as ' + args[0] <=> args[1] +' language 'plruby'; +select mac_cmp('00:07:E9:85:3E:C5'::macaddr, '00:E0:29:3E:E7:25'::macaddr); + mac_cmp +--------- + -1 +(1 row) + +create or replace function mac_trunc(macaddr) returns macaddr as ' + args[0].truncate +' language 'plruby'; +select mac_trunc('00:07:E9:85:3E:C5'::macaddr); + mac_trunc +------------------- + 00:07:e9:00:00:00 +(1 row) + +select mac_trunc('00:E0:29:3E:E7:25'::macaddr); + mac_trunc +------------------- + 00:e0:29:00:00:00 +(1 row) +