]> granicus.if.org Git - postgresql/commitdiff
Back-patch 8.0 version of plperl_hash_from_tuple() into prior releases
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 26 Jan 2005 17:09:21 +0000 (17:09 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 26 Jan 2005 17:09:21 +0000 (17:09 +0000)
to fix failure to cope with quote marks in field values; not to mention
that it is shorter and faster.  Per report from Charles Haron.

src/pl/plperl/plperl.c

index 5916977a3f90407e85b764e3c16c1f7671f6aa19..3aa551cdbe02153f758581035e8053a5218233bf 100644 (file)
@@ -33,7 +33,7 @@
  *       ENHANCEMENTS, OR MODIFICATIONS.
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.40 2003/09/04 15:16:39 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.40.2.1 2005/01/26 17:09:21 tgl Exp $
  *
  **********************************************************************/
 
@@ -737,76 +737,53 @@ compile_plperl_function(Oid fn_oid, bool is_trigger)
 
 
 /**********************************************************************
- * plperl_build_tuple_argument() - Build a string for a ref to a hash
+ * plperl_build_tuple_argument() - Build a ref to a hash
  *                               from all attributes of a given tuple
  **********************************************************************/
 static SV  *
 plperl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc)
 {
+       HV                 *hv;
        int                     i;
-       SV                 *output;
-       Datum           attr;
-       bool            isnull;
-       char       *attname;
-       char       *outputstr;
-       HeapTuple       typeTup;
-       Oid                     typoutput;
-       Oid                     typelem;
 
-       output = sv_2mortal(newSVpv("{", 0));
+       hv = newHV();
 
        for (i = 0; i < tupdesc->natts; i++)
        {
-               /* ignore dropped attributes */
+               Datum           attr;
+               bool            isnull;
+               char       *attname;
+               char       *outputstr;
+               Oid                     typoutput;
+               Oid                     typioparam;
+               bool            typisvarlena;
+               int                     namelen;
+
                if (tupdesc->attrs[i]->attisdropped)
                        continue;
 
-               /************************************************************
-                * Get the attribute name
-                ************************************************************/
-               attname = tupdesc->attrs[i]->attname.data;
-
-               /************************************************************
-                * Get the attributes value
-                ************************************************************/
+               attname = NameStr(tupdesc->attrs[i]->attname);
+               namelen = strlen(attname);
                attr = heap_getattr(tuple, i + 1, tupdesc, &isnull);
 
-               /************************************************************
-                *      If it is null it will be set to undef in the hash.
-                ************************************************************/
-               if (isnull)
-               {
-                       sv_catpvf(output, "'%s' => undef,", attname);
+               if (isnull) {
+                       /* Store (attname => undef) and move on. */
+                       hv_store(hv, attname, namelen, newSV(0), 0);
                        continue;
                }
 
-               /************************************************************
-                * Lookup the attribute type in the syscache
-                * for the output function
-                ************************************************************/
-               typeTup = SearchSysCache(TYPEOID,
-                                                  ObjectIdGetDatum(tupdesc->attrs[i]->atttypid),
-                                                                0, 0, 0);
-               if (!HeapTupleIsValid(typeTup))
-                       elog(ERROR, "cache lookup failed for type %u",
-                                tupdesc->attrs[i]->atttypid);
+               /* XXX should have a way to cache these lookups */
 
-               typoutput = ((Form_pg_type) GETSTRUCT(typeTup))->typoutput;
-               typelem = ((Form_pg_type) GETSTRUCT(typeTup))->typelem;
-               ReleaseSysCache(typeTup);
+               getTypeOutputInfo(tupdesc->attrs[i]->atttypid,
+                                                 &typoutput, &typioparam, &typisvarlena);
 
-               /************************************************************
-                * Append the attribute name and the value to the list.
-                ************************************************************/
                outputstr = DatumGetCString(OidFunctionCall3(typoutput,
                                                                                                         attr,
-                                                                                          ObjectIdGetDatum(typelem),
+                                                                                       ObjectIdGetDatum(typioparam),
                                                   Int32GetDatum(tupdesc->attrs[i]->atttypmod)));
-               sv_catpvf(output, "'%s' => '%s',", attname, outputstr);
-               pfree(outputstr);
+
+               hv_store(hv, attname, namelen, newSVpv(outputstr, 0), 0);
        }
 
-       sv_catpv(output, "}");
-       output = perl_eval_pv(SvPV(output, PL_na), TRUE);
-       return output;
+       return newRV_noinc((SV *) hv);
 }