Re: 7.3.3 - plpython & trigger problem

Поиск
Список
Период
Сортировка
От Tom Lane
Тема Re: 7.3.3 - plpython & trigger problem
Дата
Msg-id 20764.1055356724@sss.pgh.pa.us
обсуждение исходный текст
Ответ на Re: 7.3.3 - plpython & trigger problem  (Arthur Ward <ward005@bama.ua.edu>)
Ответы Re: 7.3.3 - plpython & trigger problem  (Arthur Ward <ward005@bama.ua.edu>)
Список pgsql-bugs
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

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

Предыдущее
От: "Li, Guoben"
Дата:
Сообщение: postgresql.jar
Следующее
От: Tom Lane
Дата:
Сообщение: Re: valgrind