Re: BUG #2917: spi_prepare doesn't accept typename aliases

Поиск
Список
Период
Сортировка
От Andrew Dunstan
Тема Re: BUG #2917: spi_prepare doesn't accept typename aliases
Дата
Msg-id 45BA1B72.8010509@dunslane.net
обсуждение исходный текст
Ответ на Re: BUG #2917: spi_prepare doesn't accept typename aliases  (Andrew Dunstan <andrew@dunslane.net>)
Ответы Re: BUG #2917: spi_prepare doesn't accept typename aliases  (Tom Lane <tgl@sss.pgh.pa.us>)
Список pgsql-hackers
I wrote:
> Tom Lane wrote:
>>
>> I think parseTypeString() may be the thing to use.  It's what plpgsql
>> uses...
>>
>>
>
> OK, I'll see what I can do.
>

see attached patch.  If this is OK I will apply it and also fix pltcl
and plpython similarly, mutatis mutandis.

cheers

andrew
Index: src/pl/plperl/plperl.c
===================================================================
RCS file: /cvsroot/pgsql/src/pl/plperl/plperl.c,v
retrieving revision 1.123
diff -c -r1.123 plperl.c
*** src/pl/plperl/plperl.c    21 Nov 2006 16:59:02 -0000    1.123
--- src/pl/plperl/plperl.c    26 Jan 2007 15:13:05 -0000
***************
*** 2128,2145 ****
      PG_TRY();
      {
          /************************************************************
!          * Lookup the argument types by name in the system cache
!          * and remember the required information for input conversion
           ************************************************************/
          for (i = 0; i < argc; i++)
          {
!             List       *names;
              HeapTuple    typeTup;

!             /* Parse possibly-qualified type name and look it up in pg_type */
!             names = stringToQualifiedNameList(SvPV(argv[i], PL_na),
!                                               "plperl_spi_prepare");
!             typeTup = typenameType(NULL, makeTypeNameFromNameList(names));
              qdesc->argtypes[i] = HeapTupleGetOid(typeTup);
              perm_fmgr_info(((Form_pg_type) GETSTRUCT(typeTup))->typinput,
                             &(qdesc->arginfuncs[i]));
--- 2128,2152 ----
      PG_TRY();
      {
          /************************************************************
!          * Resolve argument type names and then look them up by oid
!          * in the system cache, and remember the required information
!          * for input conversion.
           ************************************************************/
          for (i = 0; i < argc; i++)
          {
!             Oid         typeId;
!             int32       typmod;
              HeapTuple    typeTup;

!             parseTypeString(SvPV(argv[i], PL_na), &typeId, &typmod);
!
!             typeTup = SearchSysCache(TYPEOID,
!                                      ObjectIdGetDatum(typeId),
!                                      0,0,0);
!             if (!HeapTupleIsValid(typeTup))
!                 elog(ERROR, "cache lookup failed for type %u", typeId);
!
!
              qdesc->argtypes[i] = HeapTupleGetOid(typeTup);
              perm_fmgr_info(((Form_pg_type) GETSTRUCT(typeTup))->typinput,
                             &(qdesc->arginfuncs[i]));
Index: src/pl/plperl/expected/plperl.out
===================================================================
RCS file: /cvsroot/pgsql/src/pl/plperl/expected/plperl.out,v
retrieving revision 1.9
diff -c -r1.9 plperl.out
*** src/pl/plperl/expected/plperl.out    13 Aug 2006 17:31:10 -0000    1.9
--- src/pl/plperl/expected/plperl.out    26 Jan 2007 15:13:05 -0000
***************
*** 438,444 ****
  -- Test spi_prepare/spi_exec_prepared/spi_freeplan
  --
  CREATE OR REPLACE FUNCTION perl_spi_prepared(INTEGER) RETURNS INTEGER AS $$
!    my $x = spi_prepare('select $1 AS a', 'INT4');
     my $q = spi_exec_prepared( $x, $_[0] + 1);
     spi_freeplan($x);
  return $q->{rows}->[0]->{a};
--- 438,444 ----
  -- Test spi_prepare/spi_exec_prepared/spi_freeplan
  --
  CREATE OR REPLACE FUNCTION perl_spi_prepared(INTEGER) RETURNS INTEGER AS $$
!    my $x = spi_prepare('select $1 AS a', 'INTEGER');
     my $q = spi_exec_prepared( $x, $_[0] + 1);
     spi_freeplan($x);
  return $q->{rows}->[0]->{a};
***************
*** 468,470 ****
--- 468,504 ----
                       4
  (2 rows)

+ --
+ -- Test prepare with a type with spaces
+ --
+ CREATE OR REPLACE FUNCTION perl_spi_prepared_double(double precision) RETURNS double precision AS $$
+   my $x = spi_prepare('SELECT 10.0 * $1 AS a', 'DOUBLE PRECISION');
+   my $q = spi_query_prepared($x,$_[0]);
+   my $result;
+   while (defined (my $y = spi_fetchrow($q))) {
+       $result = $y->{a};
+   }
+   spi_freeplan($x);
+   return $result;
+ $$ LANGUAGE plperl;
+ SELECT perl_spi_prepared_double(4.35) as "double precision";
+  double precision
+ ------------------
+              43.5
+ (1 row)
+
+ --
+ -- Test with a bad type
+ --
+ CREATE OR REPLACE FUNCTION perl_spi_prepared_bad(double precision) RETURNS double precision AS $$
+   my $x = spi_prepare('SELECT 10.0 * $1 AS a', 'does_not_exist');
+   my $q = spi_query_prepared($x,$_[0]);
+   my $result;
+   while (defined (my $y = spi_fetchrow($q))) {
+       $result = $y->{a};
+   }
+   spi_freeplan($x);
+   return $result;
+ $$ LANGUAGE plperl;
+ SELECT perl_spi_prepared_bad(4.35) as "double precision";
+ ERROR:  error from Perl function: type "does_not_exist" does not exist at line 2.
Index: src/pl/plperl/sql/plperl.sql
===================================================================
RCS file: /cvsroot/pgsql/src/pl/plperl/sql/plperl.sql,v
retrieving revision 1.11
diff -c -r1.11 plperl.sql
*** src/pl/plperl/sql/plperl.sql    13 Aug 2006 17:31:10 -0000    1.11
--- src/pl/plperl/sql/plperl.sql    26 Jan 2007 15:13:05 -0000
***************
*** 316,322 ****
  -- Test spi_prepare/spi_exec_prepared/spi_freeplan
  --
  CREATE OR REPLACE FUNCTION perl_spi_prepared(INTEGER) RETURNS INTEGER AS $$
!    my $x = spi_prepare('select $1 AS a', 'INT4');
     my $q = spi_exec_prepared( $x, $_[0] + 1);
     spi_freeplan($x);
  return $q->{rows}->[0]->{a};
--- 316,322 ----
  -- Test spi_prepare/spi_exec_prepared/spi_freeplan
  --
  CREATE OR REPLACE FUNCTION perl_spi_prepared(INTEGER) RETURNS INTEGER AS $$
!    my $x = spi_prepare('select $1 AS a', 'INTEGER');
     my $q = spi_exec_prepared( $x, $_[0] + 1);
     spi_freeplan($x);
  return $q->{rows}->[0]->{a};
***************
*** 337,339 ****
--- 337,369 ----
  $$ LANGUAGE plperl;
  SELECT * from perl_spi_prepared_set(1,2);

+ --
+ -- Test prepare with a type with spaces
+ --
+ CREATE OR REPLACE FUNCTION perl_spi_prepared_double(double precision) RETURNS double precision AS $$
+   my $x = spi_prepare('SELECT 10.0 * $1 AS a', 'DOUBLE PRECISION');
+   my $q = spi_query_prepared($x,$_[0]);
+   my $result;
+   while (defined (my $y = spi_fetchrow($q))) {
+       $result = $y->{a};
+   }
+   spi_freeplan($x);
+   return $result;
+ $$ LANGUAGE plperl;
+ SELECT perl_spi_prepared_double(4.35) as "double precision";
+
+ --
+ -- Test with a bad type
+ --
+ CREATE OR REPLACE FUNCTION perl_spi_prepared_bad(double precision) RETURNS double precision AS $$
+   my $x = spi_prepare('SELECT 10.0 * $1 AS a', 'does_not_exist');
+   my $q = spi_query_prepared($x,$_[0]);
+   my $result;
+   while (defined (my $y = spi_fetchrow($q))) {
+       $result = $y->{a};
+   }
+   spi_freeplan($x);
+   return $result;
+ $$ LANGUAGE plperl;
+ SELECT perl_spi_prepared_bad(4.35) as "double precision";
+

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Andrew Dunstan
Дата:
Сообщение: Re: Proposal: Commit timestamp
Следующее
От: Gregory Stark
Дата:
Сообщение: Re: HAVING push-down