Re: [PATCHES] PL/Perl regression tests with use_strict

2005-08-23 Thread Andrew Dunstan
Michael Fuhr said:
> On Tue, Aug 23, 2005 at 10:30:51PM -0600, Michael Fuhr wrote:
>> Global symbol "$x" requires explicit package name at (eval 3) line 1.
>>
>> If I'm reading the Perl source code correctly (pp_ctl.c), the number
>> following "eval" comes from a variable named PL_evalseq that's
>> incremented each time it appears in one of these messages.  It looks
>> like we'd have to munge the error message to get rid of that.
>
> Hmmm...tests suggest that we might be able to munge $@ in the
> mk*safefunc functions.  That is, instead of doing
>
>  return eval($stuff);
>
> we might be able to do
>
>  my $retval = eval($stuff);
>  $@ =~ s/ \(eval \d+\) / /g if $@;
>  return $retval;
>
> That would convert messages like
>
>  Global symbol "$x" requires explicit package name at (eval 3) line 1.
>
> into
>
>  Global symbol "$x" requires explicit package name at line 1.
>
> Is that what you're looking for?  So far I've done only simple tests in
> standalone embedded Perl programs, so I don't know if this approach
> would work in PL/Perl or have unintended effects.

It  would probably be more efficient and less convoluted to munge this in a
__DIE__ handler. The we wouldn't need the extra level of eval.

e.g.

