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;
}
/************************************************************