pltcl/plython fixes for spi_prepare types - Mailing list pgsql-patches

From Andrew Dunstan
Subject pltcl/plython fixes for spi_prepare types
Date
Msg-id 45BBAC57.8040709@dunslane.net
Whole thread Raw
Responses Re: [pgsql-patches] pltcl/plython fixes for spi_prepare types
List pgsql-patches
Here's a patch along the same lines as the fix for plperl committed
earlier today, that allows passing type aliases to spi_prepare as well
as types named in pg_type. It also removes the mention of the previous
limitation in the pltcl docs. Unlike the plperl and pltcl cases, I
didn't use the simpler form that Tom suggested for plpython, as that
code wants to get hold of the HeapTuple. If anyone wants to tidy that up
some, feel free. Also, some regression tests from those with more tcl-fu
or python-fu that I have would be nice.

I'll apply this in a day or two unless there's an objection.

cheers

andrew
Index: doc/src/sgml/pltcl.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v
retrieving revision 2.42
diff -c -r2.42 pltcl.sgml
*** doc/src/sgml/pltcl.sgml    16 Sep 2006 00:30:15 -0000    2.42
--- doc/src/sgml/pltcl.sgml    27 Jan 2007 18:40:01 -0000
***************
*** 332,340 ****
          If the query uses parameters, the names of the parameter types
          must be given as a Tcl list.  (Write an empty list for
          <replaceable>typelist</replaceable> if no parameters are used.)
-         Presently, the parameter types must be identified by the internal
-         type names shown in the system table <literal>pg_type</>; for example <literal>int4</> not
-         <literal>integer</>.
         </para>
         <para>
          The return value from <function>spi_prepare</function> is a query ID
--- 332,337 ----
Index: src/pl/plpython/plpython.c
===================================================================
RCS file: /cvsroot/pgsql/src/pl/plpython/plpython.c,v
retrieving revision 1.92
diff -c -r1.92 plpython.c
*** src/pl/plpython/plpython.c    25 Jan 2007 14:52:23 -0000    1.92
--- src/pl/plpython/plpython.c    27 Jan 2007 18:40:04 -0000
***************
*** 2304,2330 ****
                  for (i = 0; i < nargs; i++)
                  {
                      char       *sptr;
-                     List       *names;
                      HeapTuple    typeTup;
                      Form_pg_type typeStruct;

                      optr = PySequence_GetItem(list, i);
                      if (!PyString_Check(optr))
                          elog(ERROR, "Type names must be strings.");
                      sptr = PyString_AsString(optr);

-                     /*
-                      * Parse possibly-qualified type name and look it up in
-                      * pg_type
-                      */
-                     names = stringToQualifiedNameList(sptr,
-                                                       "PLy_spi_prepare");
-                     typeTup = typenameType(NULL,
-                                            makeTypeNameFromNameList(names));
                      Py_DECREF(optr);
                      optr = NULL;    /* this is important */

!                     plan->types[i] = HeapTupleGetOid(typeTup);
                      typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
                      if (typeStruct->typtype != 'c')
                          PLy_output_datum_func(&plan->args[i], typeTup);
--- 2304,2337 ----
                  for (i = 0; i < nargs; i++)
                  {
                      char       *sptr;
                      HeapTuple    typeTup;
+                     Oid         typeId;
+                     int32       typmod;
                      Form_pg_type typeStruct;

                      optr = PySequence_GetItem(list, i);
                      if (!PyString_Check(optr))
                          elog(ERROR, "Type names must be strings.");
                      sptr = PyString_AsString(optr);
+
+                     /********************************************************
+                      * Resolve argument type names and then look them up by
+                      * oid in the system cache, and remember the required
+                      *information for input conversion.
+                      ********************************************************/
+
+                     parseTypeString(sptr, &typeId, &typmod);
+
+                     typeTup = SearchSysCache(TYPEOID,
+                                              ObjectIdGetDatum(typeId),
+                                              0,0,0);
+                     if (!HeapTupleIsValid(typeTup))
+                         elog(ERROR, "cache lookup failed for type %u", typeId);

                      Py_DECREF(optr);
                      optr = NULL;    /* this is important */

!                     plan->types[i] = typeId;
                      typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
                      if (typeStruct->typtype != 'c')
                          PLy_output_datum_func(&plan->args[i], typeTup);
Index: src/pl/tcl/pltcl.c
===================================================================
RCS file: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v
retrieving revision 1.108
diff -c -r1.108 pltcl.c
*** src/pl/tcl/pltcl.c    4 Oct 2006 00:30:14 -0000    1.108
--- src/pl/tcl/pltcl.c    27 Jan 2007 18:40:06 -0000
***************
*** 1808,1830 ****
      PG_TRY();
      {
          /************************************************************
!          * Lookup the argument types by name in the system cache
!          * and remember the required information for input conversion
           ************************************************************/
          for (i = 0; i < nargs; i++)
          {
!             List       *names;
!             HeapTuple    typeTup;

!             /* Parse possibly-qualified type name and look it up in pg_type */
!             names = stringToQualifiedNameList(args[i],
!                                               "pltcl_SPI_prepare");
!             typeTup = typenameType(NULL, makeTypeNameFromNameList(names));
!             qdesc->argtypes[i] = HeapTupleGetOid(typeTup);
!             perm_fmgr_info(((Form_pg_type) GETSTRUCT(typeTup))->typinput,
!                            &(qdesc->arginfuncs[i]));
!             qdesc->argtypioparams[i] = getTypeIOParam(typeTup);
!             ReleaseSysCache(typeTup);
          }

          /************************************************************
--- 1808,1829 ----
      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 < nargs; i++)
          {
!             Oid         typId, typInput, typIOParam;
!             int32       typmod;

!             parseTypeString(args[i], &typId, &typmod);
!
!             getTypeInputInfo(typId, &typInput, &typIOParam);
!
!             qdesc->argtypes[i] = typId;
!             perm_fmgr_info(typInput, &(qdesc->arginfuncs[i]));
!             qdesc->argtypioparams[i] = typIOParam;
          }

          /************************************************************

pgsql-patches by date:

Previous
From: Tom Lane
Date:
Subject: Re: [DOCS] Change draft gmake control
Next
From: Neil Conway
Date:
Subject: minor regression test refactor