Arthur Ward <ward005@bama.ua.edu> writes:
> No, it does not match what I'm seeing. To check, I dropped my test
> table and function, exited psql, started psql, and ran the script I
> originally posted. I still get the same results. If I had to guess, this
> seems more like a Postgres to plpython conversion problem than a
> caching problem.
Bingo. The conversion-method-selection code is not only broken (for
several datatypes besides this one), but quite wrongheaded (testing on
the name of the datatype is the wrong approach). I've applied the
attached patch; please confirm it works for you.
regards, tom lane
*** src/pl/plpython/plpython.c.orig Thu Feb 13 18:06:19 2003
--- src/pl/plpython/plpython.c Wed Jun 11 14:31:23 2003
***************
*** 244,251 ****
static void PLy_typeinfo_dealloc(PLyTypeInfo *);
static void PLy_output_datum_func(PLyTypeInfo *, Form_pg_type);
static void PLy_output_datum_func2(PLyObToDatum *, Form_pg_type);
! static void PLy_input_datum_func(PLyTypeInfo *, Form_pg_type);
! static void PLy_input_datum_func2(PLyDatumToOb *, Form_pg_type);
static void PLy_output_tuple_funcs(PLyTypeInfo *, TupleDesc);
static void PLy_input_tuple_funcs(PLyTypeInfo *, TupleDesc);
--- 244,251 ----
static void PLy_typeinfo_dealloc(PLyTypeInfo *);
static void PLy_output_datum_func(PLyTypeInfo *, Form_pg_type);
static void PLy_output_datum_func2(PLyObToDatum *, Form_pg_type);
! static void PLy_input_datum_func(PLyTypeInfo *, Oid, Form_pg_type);
! static void PLy_input_datum_func2(PLyDatumToOb *, Oid, Form_pg_type);
static void PLy_output_tuple_funcs(PLyTypeInfo *, TupleDesc);
static void PLy_input_tuple_funcs(PLyTypeInfo *, TupleDesc);
***************
*** 1152,1158 ****
argTypeStruct = (Form_pg_type) GETSTRUCT(argTypeTup);
if (argTypeStruct->typrelid == InvalidOid)
! PLy_input_datum_func(&(proc->args[i]), argTypeStruct);
else
{
TupleTableSlot *slot = (TupleTableSlot *) fcinfo->arg[i];
--- 1152,1160 ----
argTypeStruct = (Form_pg_type) GETSTRUCT(argTypeTup);
if (argTypeStruct->typrelid == InvalidOid)
! PLy_input_datum_func(&(proc->args[i]),
! procStruct->proargtypes[i],
! argTypeStruct);
else
{
TupleTableSlot *slot = (TupleTableSlot *) fcinfo->arg[i];
***************
*** 1373,1379 ****
typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
! PLy_input_datum_func2(&(arg->in.r.atts[i]), typeStruct);
ReleaseSysCache(typeTup);
}
--- 1375,1383 ----
typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
! PLy_input_datum_func2(&(arg->in.r.atts[i]),
! desc->attrs[i]->atttypid,
! typeStruct);
ReleaseSysCache(typeTup);
}
***************
*** 1439,1523 ****
}
void
! PLy_input_datum_func(PLyTypeInfo * arg, Form_pg_type typeStruct)
{
enter();
if (arg->is_rel == 1)
elog(FATAL, "plpython: PLyTypeInfo struct is initialized for Tuple");
arg->is_rel = 0;
! PLy_input_datum_func2(&(arg->in.d), typeStruct);
}
void
! PLy_input_datum_func2(PLyDatumToOb * arg, Form_pg_type typeStruct)
{
! char *type;
!
perm_fmgr_info(typeStruct->typoutput, &arg->typfunc);
arg->typelem = typeStruct->typelem;
arg->typbyval = typeStruct->typbyval;
! /*
! * hmmm, wierd. means this arg will always be converted to a python
! * None
! */
! if (!OidIsValid(typeStruct->typoutput))
! {
! elog(ERROR, "plpython: (FIXME) typeStruct->typoutput is invalid");
!
! arg->func = NULL;
! return;
! }
!
! type = NameStr(typeStruct->typname);
! switch (type[0])
{
! case 'b':
! {
! if (strcasecmp("bool", type))
! {
! arg->func = PLyBool_FromString;
! return;
! }
! break;
! }
! case 'f':
! {
! if ((strncasecmp("float", type, 5) == 0) &&
! ((type[5] == '8') || (type[5] == '4')))
! {
! arg->func = PLyFloat_FromString;
! return;
! }
! break;
! }
! case 'i':
! {
! if ((strncasecmp("int", type, 3) == 0) &&
! ((type[3] == '4') || (type[3] == '2')) &&
! (type[4] == '\0'))
! {
! arg->func = PLyInt_FromString;
! return;
! }
! else if (strcasecmp("int8", type) == 0)
! arg->func = PLyLong_FromString;
! break;
! }
! case 'n':
! {
! if (strcasecmp("numeric", type) == 0)
! {
! arg->func = PLyFloat_FromString;
! return;
! }
! break;
! }
default:
break;
}
- arg->func = PLyString_FromString;
}
void
--- 1443,1488 ----
}
void
! PLy_input_datum_func(PLyTypeInfo * arg, Oid typeOid, Form_pg_type typeStruct)
{
enter();
if (arg->is_rel == 1)
elog(FATAL, "plpython: PLyTypeInfo struct is initialized for Tuple");
arg->is_rel = 0;
! PLy_input_datum_func2(&(arg->in.d), typeOid, typeStruct);
}
void
! PLy_input_datum_func2(PLyDatumToOb * arg, Oid typeOid, Form_pg_type typeStruct)
{
! /* Get the type's conversion information */
perm_fmgr_info(typeStruct->typoutput, &arg->typfunc);
arg->typelem = typeStruct->typelem;
arg->typbyval = typeStruct->typbyval;
! /* Determine which kind of Python object we will convert to */
! switch (typeOid)
{
! case BOOLOID:
! arg->func = PLyBool_FromString;
! break;
! case FLOAT4OID:
! case FLOAT8OID:
! case NUMERICOID:
! arg->func = PLyFloat_FromString;
! break;
! case INT2OID:
! case INT4OID:
! arg->func = PLyInt_FromString;
! break;
! case INT8OID:
! arg->func = PLyLong_FromString;
! break;
default:
+ arg->func = PLyString_FromString;
break;
}
}
void