mirror of
https://github.com/postgres/postgres.git
synced 2025-05-17 06:41:24 +03:00
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.
This commit is contained in:
parent
db78e53fac
commit
03a7dd013e
@ -33,7 +33,7 @@
|
|||||||
* ENHANCEMENTS, OR MODIFICATIONS.
|
* ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* from all attributes of a given tuple
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
static SV *
|
static SV *
|
||||||
plperl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc)
|
plperl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc)
|
||||||
{
|
{
|
||||||
|
HV *hv;
|
||||||
int i;
|
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++)
|
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)
|
if (tupdesc->attrs[i]->attisdropped)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/************************************************************
|
attname = NameStr(tupdesc->attrs[i]->attname);
|
||||||
* Get the attribute name
|
namelen = strlen(attname);
|
||||||
************************************************************/
|
|
||||||
attname = tupdesc->attrs[i]->attname.data;
|
|
||||||
|
|
||||||
/************************************************************
|
|
||||||
* Get the attributes value
|
|
||||||
************************************************************/
|
|
||||||
attr = heap_getattr(tuple, i + 1, tupdesc, &isnull);
|
attr = heap_getattr(tuple, i + 1, tupdesc, &isnull);
|
||||||
|
|
||||||
/************************************************************
|
if (isnull) {
|
||||||
* If it is null it will be set to undef in the hash.
|
/* Store (attname => undef) and move on. */
|
||||||
************************************************************/
|
hv_store(hv, attname, namelen, newSV(0), 0);
|
||||||
if (isnull)
|
|
||||||
{
|
|
||||||
sv_catpvf(output, "'%s' => undef,", attname);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************
|
/* XXX should have a way to cache these lookups */
|
||||||
* 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);
|
|
||||||
|
|
||||||
typoutput = ((Form_pg_type) GETSTRUCT(typeTup))->typoutput;
|
getTypeOutputInfo(tupdesc->attrs[i]->atttypid,
|
||||||
typelem = ((Form_pg_type) GETSTRUCT(typeTup))->typelem;
|
&typoutput, &typioparam, &typisvarlena);
|
||||||
ReleaseSysCache(typeTup);
|
|
||||||
|
|
||||||
/************************************************************
|
|
||||||
* Append the attribute name and the value to the list.
|
|
||||||
************************************************************/
|
|
||||||
outputstr = DatumGetCString(OidFunctionCall3(typoutput,
|
outputstr = DatumGetCString(OidFunctionCall3(typoutput,
|
||||||
attr,
|
attr,
|
||||||
ObjectIdGetDatum(typelem),
|
ObjectIdGetDatum(typioparam),
|
||||||
Int32GetDatum(tupdesc->attrs[i]->atttypmod)));
|
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, "}");
|
return newRV_noinc((SV *) hv);
|
||||||
output = perl_eval_pv(SvPV(output, PL_na), TRUE);
|
|
||||||
return output;
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user