aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-01-26 17:09:21 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-01-26 17:09:21 +0000
commit03a7dd013edb3b948ffdba30632185b298d417f8 (patch)
treea7019a48236a389367c3f039f42417478c04f01d /src
parentdb78e53fac8251f446d1ecf49c8c81c240c1381e (diff)
downloadpostgresql-03a7dd013edb3b948ffdba30632185b298d417f8.tar.gz
postgresql-03a7dd013edb3b948ffdba30632185b298d417f8.zip
Back-patch 8.0 version of plperl_hash_from_tuple() into prior releases
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.
Diffstat (limited to 'src')
-rw-r--r--src/pl/plperl/plperl.c73
1 files changed, 25 insertions, 48 deletions
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index 5916977a3f9..3aa551cdbe0 100644
--- a/src/pl/plperl/plperl.c
+++ b/src/pl/plperl/plperl.c
@@ -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);
}