$SIG{__DIE__} =
  sub { my $msg = $_[0]; $msg =~ s/\(eval \d+\) //; die $msg; };

cheers

andrew




---(end of broadcast)---
TIP 9: In versions below 8.0, the planner will ignore your desire to
   choose an index scan if your joining column's datatypes do not
   match


Re: [PATCHES] PL/Perl regression tests with use_strict

2005-08-23 Thread Michael Fuhr
On Tue, Aug 23, 2005 at 10:30:51PM -0600, Michael Fuhr wrote:
> Global symbol "$x" requires explicit package name at (eval 3) line 1.
> 
> If I'm reading the Perl source code correctly (pp_ctl.c), the number
> following "eval" comes from a variable named PL_evalseq that's
> incremented each time it appears in one of these messages.  It looks
> like we'd have to munge the error message to get rid of that.

Hmmm...tests suggest that we might be able to munge $@ in the
mk*safefunc functions.  That is, instead of doing

  return eval($stuff);

we might be able to do

  my $retval = eval($stuff);
  $@ =~ s/ \(eval \d+\) / /g if $@;
  return $retval;

That would convert messages like 

  Global symbol "$x" requires explicit package name at (eval 3) line 1.

into

  Global symbol "$x" requires explicit package name at line 1.

Is that what you're looking for?  So far I've done only simple tests
in standalone embedded Perl programs, so I don't know if this approach
would work in PL/Perl or have unintended effects.

-- 
Michael Fuhr

---(end of broadcast)---
TIP 9: In versions below 8.0, the planner will ignore your desire to
   choose an index scan if your joining column's datatypes do not
   match


Re: [PATCHES] PL/Perl regression tests with use_strict

2005-08-23 Thread Michael Fuhr
On Tue, Aug 23, 2005 at 11:58:25PM -0400, Tom Lane wrote:
> Michael Fuhr <[EMAIL PROTECTED]> writes:
> > Here's an updated version of the PL/Perl regression test patch that
> > works with Andrew Dunstan's strict mode patch, both when use_strict
> > is enabled and when it's disabled.  The variant of plperl_elog.out
> > is no longer needed.
> 
> Actually, the main reason I didn't apply the prior version right 
> away was that the variant .out file was bugging me.  Why does the
> error report contain a line number that's dependent on implementation
> internals in the first place?  Changing it to a different number
> doesn't seem like an improvement; can't we get rid of that entirely?

Actually, I just noticed that the varying number isn't a line number
but rather a sequence number.  Example:

% cat foo
#!/usr/bin/perl
use strict;
use warnings;
my $code = '$x = 123;';
eval $code; print $@;
eval $code; print $@;
eval $code; print $@;

% ./foo
Global symbol "$x" requires explicit package name at (eval 1) line 1.
Global symbol "$x" requires explicit package name at (eval 2) line 1.
Global symbol "$x" requires explicit package name at (eval 3) line 1.

If I'm reading the Perl source code correctly (pp_ctl.c), the number
following "eval" comes from a variable named PL_evalseq that's
incremented each time it appears in one of these messages.  It looks
like we'd have to munge the error message to get rid of that.

-- 
Michael Fuhr

---(end of broadcast)---
TIP 6: explain analyze is your friend


Re: [PATCHES] plperl strict mode and associated fixes

2005-08-23 Thread Tom Lane
Michael Fuhr <[EMAIL PROTECTED]> writes:
> Hmmm...even if the "plperl" custom variable class isn't defined in
> postgresql.conf, plperl.use_strict springs into existence when the
> interpreter is initialized:

Yes, this is per spec.  The "custom class" concept is only intended
to allow you to put things into postgresql.conf before the associated
shared library is loaded; it is not intended to stop the shared library
from defining GUC variables that you didn't see fit to put values into
postgresql.conf for.

regards, tom lane

---(end of broadcast)---
TIP 4: Have you searched our list archives?

   http://archives.postgresql.org


Re: [PATCHES] PL/Perl regression tests with use_strict

2005-08-23 Thread Tom Lane
Michael Fuhr <[EMAIL PROTECTED]> writes:
> Here's an updated version of the PL/Perl regression test patch that
> works with Andrew Dunstan's strict mode patch, both when use_strict
> is enabled and when it's disabled.  The variant of plperl_elog.out
> is no longer needed.

Actually, the main reason I didn't apply the prior version right 
away was that the variant .out file was bugging me.  Why does the
error report contain a line number that's dependent on implementation
internals in the first place?  Changing it to a different number
doesn't seem like an improvement; can't we get rid of that entirely?

regards, tom lane

---(end of broadcast)---
TIP 9: In versions below 8.0, the planner will ignore your desire to
   choose an index scan if your joining column's datatypes do not
   match


[PATCHES] Work-in-progress referential action trigger timing patch

2005-08-23 Thread Stephan Szabo

Here's my current work in progress for 8.1 devel related to fixing the
timing issues with referential actions having their checks run on
intermediate states.  I've only put in a simple test that failed against
8.0 in the regression patch and regression still passes for me.  There's
still an outstanding question of whether looping gives the correct result
in the presence of explicit inserts and set constraints immediate in
before triggers.Index: src/backend/commands/trigger.c
===
RCS file: /projects/cvsroot/pgsql/src/backend/commands/trigger.c,v
retrieving revision 1.193
diff -c -r1.193 trigger.c
*** src/backend/commands/trigger.c  23 Aug 2005 22:40:08 -  1.193
--- src/backend/commands/trigger.c  24 Aug 2005 03:24:48 -
***
*** 2281,2286 
--- 2280,2286 
TriggerDesc *trigdesc = NULL;
FmgrInfo   *finfo = NULL;
Instrumentation *instr = NULL;
+   bool last_relation_loaded = false;
  
/* Make a per-tuple memory context for trigger function calls */
per_tuple_context =
***
*** 2309,2314 
--- 2309,2328 
 */
if (rel == NULL || rel->rd_id != event->ate_relid)
{
+   bool found_relation_in_estate = false;
+   if (last_relation_loaded) {
+   if (rel)
+   heap_close(rel, NoLock);
+   if (trigdesc)
+   FreeTriggerDesc(trigdesc);
+   if (finfo)
+   pfree(finfo);
+   Assert(instr == NULL);  /* never used 
in this case */
+   rel = NULL;
+   trigdesc = NULL;
+   finfo = NULL;
+   }
+ 
if (estate)
{
/* Find target relation among estate's 
result rels */
***
*** 2324,2348 
rInfo++;
nr--;
}
!   if (nr <= 0)
/* should not happen */
!   elog(ERROR, "could not find 
relation %u among query result relations",
!event->ate_relid);
!   rel = rInfo->ri_RelationDesc;
!   trigdesc = rInfo->ri_TrigDesc;
!   finfo = rInfo->ri_TrigFunctions;
!   instr = rInfo->ri_TrigInstrument;
}
-   else
-   {
-   /* Hard way: we manage the resources 
for ourselves */
-   if (rel)
-   heap_close(rel, NoLock);
-   if (trigdesc)
-   FreeTriggerDesc(trigdesc);
-   if (finfo)
-   pfree(finfo);
-   Assert(instr == NULL);  /* never used 
in this case */
  
/*
 * We assume that an appropriate lock 
is still held by
 * the executor, so grab no new lock 
here.
--- 2338,2355 
rInfo++;
nr--;
}
!   if (nr > 0) 
!   {
!   rel = rInfo->ri_RelationDesc;
!   trigdesc = rInfo->ri_TrigDesc;
!   finfo = rInfo->ri_TrigFunctions;
!   instr = 
rInfo->ri_TrigInstrument;
!   found_relation_in_estate = true;
!   }
}
  
+   if (!found_relation_in_estate) 
+   {
/*
 * We assume that an appropriate lock 
is still held by
 * the executor, so grab no new lock 
her

Re: [PATCHES] plperl strict mode and associated fixes

2005-08-23 Thread Michael Fuhr
On Tue, Aug 23, 2005 at 09:12:10PM -0400, Andrew Dunstan wrote:
> The attached patch completes (I hope) the work begun by Michael Fuhr in 
> an earlier unapplied patch, and makes strict mode work as recently 
> discussed. I moved the embedded strings out of the calling functions 
> into global macros to try to make the code a little more readable.
> 
> Unfortunately we can't have regression tests for this because it relies 
> on a custom variable class.

Hmmm...even if the "plperl" custom variable class isn't defined in
postgresql.conf, plperl.use_strict springs into existence when the
interpreter is initialized:

test=> SET plperl.use_strict TO on;
ERROR:  unrecognized configuration parameter "plperl.use_strict"
test=> CREATE FUNCTION foo() RETURNS void AS  LANGUAGE plperl;
CREATE FUNCTION
test=> SET plperl.use_strict TO on;
SET
test=> CREATE OR REPLACE FUNCTION foo() RETURNS void AS $$ $x = 1234; $$ 
LANGUAGE plperl;
ERROR:  creation of Perl function failed: Global symbol "$x" requires explicit 
package name at (eval 8) line 1.
test=> SET plperl.use_strict TO off;
SET
test=> CREATE OR REPLACE FUNCTION foo() RETURNS void AS $$ $x = 1234; $$ 
LANGUAGE plperl;
CREATE FUNCTION

Is such automatic creation of a GUC variable intended?  If so,
couldn't you exploit that in regression tests?

-- 
Michael Fuhr

---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


Re: [PATCHES] PL/Perl regression tests with use_strict

2005-08-23 Thread Michael Fuhr
On Sat, Aug 20, 2005 at 01:52:42PM -0600, Michael Fuhr wrote:
> The attached patch allows the PL/Perl regression tests to pass when
> use_strict is enabled.  I've also attached a variant of plperl_elog.out
> to account for an elog() message that shows a different line number
> when run under use_strict.

Here's an updated version of the PL/Perl regression test patch that
works with Andrew Dunstan's strict mode patch, both when use_strict
is enabled and when it's disabled.  The variant of plperl_elog.out
is no longer needed.

-- 
Michael Fuhr
Index: src/pl/plperl/expected/plperl.out
===
RCS file: /projects/cvsroot/pgsql/src/pl/plperl/expected/plperl.out,v
retrieving revision 1.4
diff -c -r1.4 plperl.out
*** src/pl/plperl/expected/plperl.out   12 Jul 2005 01:16:22 -  1.4
--- src/pl/plperl/expected/plperl.out   24 Aug 2005 02:17:08 -
***
*** 336,342 
  -- Test return_next
  --
  CREATE OR REPLACE FUNCTION perl_srf_rn() RETURNS SETOF RECORD AS $$
! $i = 0;
  for ("World", "PostgreSQL", "PL/Perl") {
  return_next({f1=>++$i, f2=>'Hello', f3=>$_});
  }
--- 336,342 
  -- Test return_next
  --
  CREATE OR REPLACE FUNCTION perl_srf_rn() RETURNS SETOF RECORD AS $$
! my $i = 0;
  for ("World", "PostgreSQL", "PL/Perl") {
  return_next({f1=>++$i, f2=>'Hello', f3=>$_});
  }
***
*** 354,361 
  -- Test spi_query/spi_fetchrow
  --
  CREATE OR REPLACE FUNCTION perl_spi_func() RETURNS SETOF INTEGER AS $$
! $x = spi_query("select 1 as a union select 2 as a");
! while (defined ($y = spi_fetchrow($x))) {
  return_next($y->{a});
  }
  return;
--- 354,361 
  -- Test spi_query/spi_fetchrow
  --
  CREATE OR REPLACE FUNCTION perl_spi_func() RETURNS SETOF INTEGER AS $$
! my $x = spi_query("select 1 as a union select 2 as a");
! while (defined (my $y = spi_fetchrow($x))) {
  return_next($y->{a});
  }
  return;
Index: src/pl/plperl/expected/plperl_elog.out
===
RCS file: /projects/cvsroot/pgsql/src/pl/plperl/expected/plperl_elog.out,v
retrieving revision 1.2
diff -c -r1.2 plperl_elog.out
*** src/pl/plperl/expected/plperl_elog.out  7 Jul 2005 04:41:01 -   
1.2
--- src/pl/plperl/expected/plperl_elog.out  24 Aug 2005 02:17:08 -
***
*** 19,25 
  
  $$;
  select perl_warn('implicit elog via warn');
! NOTICE:  implicit elog via warn at (eval 7) line 4.
  
   perl_warn 
  ---
--- 19,25 
  
  $$;
  select perl_warn('implicit elog via warn');
! NOTICE:  implicit elog via warn at (eval 8) line 4.
  
   perl_warn 
  ---
Index: src/pl/plperl/sql/plperl.sql
===
RCS file: /projects/cvsroot/pgsql/src/pl/plperl/sql/plperl.sql,v
retrieving revision 1.4
diff -c -r1.4 plperl.sql
*** src/pl/plperl/sql/plperl.sql12 Jul 2005 01:16:22 -  1.4
--- src/pl/plperl/sql/plperl.sql24 Aug 2005 02:17:08 -
***
*** 240,246 
  --
  
  CREATE OR REPLACE FUNCTION perl_srf_rn() RETURNS SETOF RECORD AS $$
! $i = 0;
  for ("World", "PostgreSQL", "PL/Perl") {
  return_next({f1=>++$i, f2=>'Hello', f3=>$_});
  }
--- 240,246 
  --
  
  CREATE OR REPLACE FUNCTION perl_srf_rn() RETURNS SETOF RECORD AS $$
! my $i = 0;
  for ("World", "PostgreSQL", "PL/Perl") {
  return_next({f1=>++$i, f2=>'Hello', f3=>$_});
  }
***
*** 253,260 
  --
  
  CREATE OR REPLACE FUNCTION perl_spi_func() RETURNS SETOF INTEGER AS $$
! $x = spi_query("select 1 as a union select 2 as a");
! while (defined ($y = spi_fetchrow($x))) {
  return_next($y->{a});
  }
  return;
--- 253,260 
  --
  
  CREATE OR REPLACE FUNCTION perl_spi_func() RETURNS SETOF INTEGER AS $$
! my $x = spi_query("select 1 as a union select 2 as a");
! while (defined (my $y = spi_fetchrow($x))) {
  return_next($y->{a});
  }
  return;

---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


[PATCHES] plperl strict mode and associated fixes

2005-08-23 Thread Andrew Dunstan


The attached patch completes (I hope) the work begun by Michael Fuhr in 
an earlier unapplied patch, and makes strict mode work as recently 
discussed. I moved the embedded strings out of the calling functions 
into global macros to try to make the code a little more readable.


Unfortunately we can't have regression tests for this because it relies 
on a custom variable class.


Illustration of use:

andrew=# set plperl.use_strict = 'true';
SET
andrew=# create function foo() returns text language plperlu as $$ 
$foo=1; return 'foo';$$;
ERROR:  creation of Perl function failed: Global symbol "$foo" requires 
explicit package name at (eval 1) line 1.

andrew=# set plperl.use_strict = 'false';
SET
andrew=# create function foo() returns text language plperlu as $$ 
$foo=1; return 'foo';$$;

CREATE FUNCTION


cheers

andrew
Index: src/pl/plperl/plperl.c
===
RCS file: /home/cvsmirror/pgsql/src/pl/plperl/plperl.c,v
retrieving revision 1.90
diff -c -r1.90 plperl.c
*** src/pl/plperl/plperl.c	20 Aug 2005 19:19:21 -	1.90
--- src/pl/plperl/plperl.c	24 Aug 2005 00:18:03 -
***
*** 185,241 
  	/* We don't need to do anything yet when a new backend starts. */
  }
  
  
  static void
  plperl_init_interp(void)
  {
! 	static char	   *loose_embedding[3] = {
! 		"", "-e",
! 		/* all one string follows (no commas please) */
! 		"SPI::bootstrap(); use vars qw(%_SHARED);"
! 		"sub ::plperl_warn { my $msg = shift; &elog(&NOTICE, $msg); } "
! 		"$SIG{__WARN__} = \\&::plperl_warn; "
! 		"sub ::mkunsafefunc {return eval(qq[ sub { $_[0] $_[1] } ]); }"
! 		"sub ::_plperl_to_pg_array"
! 		"{"
! 		"  my $arg = shift; ref $arg eq 'ARRAY' || return $arg; "
! 		"  my $res = ''; my $first = 1; "
! 		"  foreach my $elem (@$arg) "
! 		"  { "
! 		"$res .= ', ' unless $first; $first = undef; "
! 		"if (ref $elem) "
! 		"{ "
! 		"  $res .= _plperl_to_pg_array($elem); "
! 		"} "
! 		"else "
! 		"{ "
! 		"  my $str = qq($elem); "
! 		"  $str =~ s/([\"])/$1/g; "
! 		"  $res .= qq(\"$str\"); "
! 		"} "
! 		"  } "
! 		"  return qq({$res}); "
! 		"} "
  	};
  
  
- 	static char	   *strict_embedding[3] = {
- 		"", "-e",
- 		/* all one string follows (no commas please) */
- 		"SPI::bootstrap(); use vars qw(%_SHARED);"
- 		"sub ::plperl_warn { my $msg = shift; &elog(&NOTICE, $msg); } "
- 		"$SIG{__WARN__} = \\&::plperl_warn; "
- 		"sub ::mkunsafefunc {return eval("
- 		"qq[ sub { use strict; $_[0] $_[1] } ]); }"
- 	};
- 
  	plperl_interp = perl_alloc();
  	if (!plperl_interp)
  		elog(ERROR, "could not allocate Perl interpreter");
  
  	perl_construct(plperl_interp);
! 	perl_parse(plperl_interp, plperl_init_shared_libs, 3 ,
! 			   (plperl_use_strict ? strict_embedding : loose_embedding), NULL);
  	perl_run(plperl_interp);
  
  	plperl_proc_hash = newHV();
--- 185,259 
  	/* We don't need to do anything yet when a new backend starts. */
  }
  
+ #define PERLBOOT \
+ "SPI::bootstrap(); use vars qw(%_SHARED);"\
+ "sub ::plperl_warn { my $msg = shift; &elog(&NOTICE, $msg); } "  \
+ 	"$SIG{__WARN__} = \\&::plperl_warn; " \
+ 	"sub ::mkunsafefunc {return eval(qq[ sub { $_[0] $_[1] } ]); }" \
+ "use strict; " \
+ 	"sub ::mk_strict_unsafefunc {return eval(" \
+ 	"qq[ sub { use strict; $_[0] $_[1] } ]); }" \
+ " " \
+ 	"sub ::_plperl_to_pg_array" \
+ 	"{" \
+ 	"  my $arg = shift; ref $arg eq 'ARRAY' || return $arg; " \
+ 	"  my $res = ''; my $first = 1; " \
+ 	"  foreach my $elem (@$arg) " \
+ 	"  { " \
+ 	"$res .= ', ' unless $first; $first = undef; " \
+ 	"if (ref $elem) " \
+ 	"{ " \
+ 	"  $res .= _plperl_to_pg_array($elem); " \
+ 	"} " \
+ 	"else " \
+ 	"{ " \
+ 	"  my $str = qq($elem); " \
+ 	"  $str =~ s/([\"])/$1/g; " \
+ 	"  $res .= qq(\"$str\"); " \
+ 	"} " \
+ 	"  } " \
+ 	"  return qq({$res}); " \
+ 	"} "
+ 
+ #define SAFE_MODULE "require Safe; $Safe::VERSION"
+ 
+ #define SAFE_OK \
+ 	"use vars qw($PLContainer); $PLContainer = new Safe('PLPerl');" \
+ 	"$PLContainer->permit_only(':default');" \
+ 	"$PLContainer->permit(qw[:base_math !:base_io sort time]);" \
+ 	"$PLContainer->share(qw[&elog &spi_exec_query &return_next " \
+ 	"&spi_query &spi_fetchrow " \
+ 	"&_plperl_to_pg_array " \
+ 	"&DEBUG &LOG &INFO &NOTICE &WARNING &ERROR %_SHARED ]);" \
+ 	"sub ::mksafefunc { return $PLContainer->reval(qq[ " \
+ 	" sub { $_[0] $_[1]}]); }" \
+ 	"$PLContainer->permit('require');$PLContainer->reval('use strict;');" \
+ 	"$PLContainer->deny('require');" \
+ 	"sub ::mk_strict_safefunc { return $PLContainer->reval(qq[ " \
+ 	" sub { BEGIN { strict->import(); } $_[0] $_[1]}]); }" \
+ 
+ #define SAFE_BAD \
+ 	"use vars qw($PLContainer); $PLContainer = new Safe('PLPerl');" \
+ 	"$PLContainer->permit_only(':default');" \
+ 	"$PLContainer->share(qw[&elog &ERROR ]);" \
+ 	"sub ::mksafefunc { return $PLContainer->reval(qq[sub { " \
+ 	"

Re: [PATCHES] enable/disable trigger (Re: Fwd: [HACKERS] Open items)

2005-08-23 Thread Bruce Momjian

Thanks, modified patch applied by Tom, with the addition of a USER
triggers only mode.

---

Satoshi Nagayasu wrote:
> The message format for elog() report is cleaned up.
> 
> -- 
> NAGAYASU Satoshi <[EMAIL PROTECTED]>

> diff -cr pgsql.orig/src/backend/commands/tablecmds.c 
> pgsql/src/backend/commands/tablecmds.c
> *** pgsql.orig/src/backend/commands/tablecmds.c   2005-06-28 
> 14:08:54.0 +0900
> --- pgsql/src/backend/commands/tablecmds.c2005-08-08 13:46:44.0 
> +0900
> ***
> *** 236,241 
> --- 236,243 
-- 
  Bruce Momjian|  http://candle.pha.pa.us
  pgman@candle.pha.pa.us   |  (610) 359-1001
  +  If your life is a hard drive, |  13 Roberts Road
  +  Christ can be your backup.|  Newtown Square, Pennsylvania 19073

---(end of broadcast)---
TIP 4: Have you searched our list archives?

   http://archives.postgresql.org


Re: [PATCHES] Win32 Thread Safety

2005-08-23 Thread Bruce Momjian

Patch applied and file renamed, configure run.  Thanks.

---

Dave Page wrote:
> The attached patch updates the thread test program to run stand-alone on
> Windows. The test itself is bypassed in configure as discussed, and
> libpq has been updated appropriately to allow it to build in thread-safe
> mode.
> 
> To apply, apply the patch as normal, then rename
> src/interface/libpq/pthread.h.win32 to
> src/interface/libpq/pthread-win32.h. Finally, run autoconf to regenerate
> configure.
> 
> Regards, Dave.

Content-Description: win32_thread_safety.diff.gz

[ Attachment, skipping... ]

> 
> ---(end of broadcast)---
> TIP 9: In versions below 8.0, the planner will ignore your desire to
>choose an index scan if your joining column's datatypes do not
>match

-- 
  Bruce Momjian|  http://candle.pha.pa.us
  pgman@candle.pha.pa.us   |  (610) 359-1001
  +  If your life is a hard drive, |  13 Roberts Road
  +  Christ can be your backup.|  Newtown Square, Pennsylvania 19073

---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


Re: [PATCHES] Win32 unicode vs ICU

2005-08-23 Thread Tom Lane
I looked over the proposed patch a bit and found some problems --- in
particular, if I read M$'s documentation about MultiByteToWideChar
correctly, they chose an API that fails for zero-length input, and
so you gotta program around that.  Also, varstr_cmp() cannot assume
it gets null-terminated input.

I cannot test the attached revised patch; please check it out.

regards, tom lane

Index: oracle_compat.c
===
RCS file: /cvsroot/pgsql/src/backend/utils/adt/oracle_compat.c,v
retrieving revision 1.60
diff -c -r1.60 oracle_compat.c
*** oracle_compat.c 7 May 2005 15:18:17 -   1.60
--- oracle_compat.c 23 Aug 2005 17:13:11 -
***
*** 149,154 
--- 149,265 
  #endif   /* USE_WIDE_UPPER_LOWER */
  
  
+ /*
+  * On Windows, the "Unicode" locales assume UTF16 not UTF8 encoding.
+  * To make use of the upper/lower functionality, we need to map UTF8 to
+  * UTF16, which for some reason mbstowcs and wcstombs won't do for us.
+  * This conversion layer takes care of it.
+  */
+ 
+ #ifdef WIN32
+ 
+ /* texttowcs for the case of UTF8 to UTF16 */
+ static wchar_t *
+ win32_utf8_texttowcs(const text *txt)
+ {
+   int nbytes = VARSIZE(txt) - VARHDRSZ;
+   wchar_t*result;
+   int r;
+ 
+   /* Overflow paranoia */
+   if (nbytes < 0 ||
+   nbytes > (int) (INT_MAX / sizeof(wchar_t)) -1)
+   ereport(ERROR,
+   (errcode(ERRCODE_OUT_OF_MEMORY),
+errmsg("out of memory")));
+ 
+   /* Output workspace cannot have more codes than input bytes */
+   result = (wchar_t *) palloc((nbytes + 1) * sizeof(wchar_t));
+ 
+   /* stupid Microsloth API does not work for zero-length input */
+   if (nbytes == 0)
+   r = 0;
+   else
+   {
+   /* Do the conversion */
+   r = MultiByteToWideChar(CP_UTF8, 0, VARDATA(txt), nbytes,
+   result, nbytes);
+ 
+   if (!r) /* assume it's 
NO_UNICODE_TRANSLATION */
+   {
+   /* see notes above about error reporting */
+   pg_verifymbstr(VARDATA(txt), nbytes, false);
+   ereport(ERROR,
+   
(errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
+errmsg("invalid multibyte character 
for locale"),
+errhint("The server's LC_CTYPE locale 
is probably incompatible with the database encoding.")));
+   }
+   }
+ 
+   Assert(r <= nbytes);
+   result[r] = 0;
+ 
+   return result;
+ }
+ 
+ /* wcstotext for the case of UTF16 to UTF8 */
+ static text *
+ win32_utf8_wcstotext(const wchar_t *str)
+ {
+   text*result;
+   int  nbytes;
+   int  r;
+ 
+   nbytes = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
+   if (nbytes == 0)/* shouldn't happen */
+   ereport(ERROR,
+   (errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
+errmsg("UTF16 to UTF8 translation failed: %lu",
+   GetLastError(;
+ 
+   result = palloc(nbytes+VARHDRSZ);
+ 
+   r = WideCharToMultiByte(CP_UTF8, 0, str, -1, VARDATA(result), nbytes,
+   NULL, NULL);
+   if (r == 0) /* shouldn't happen */
+   ereport(ERROR,
+   (errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
+errmsg("UTF16 to UTF8 translation failed: %lu",
+   GetLastError(;
+ 
+   VARATT_SIZEP(result) = nbytes + VARHDRSZ - 1; /* -1 to ignore null */
+ 
+   return result;
+ }
+ 
+ /* interface layer to check which encoding is in use */
+ 
+ static wchar_t *
+ win32_texttowcs(const text *txt)
+ {
+   if (GetDatabaseEncoding() == PG_UTF8)
+   return win32_utf8_texttowcs(txt);
+   else
+   return texttowcs(txt);
+ }
+ 
+ static text *
+ win32_wcstotext(const wchar_t *str, int ncodes)
+ {
+   if (GetDatabaseEncoding() == PG_UTF8)
+   return win32_utf8_wcstotext(str);
+   else
+   return wcstotext(str, ncodes);
+ }
+ 
+ /* use macros to cause routines below to call interface layer */
+ 
+ #define texttowcs win32_texttowcs
+ #define wcstotext win32_wcstotext
+ 
+ #endif /* WIN32 */
+ 
+ 
  /
   *
   * lower
Index: varlena.c
===
RCS file: /cvsr

Re: [PATCHES] [pgsql-hackers-win32] win32 random number generator

2005-08-23 Thread Tom Lane
"Merlin Moncure" <[EMAIL PROTECTED]> writes:
> "Merlin Moncure" <[EMAIL PROTECTED]> writes:
>> Looks like this in lrand48(void):
>> _rand48_seed[1] > 1);

>> _rand48_seed[1] >> 1);
>> ^^

> The problem is the shift operator :).

Ah, missed that completely in looking at the casts.  Will fix.

regards, tom lane

---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


Re: [PATCHES] PL/Perl embedding string common elements

2005-08-23 Thread Andrew Dunstan



Tom Lane wrote:


Andrew Dunstan <[EMAIL PROTECTED]> writes:
 

Do you expect turning it on to affect only future compilations? Or 
should we recompile every function already compiled in the present 
backend? I can see arguments either way.
   



Yeah, me too.  I would definitely expect a change in the variable
(in either direction) to be respected in subsequent function
compilations.  I'm less excited about redoing previous compilations;
a case could be made for doing so, but I won't insist on it.
I think the main case where use_strict is interesting is in development,
where you're repeatedly CREATE OR REPLACE'ing the function and retesting
it, so you're going to be doing new compilations anyway.


 




Discussion seems to have died on this. If there's no objection and 
nobody else is doing this I will prepare a patch based on keeping the 
setting as USERSET and not recompiling previously compiled functions. 
I'll move the embedding strings to macroland and tidy things up as 
discussed. It will take me a few days to get that ready.


cheers

andrew

---(end of broadcast)---
TIP 5: don't forget to increase your free space map settings


Re: [PATCHES] [pgsql-hackers-win32] win32 random number generator

2005-08-23 Thread Merlin Moncure
> "Merlin Moncure" <[EMAIL PROTECTED]> writes:
> > Looks like this in lrand48(void):
_rand48_seed[1] > 1);
 
> > _rand48_seed[1] >> 1);
^^

The problem is the shift operator :).  Anyways I double checked the
results and it works as expected now so here's a patch.  I also removed
the spurious casts.

Merlin


fix_random.diff
Description: fix_random.diff

---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster