mirror of
https://github.com/postgres/postgres.git
synced 2025-04-25 21:42:33 +03:00
Change CREATE TYPE to require datatype output and send functions to have
only one argument. (Per recent discussion, the option to accept multiple arguments is pretty useless for user-defined types, and would be a likely source of security holes if it was used.) Simplify call sites of output/send functions to not bother passing more than one argument.
This commit is contained in:
parent
ae793ff63c
commit
6c412f0605
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/create_type.sgml,v 1.54 2005/01/04 00:39:53 tgl Exp $
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/create_type.sgml,v 1.55 2005/05/01 18:56:17 tgl Exp $
|
||||
PostgreSQL documentation
|
||||
-->
|
||||
|
||||
@ -107,13 +107,10 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> (
|
||||
(or the type's own OID for a composite type),
|
||||
and the third is the <literal>typmod</> of the destination column, if known
|
||||
(-1 will be passed if not).
|
||||
The input function should return a value of the data type itself.
|
||||
The output function may be
|
||||
declared as taking one argument of the new data type, or as taking
|
||||
two arguments of which the second is type <type>oid</type>.
|
||||
The second argument is again the array element type OID for array types
|
||||
or the type OID for composite types.
|
||||
The output function should return type <type>cstring</type>.
|
||||
The input function must return a value of the data type itself.
|
||||
The output function must be
|
||||
declared as taking one argument of the new data type.
|
||||
The output function must return type <type>cstring</type>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -137,11 +134,8 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> (
|
||||
<replaceable class="parameter">send_function</replaceable> converts
|
||||
from the internal representation to the external binary representation.
|
||||
If this function is not supplied, the type cannot participate in binary
|
||||
output. The send function may be
|
||||
declared as taking one argument of the new data type, or as taking
|
||||
two arguments of which the second is type <type>oid</type>.
|
||||
The second argument is again the array element type OID for array types
|
||||
or the type OID for composite types.
|
||||
output. The send function must be
|
||||
declared as taking one argument of the new data type.
|
||||
The send function must return type <type>bytea</type>.
|
||||
</para>
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/common/printtup.c,v 1.89 2005/04/23 17:45:35 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/common/printtup.c,v 1.90 2005/05/01 18:56:17 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -48,7 +48,6 @@ typedef struct
|
||||
{ /* Per-attribute information */
|
||||
Oid typoutput; /* Oid for the type's text output fn */
|
||||
Oid typsend; /* Oid for the type's binary output fn */
|
||||
Oid typioparam; /* param to pass to the output fn */
|
||||
bool typisvarlena; /* is it varlena (ie possibly toastable)? */
|
||||
int16 format; /* format code for this column */
|
||||
FmgrInfo finfo; /* Precomputed call info for output fn */
|
||||
@ -263,7 +262,6 @@ printtup_prepare_info(DR_printtup *myState, TupleDesc typeinfo, int numAttrs)
|
||||
{
|
||||
getTypeOutputInfo(typeinfo->attrs[i]->atttypid,
|
||||
&thisState->typoutput,
|
||||
&thisState->typioparam,
|
||||
&thisState->typisvarlena);
|
||||
fmgr_info(thisState->typoutput, &thisState->finfo);
|
||||
}
|
||||
@ -271,7 +269,6 @@ printtup_prepare_info(DR_printtup *myState, TupleDesc typeinfo, int numAttrs)
|
||||
{
|
||||
getTypeBinaryOutputInfo(typeinfo->attrs[i]->atttypid,
|
||||
&thisState->typsend,
|
||||
&thisState->typioparam,
|
||||
&thisState->typisvarlena);
|
||||
fmgr_info(thisState->typsend, &thisState->finfo);
|
||||
}
|
||||
@ -338,10 +335,8 @@ printtup(TupleTableSlot *slot, DestReceiver *self)
|
||||
/* Text output */
|
||||
char *outputstr;
|
||||
|
||||
outputstr = DatumGetCString(FunctionCall3(&thisState->finfo,
|
||||
attr,
|
||||
ObjectIdGetDatum(thisState->typioparam),
|
||||
Int32GetDatum(typeinfo->attrs[i]->atttypmod)));
|
||||
outputstr = DatumGetCString(FunctionCall1(&thisState->finfo,
|
||||
attr));
|
||||
pq_sendcountedtext(&buf, outputstr, strlen(outputstr), false);
|
||||
pfree(outputstr);
|
||||
}
|
||||
@ -350,9 +345,8 @@ printtup(TupleTableSlot *slot, DestReceiver *self)
|
||||
/* Binary output */
|
||||
bytea *outputbytes;
|
||||
|
||||
outputbytes = DatumGetByteaP(FunctionCall2(&thisState->finfo,
|
||||
attr,
|
||||
ObjectIdGetDatum(thisState->typioparam)));
|
||||
outputbytes = DatumGetByteaP(FunctionCall1(&thisState->finfo,
|
||||
attr));
|
||||
/* We assume the result will not have been toasted */
|
||||
pq_sendint(&buf, VARSIZE(outputbytes) - VARHDRSZ, 4);
|
||||
pq_sendbytes(&buf, VARDATA(outputbytes),
|
||||
@ -439,10 +433,8 @@ printtup_20(TupleTableSlot *slot, DestReceiver *self)
|
||||
else
|
||||
attr = origattr;
|
||||
|
||||
outputstr = DatumGetCString(FunctionCall3(&thisState->finfo,
|
||||
attr,
|
||||
ObjectIdGetDatum(thisState->typioparam),
|
||||
Int32GetDatum(typeinfo->attrs[i]->atttypmod)));
|
||||
outputstr = DatumGetCString(FunctionCall1(&thisState->finfo,
|
||||
attr));
|
||||
pq_sendcountedtext(&buf, outputstr, strlen(outputstr), true);
|
||||
pfree(outputstr);
|
||||
|
||||
@ -534,8 +526,7 @@ debugtup(TupleTableSlot *slot, DestReceiver *self)
|
||||
attr;
|
||||
char *value;
|
||||
bool isnull;
|
||||
Oid typoutput,
|
||||
typioparam;
|
||||
Oid typoutput;
|
||||
bool typisvarlena;
|
||||
|
||||
for (i = 0; i < natts; ++i)
|
||||
@ -544,7 +535,7 @@ debugtup(TupleTableSlot *slot, DestReceiver *self)
|
||||
if (isnull)
|
||||
continue;
|
||||
getTypeOutputInfo(typeinfo->attrs[i]->atttypid,
|
||||
&typoutput, &typioparam, &typisvarlena);
|
||||
&typoutput, &typisvarlena);
|
||||
|
||||
/*
|
||||
* If we have a toasted datum, forcibly detoast it here to avoid
|
||||
@ -555,10 +546,8 @@ debugtup(TupleTableSlot *slot, DestReceiver *self)
|
||||
else
|
||||
attr = origattr;
|
||||
|
||||
value = DatumGetCString(OidFunctionCall3(typoutput,
|
||||
attr,
|
||||
ObjectIdGetDatum(typioparam),
|
||||
Int32GetDatum(typeinfo->attrs[i]->atttypmod)));
|
||||
value = DatumGetCString(OidFunctionCall1(typoutput,
|
||||
attr));
|
||||
|
||||
printatt((unsigned) i + 1, typeinfo->attrs[i], value);
|
||||
|
||||
@ -647,9 +636,8 @@ printtup_internal_20(TupleTableSlot *slot, DestReceiver *self)
|
||||
else
|
||||
attr = origattr;
|
||||
|
||||
outputbytes = DatumGetByteaP(FunctionCall2(&thisState->finfo,
|
||||
attr,
|
||||
ObjectIdGetDatum(thisState->typioparam)));
|
||||
outputbytes = DatumGetByteaP(FunctionCall1(&thisState->finfo,
|
||||
attr));
|
||||
/* We assume the result will not have been toasted */
|
||||
pq_sendint(&buf, VARSIZE(outputbytes) - VARHDRSZ, 4);
|
||||
pq_sendbytes(&buf, VARDATA(outputbytes),
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.202 2005/04/14 20:03:23 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.203 2005/05/01 18:56:17 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -850,10 +850,8 @@ InsertOneValue(char *value, int i)
|
||||
CStringGetDatum(value),
|
||||
ObjectIdGetDatum(typioparam),
|
||||
Int32GetDatum(-1));
|
||||
prt = DatumGetCString(OidFunctionCall3(typoutput,
|
||||
values[i],
|
||||
ObjectIdGetDatum(typioparam),
|
||||
Int32GetDatum(-1)));
|
||||
prt = DatumGetCString(OidFunctionCall1(typoutput,
|
||||
values[i]));
|
||||
elog(DEBUG4, "inserted -> %s", prt);
|
||||
pfree(prt);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.240 2005/04/14 20:03:23 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.241 2005/05/01 18:56:18 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1178,8 +1178,6 @@ CopyTo(Relation rel, List *attnumlist, bool binary, bool oids,
|
||||
Form_pg_attribute *attr;
|
||||
FmgrInfo *out_functions;
|
||||
bool *force_quote;
|
||||
Oid *typioparams;
|
||||
bool *isvarlena;
|
||||
char *string;
|
||||
ListCell *cur;
|
||||
MemoryContext oldcontext;
|
||||
@ -1194,22 +1192,21 @@ CopyTo(Relation rel, List *attnumlist, bool binary, bool oids,
|
||||
* Get info about the columns we need to process.
|
||||
*/
|
||||
out_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
|
||||
typioparams = (Oid *) palloc(num_phys_attrs * sizeof(Oid));
|
||||
isvarlena = (bool *) palloc(num_phys_attrs * sizeof(bool));
|
||||
force_quote = (bool *) palloc(num_phys_attrs * sizeof(bool));
|
||||
foreach(cur, attnumlist)
|
||||
{
|
||||
int attnum = lfirst_int(cur);
|
||||
Oid out_func_oid;
|
||||
bool isvarlena;
|
||||
|
||||
if (binary)
|
||||
getTypeBinaryOutputInfo(attr[attnum - 1]->atttypid,
|
||||
&out_func_oid, &typioparams[attnum - 1],
|
||||
&isvarlena[attnum - 1]);
|
||||
&out_func_oid,
|
||||
&isvarlena);
|
||||
else
|
||||
getTypeOutputInfo(attr[attnum - 1]->atttypid,
|
||||
&out_func_oid, &typioparams[attnum - 1],
|
||||
&isvarlena[attnum - 1]);
|
||||
&out_func_oid,
|
||||
&isvarlena);
|
||||
fmgr_info(out_func_oid, &out_functions[attnum - 1]);
|
||||
|
||||
if (list_member_int(force_quote_atts, attnum))
|
||||
@ -1321,10 +1318,8 @@ CopyTo(Relation rel, List *attnumlist, bool binary, bool oids,
|
||||
{
|
||||
if (!binary)
|
||||
{
|
||||
string = DatumGetCString(FunctionCall3(&out_functions[attnum - 1],
|
||||
value,
|
||||
ObjectIdGetDatum(typioparams[attnum - 1]),
|
||||
Int32GetDatum(attr[attnum - 1]->atttypmod)));
|
||||
string = DatumGetCString(FunctionCall1(&out_functions[attnum - 1],
|
||||
value));
|
||||
if (csv_mode)
|
||||
{
|
||||
CopyAttributeOutCSV(string, delim, quote, escape,
|
||||
@ -1339,9 +1334,8 @@ CopyTo(Relation rel, List *attnumlist, bool binary, bool oids,
|
||||
{
|
||||
bytea *outputbytes;
|
||||
|
||||
outputbytes = DatumGetByteaP(FunctionCall2(&out_functions[attnum - 1],
|
||||
value,
|
||||
ObjectIdGetDatum(typioparams[attnum - 1])));
|
||||
outputbytes = DatumGetByteaP(FunctionCall1(&out_functions[attnum - 1],
|
||||
value));
|
||||
/* We assume the result will not have been toasted */
|
||||
CopySendInt32(VARSIZE(outputbytes) - VARHDRSZ);
|
||||
CopySendData(VARDATA(outputbytes),
|
||||
@ -1366,8 +1360,6 @@ CopyTo(Relation rel, List *attnumlist, bool binary, bool oids,
|
||||
MemoryContextDelete(mycontext);
|
||||
|
||||
pfree(out_functions);
|
||||
pfree(typioparams);
|
||||
pfree(isvarlena);
|
||||
pfree(force_quote);
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.70 2005/04/14 20:03:24 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.71 2005/05/01 18:56:18 tgl Exp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The "DefineFoo" routines take the parse tree and pick out the
|
||||
@ -920,12 +920,11 @@ findTypeInputFunction(List *procname, Oid typeOid)
|
||||
static Oid
|
||||
findTypeOutputFunction(List *procname, Oid typeOid)
|
||||
{
|
||||
Oid argList[2];
|
||||
Oid argList[1];
|
||||
Oid procOid;
|
||||
|
||||
/*
|
||||
* Output functions can take a single argument of the type, or two
|
||||
* arguments (data value, element OID).
|
||||
* Output functions can take a single argument of the type.
|
||||
*
|
||||
* For backwards compatibility we allow OPAQUE in place of the actual
|
||||
* type name; if we see this, we issue a warning and fix up the
|
||||
@ -937,24 +936,11 @@ findTypeOutputFunction(List *procname, Oid typeOid)
|
||||
if (OidIsValid(procOid))
|
||||
return procOid;
|
||||
|
||||
argList[1] = OIDOID;
|
||||
|
||||
procOid = LookupFuncName(procname, 2, argList, true);
|
||||
if (OidIsValid(procOid))
|
||||
return procOid;
|
||||
|
||||
/* No luck, try it with OPAQUE */
|
||||
argList[0] = OPAQUEOID;
|
||||
|
||||
procOid = LookupFuncName(procname, 1, argList, true);
|
||||
|
||||
if (!OidIsValid(procOid))
|
||||
{
|
||||
argList[1] = OIDOID;
|
||||
|
||||
procOid = LookupFuncName(procname, 2, argList, true);
|
||||
}
|
||||
|
||||
if (OidIsValid(procOid))
|
||||
{
|
||||
/* Found, but must complain and fix the pg_proc entry */
|
||||
@ -1016,12 +1002,11 @@ findTypeReceiveFunction(List *procname, Oid typeOid)
|
||||
static Oid
|
||||
findTypeSendFunction(List *procname, Oid typeOid)
|
||||
{
|
||||
Oid argList[2];
|
||||
Oid argList[1];
|
||||
Oid procOid;
|
||||
|
||||
/*
|
||||
* Send functions can take a single argument of the type, or two
|
||||
* arguments (data value, element OID).
|
||||
* Send functions can take a single argument of the type.
|
||||
*/
|
||||
argList[0] = typeOid;
|
||||
|
||||
@ -1029,12 +1014,6 @@ findTypeSendFunction(List *procname, Oid typeOid)
|
||||
if (OidIsValid(procOid))
|
||||
return procOid;
|
||||
|
||||
argList[1] = OIDOID;
|
||||
|
||||
procOid = LookupFuncName(procname, 2, argList, true);
|
||||
if (OidIsValid(procOid))
|
||||
return procOid;
|
||||
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_FUNCTION),
|
||||
errmsg("function %s does not exist",
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.137 2005/03/29 02:53:53 neilc Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.138 2005/05/01 18:56:18 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -632,9 +632,7 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
|
||||
result;
|
||||
bool isnull;
|
||||
Oid typoid,
|
||||
foutoid,
|
||||
typioparam;
|
||||
int32 typmod;
|
||||
foutoid;
|
||||
bool typisvarlena;
|
||||
|
||||
SPI_result = 0;
|
||||
@ -651,17 +649,11 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
|
||||
return NULL;
|
||||
|
||||
if (fnumber > 0)
|
||||
{
|
||||
typoid = tupdesc->attrs[fnumber - 1]->atttypid;
|
||||
typmod = tupdesc->attrs[fnumber - 1]->atttypmod;
|
||||
}
|
||||
else
|
||||
{
|
||||
typoid = (SystemAttributeDefinition(fnumber, true))->atttypid;
|
||||
typmod = -1;
|
||||
}
|
||||
|
||||
getTypeOutputInfo(typoid, &foutoid, &typioparam, &typisvarlena);
|
||||
getTypeOutputInfo(typoid, &foutoid, &typisvarlena);
|
||||
|
||||
/*
|
||||
* If we have a toasted datum, forcibly detoast it here to avoid
|
||||
@ -672,10 +664,8 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
|
||||
else
|
||||
val = origval;
|
||||
|
||||
result = OidFunctionCall3(foutoid,
|
||||
val,
|
||||
ObjectIdGetDatum(typioparam),
|
||||
Int32GetDatum(typmod));
|
||||
result = OidFunctionCall1(foutoid,
|
||||
val);
|
||||
|
||||
/* Clean up detoasted copy, if any */
|
||||
if (val != origval)
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/print.c,v 1.75 2005/04/19 22:35:15 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/print.c,v 1.76 2005/05/01 18:56:18 tgl Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@ -345,7 +345,6 @@ print_expr(Node *expr, List *rtable)
|
||||
{
|
||||
Const *c = (Const *) expr;
|
||||
Oid typoutput;
|
||||
Oid typioparam;
|
||||
bool typIsVarlena;
|
||||
char *outputstr;
|
||||
|
||||
@ -356,12 +355,10 @@ print_expr(Node *expr, List *rtable)
|
||||
}
|
||||
|
||||
getTypeOutputInfo(c->consttype,
|
||||
&typoutput, &typioparam, &typIsVarlena);
|
||||
&typoutput, &typIsVarlena);
|
||||
|
||||
outputstr = DatumGetCString(OidFunctionCall3(typoutput,
|
||||
c->constvalue,
|
||||
ObjectIdGetDatum(typioparam),
|
||||
Int32GetDatum(-1)));
|
||||
outputstr = DatumGetCString(OidFunctionCall1(typoutput,
|
||||
c->constvalue));
|
||||
printf("%s", outputstr);
|
||||
pfree(outputstr);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/tcop/fastpath.c,v 1.79 2005/03/29 03:01:31 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/tcop/fastpath.c,v 1.80 2005/05/01 18:56:18 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* This cruft is the server side of PQfn.
|
||||
@ -149,31 +149,25 @@ SendFunctionResult(Datum retval, bool isnull, Oid rettype, int16 format)
|
||||
|
||||
if (format == 0)
|
||||
{
|
||||
Oid typoutput,
|
||||
typioparam;
|
||||
Oid typoutput;
|
||||
bool typisvarlena;
|
||||
char *outputstr;
|
||||
|
||||
getTypeOutputInfo(rettype, &typoutput, &typioparam, &typisvarlena);
|
||||
outputstr = DatumGetCString(OidFunctionCall3(typoutput,
|
||||
retval,
|
||||
ObjectIdGetDatum(typioparam),
|
||||
Int32GetDatum(-1)));
|
||||
getTypeOutputInfo(rettype, &typoutput, &typisvarlena);
|
||||
outputstr = DatumGetCString(OidFunctionCall1(typoutput,
|
||||
retval));
|
||||
pq_sendcountedtext(&buf, outputstr, strlen(outputstr), false);
|
||||
pfree(outputstr);
|
||||
}
|
||||
else if (format == 1)
|
||||
{
|
||||
Oid typsend,
|
||||
typioparam;
|
||||
Oid typsend;
|
||||
bool typisvarlena;
|
||||
bytea *outputbytes;
|
||||
|
||||
getTypeBinaryOutputInfo(rettype,
|
||||
&typsend, &typioparam, &typisvarlena);
|
||||
outputbytes = DatumGetByteaP(OidFunctionCall2(typsend,
|
||||
retval,
|
||||
ObjectIdGetDatum(typioparam)));
|
||||
getTypeBinaryOutputInfo(rettype, &typsend, &typisvarlena);
|
||||
outputbytes = DatumGetByteaP(OidFunctionCall1(typsend,
|
||||
retval));
|
||||
/* We assume the result will not have been toasted */
|
||||
pq_sendint(&buf, VARSIZE(outputbytes) - VARHDRSZ, 4);
|
||||
pq_sendbytes(&buf, VARDATA(outputbytes),
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.119 2005/03/29 03:01:31 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.120 2005/05/01 18:56:18 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -885,7 +885,6 @@ array_out(PG_FUNCTION_ARGS)
|
||||
bool typbyval;
|
||||
char typalign;
|
||||
char typdelim;
|
||||
Oid typioparam;
|
||||
char *p,
|
||||
*tmp,
|
||||
*retval,
|
||||
@ -944,7 +943,6 @@ array_out(PG_FUNCTION_ARGS)
|
||||
typbyval = my_extra->typbyval;
|
||||
typalign = my_extra->typalign;
|
||||
typdelim = my_extra->typdelim;
|
||||
typioparam = my_extra->typioparam;
|
||||
|
||||
ndim = ARR_NDIM(v);
|
||||
dims = ARR_DIMS(v);
|
||||
@ -986,10 +984,8 @@ array_out(PG_FUNCTION_ARGS)
|
||||
bool needquote;
|
||||
|
||||
itemvalue = fetch_att(p, typbyval, typlen);
|
||||
values[i] = DatumGetCString(FunctionCall3(&my_extra->proc,
|
||||
itemvalue,
|
||||
ObjectIdGetDatum(typioparam),
|
||||
Int32GetDatum(-1)));
|
||||
values[i] = DatumGetCString(FunctionCall1(&my_extra->proc,
|
||||
itemvalue));
|
||||
p = att_addlength(p, typlen, PointerGetDatum(p));
|
||||
p = (char *) att_align(p, typalign);
|
||||
|
||||
@ -1344,7 +1340,6 @@ array_send(PG_FUNCTION_ARGS)
|
||||
int typlen;
|
||||
bool typbyval;
|
||||
char typalign;
|
||||
Oid typioparam;
|
||||
char *p;
|
||||
int nitems,
|
||||
i;
|
||||
@ -1389,7 +1384,6 @@ array_send(PG_FUNCTION_ARGS)
|
||||
typlen = my_extra->typlen;
|
||||
typbyval = my_extra->typbyval;
|
||||
typalign = my_extra->typalign;
|
||||
typioparam = my_extra->typioparam;
|
||||
|
||||
ndim = ARR_NDIM(v);
|
||||
dim = ARR_DIMS(v);
|
||||
@ -1416,9 +1410,8 @@ array_send(PG_FUNCTION_ARGS)
|
||||
|
||||
itemvalue = fetch_att(p, typbyval, typlen);
|
||||
|
||||
outputbytes = DatumGetByteaP(FunctionCall2(&my_extra->proc,
|
||||
itemvalue,
|
||||
ObjectIdGetDatum(typioparam)));
|
||||
outputbytes = DatumGetByteaP(FunctionCall1(&my_extra->proc,
|
||||
itemvalue));
|
||||
/* We assume the result will not have been toasted */
|
||||
pq_sendint(&buf, VARSIZE(outputbytes) - VARHDRSZ, 4);
|
||||
pq_sendbytes(&buf, VARDATA(outputbytes),
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/rowtypes.c,v 1.10 2005/04/30 20:04:33 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/rowtypes.c,v 1.11 2005/05/01 18:56:18 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -362,17 +362,14 @@ record_out(PG_FUNCTION_ARGS)
|
||||
|
||||
getTypeOutputInfo(column_type,
|
||||
&column_info->typiofunc,
|
||||
&column_info->typioparam,
|
||||
&typIsVarlena);
|
||||
fmgr_info_cxt(column_info->typiofunc, &column_info->proc,
|
||||
fcinfo->flinfo->fn_mcxt);
|
||||
column_info->column_type = column_type;
|
||||
}
|
||||
|
||||
value = DatumGetCString(FunctionCall3(&column_info->proc,
|
||||
values[i],
|
||||
ObjectIdGetDatum(column_info->typioparam),
|
||||
Int32GetDatum(tupdesc->attrs[i]->atttypmod)));
|
||||
value = DatumGetCString(FunctionCall1(&column_info->proc,
|
||||
values[i]));
|
||||
|
||||
/* Detect whether we need double quotes for this value */
|
||||
nq = (value[0] == '\0'); /* force quotes for empty string */
|
||||
@ -702,16 +699,14 @@ record_send(PG_FUNCTION_ARGS)
|
||||
|
||||
getTypeBinaryOutputInfo(column_type,
|
||||
&column_info->typiofunc,
|
||||
&column_info->typioparam,
|
||||
&typIsVarlena);
|
||||
fmgr_info_cxt(column_info->typiofunc, &column_info->proc,
|
||||
fcinfo->flinfo->fn_mcxt);
|
||||
column_info->column_type = column_type;
|
||||
}
|
||||
|
||||
outputbytes = DatumGetByteaP(FunctionCall2(&column_info->proc,
|
||||
values[i],
|
||||
ObjectIdGetDatum(column_info->typioparam)));
|
||||
outputbytes = DatumGetByteaP(FunctionCall1(&column_info->proc,
|
||||
values[i]));
|
||||
|
||||
/* We assume the result will not have been toasted */
|
||||
pq_sendint(&buf, VARSIZE(outputbytes) - VARHDRSZ, 4);
|
||||
|
@ -3,7 +3,7 @@
|
||||
* back to source text
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.194 2005/04/30 08:08:50 neilc Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.195 2005/05/01 18:56:18 tgl Exp $
|
||||
*
|
||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||
*
|
||||
@ -3594,7 +3594,6 @@ get_const_expr(Const *constval, deparse_context *context)
|
||||
{
|
||||
StringInfo buf = context->buf;
|
||||
Oid typoutput;
|
||||
Oid typioparam;
|
||||
bool typIsVarlena;
|
||||
char *extval;
|
||||
char *valptr;
|
||||
@ -3613,12 +3612,10 @@ get_const_expr(Const *constval, deparse_context *context)
|
||||
}
|
||||
|
||||
getTypeOutputInfo(constval->consttype,
|
||||
&typoutput, &typioparam, &typIsVarlena);
|
||||
&typoutput, &typIsVarlena);
|
||||
|
||||
extval = DatumGetCString(OidFunctionCall3(typoutput,
|
||||
constval->constvalue,
|
||||
ObjectIdGetDatum(typioparam),
|
||||
Int32GetDatum(-1)));
|
||||
extval = DatumGetCString(OidFunctionCall1(typoutput,
|
||||
constval->constvalue));
|
||||
|
||||
switch (constval->consttype)
|
||||
{
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.119 2005/02/23 22:46:17 neilc Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.120 2005/05/01 18:56:18 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -2174,7 +2174,6 @@ array_to_text(PG_FUNCTION_ARGS)
|
||||
int typlen;
|
||||
bool typbyval;
|
||||
char typalign;
|
||||
Oid typioparam;
|
||||
StringInfo result_str = makeStringInfo();
|
||||
int i;
|
||||
ArrayMetaState *my_extra;
|
||||
@ -2221,7 +2220,6 @@ array_to_text(PG_FUNCTION_ARGS)
|
||||
typlen = my_extra->typlen;
|
||||
typbyval = my_extra->typbyval;
|
||||
typalign = my_extra->typalign;
|
||||
typioparam = my_extra->typioparam;
|
||||
|
||||
for (i = 0; i < nitems; i++)
|
||||
{
|
||||
@ -2230,10 +2228,8 @@ array_to_text(PG_FUNCTION_ARGS)
|
||||
|
||||
itemvalue = fetch_att(p, typbyval, typlen);
|
||||
|
||||
value = DatumGetCString(FunctionCall3(&my_extra->proc,
|
||||
itemvalue,
|
||||
ObjectIdGetDatum(typioparam),
|
||||
Int32GetDatum(-1)));
|
||||
value = DatumGetCString(FunctionCall1(&my_extra->proc,
|
||||
itemvalue));
|
||||
|
||||
if (i > 0)
|
||||
appendStringInfo(result_str, "%s%s", fldsep, value);
|
||||
|
14
src/backend/utils/cache/lsyscache.c
vendored
14
src/backend/utils/cache/lsyscache.c
vendored
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.124 2005/04/14 20:03:26 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.125 2005/05/01 18:56:19 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* Eventually, the index information should go through here, too.
|
||||
@ -1214,6 +1214,10 @@ get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval,
|
||||
* to typelem elsewhere in the code are wrong, if they are associated with
|
||||
* I/O calls and not with actual subscripting operations! (But see
|
||||
* bootstrap.c, which can't conveniently use this routine.)
|
||||
*
|
||||
* As of PostgreSQL 8.1, output functions receive only the value itself
|
||||
* and not any auxiliary parameters, so the name of this routine is now
|
||||
* a bit of a misnomer ... it should be getTypeInputParam.
|
||||
*/
|
||||
Oid
|
||||
getTypeIOParam(HeapTuple typeTuple)
|
||||
@ -1698,8 +1702,7 @@ getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
|
||||
* Get info needed for printing values of a type
|
||||
*/
|
||||
void
|
||||
getTypeOutputInfo(Oid type, Oid *typOutput, Oid *typIOParam,
|
||||
bool *typIsVarlena)
|
||||
getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
|
||||
{
|
||||
HeapTuple typeTuple;
|
||||
Form_pg_type pt;
|
||||
@ -1723,7 +1726,6 @@ getTypeOutputInfo(Oid type, Oid *typOutput, Oid *typIOParam,
|
||||
format_type_be(type))));
|
||||
|
||||
*typOutput = pt->typoutput;
|
||||
*typIOParam = getTypeIOParam(typeTuple);
|
||||
*typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);
|
||||
|
||||
ReleaseSysCache(typeTuple);
|
||||
@ -1770,8 +1772,7 @@ getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam)
|
||||
* Get info needed for binary output of values of a type
|
||||
*/
|
||||
void
|
||||
getTypeBinaryOutputInfo(Oid type, Oid *typSend, Oid *typIOParam,
|
||||
bool *typIsVarlena)
|
||||
getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena)
|
||||
{
|
||||
HeapTuple typeTuple;
|
||||
Form_pg_type pt;
|
||||
@ -1795,7 +1796,6 @@ getTypeBinaryOutputInfo(Oid type, Oid *typSend, Oid *typIOParam,
|
||||
format_type_be(type))));
|
||||
|
||||
*typSend = pt->typsend;
|
||||
*typIOParam = getTypeIOParam(typeTuple);
|
||||
*typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);
|
||||
|
||||
ReleaseSysCache(typeTuple);
|
||||
|
@ -10,7 +10,7 @@
|
||||
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.260 2005/04/21 19:18:13 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.261 2005/05/01 18:56:19 tgl Exp $
|
||||
*
|
||||
*--------------------------------------------------------------------
|
||||
*/
|
||||
@ -3992,10 +3992,8 @@ flatten_set_variable_args(const char *name, List *args)
|
||||
Int32GetDatum(arg->typename->typmod));
|
||||
|
||||
intervalout =
|
||||
DatumGetCString(DirectFunctionCall3(interval_out,
|
||||
interval,
|
||||
ObjectIdGetDatum(InvalidOid),
|
||||
Int32GetDatum(-1)));
|
||||
DatumGetCString(DirectFunctionCall1(interval_out,
|
||||
interval));
|
||||
appendStringInfo(&buf, "INTERVAL '%s'", intervalout);
|
||||
}
|
||||
else
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.98 2005/04/14 20:03:27 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.99 2005/05/01 18:56:19 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -89,11 +89,9 @@ extern Oid get_typ_typrelid(Oid typid);
|
||||
extern Oid get_element_type(Oid typid);
|
||||
extern Oid get_array_type(Oid typid);
|
||||
extern void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam);
|
||||
extern void getTypeOutputInfo(Oid type, Oid *typOutput, Oid *typIOParam,
|
||||
bool *typIsVarlena);
|
||||
extern void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena);
|
||||
extern void getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam);
|
||||
extern void getTypeBinaryOutputInfo(Oid type, Oid *typSend, Oid *typIOParam,
|
||||
bool *typIsVarlena);
|
||||
extern void getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena);
|
||||
extern Oid getBaseType(Oid typid);
|
||||
extern int32 get_typavgwidth(Oid typid, int32 typmod);
|
||||
extern int32 get_attavgwidth(Oid relid, AttrNumber attnum);
|
||||
|
@ -33,7 +33,7 @@
|
||||
* ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.71 2005/04/01 19:34:06 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.72 2005/05/01 18:56:19 tgl Exp $
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
@ -83,7 +83,6 @@ typedef struct plperl_proc_desc
|
||||
Oid result_typioparam;
|
||||
int nargs;
|
||||
FmgrInfo arg_out_func[FUNC_MAX_ARGS];
|
||||
Oid arg_typioparam[FUNC_MAX_ARGS];
|
||||
bool arg_is_rowtype[FUNC_MAX_ARGS];
|
||||
SV *reference;
|
||||
} plperl_proc_desc;
|
||||
@ -707,10 +706,8 @@ plperl_call_perl_func(plperl_proc_desc *desc, FunctionCallInfo fcinfo)
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
tmp = DatumGetCString(FunctionCall3(&(desc->arg_out_func[i]),
|
||||
fcinfo->arg[i],
|
||||
ObjectIdGetDatum(desc->arg_typioparam[i]),
|
||||
Int32GetDatum(-1)));
|
||||
tmp = DatumGetCString(FunctionCall1(&(desc->arg_out_func[i]),
|
||||
fcinfo->arg[i]));
|
||||
XPUSHs(sv_2mortal(newSVpv(tmp, 0)));
|
||||
pfree(tmp);
|
||||
}
|
||||
@ -1322,7 +1319,6 @@ compile_plperl_function(Oid fn_oid, bool is_trigger)
|
||||
prodesc->arg_is_rowtype[i] = false;
|
||||
perm_fmgr_info(typeStruct->typoutput,
|
||||
&(prodesc->arg_out_func[i]));
|
||||
prodesc->arg_typioparam[i] = getTypeIOParam(typeTup);
|
||||
}
|
||||
|
||||
ReleaseSysCache(typeTup);
|
||||
@ -1386,7 +1382,6 @@ plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc)
|
||||
char *attname;
|
||||
char *outputstr;
|
||||
Oid typoutput;
|
||||
Oid typioparam;
|
||||
bool typisvarlena;
|
||||
int namelen;
|
||||
|
||||
@ -1406,12 +1401,10 @@ plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc)
|
||||
/* XXX should have a way to cache these lookups */
|
||||
|
||||
getTypeOutputInfo(tupdesc->attrs[i]->atttypid,
|
||||
&typoutput, &typioparam, &typisvarlena);
|
||||
&typoutput, &typisvarlena);
|
||||
|
||||
outputstr = DatumGetCString(OidFunctionCall3(typoutput,
|
||||
attr,
|
||||
ObjectIdGetDatum(typioparam),
|
||||
Int32GetDatum(tupdesc->attrs[i]->atttypmod)));
|
||||
outputstr = DatumGetCString(OidFunctionCall1(typoutput,
|
||||
attr));
|
||||
|
||||
hv_store(hv, attname, namelen, newSVpv(outputstr, 0), 0);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
* procedural language
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.135 2005/04/07 14:53:04 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.136 2005/05/01 18:56:19 tgl Exp $
|
||||
*
|
||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||
*
|
||||
@ -3881,15 +3881,11 @@ static char *
|
||||
convert_value_to_string(Datum value, Oid valtype)
|
||||
{
|
||||
Oid typoutput;
|
||||
Oid typioparam;
|
||||
bool typIsVarlena;
|
||||
|
||||
getTypeOutputInfo(valtype, &typoutput, &typioparam, &typIsVarlena);
|
||||
getTypeOutputInfo(valtype, &typoutput, &typIsVarlena);
|
||||
|
||||
return DatumGetCString(OidFunctionCall3(typoutput,
|
||||
value,
|
||||
ObjectIdGetDatum(typioparam),
|
||||
Int32GetDatum(-1)));
|
||||
return DatumGetCString(OidFunctionCall1(typoutput, value));
|
||||
}
|
||||
|
||||
/* ----------
|
||||
|
@ -31,7 +31,7 @@
|
||||
* ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.95 2005/03/29 00:17:25 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.96 2005/05/01 18:56:19 tgl Exp $
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
@ -112,7 +112,6 @@ typedef struct pltcl_proc_desc
|
||||
Oid result_typioparam;
|
||||
int nargs;
|
||||
FmgrInfo arg_out_func[FUNC_MAX_ARGS];
|
||||
Oid arg_typioparam[FUNC_MAX_ARGS];
|
||||
bool arg_is_rowtype[FUNC_MAX_ARGS];
|
||||
} pltcl_proc_desc;
|
||||
|
||||
@ -555,10 +554,8 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
tmp = DatumGetCString(FunctionCall3(&prodesc->arg_out_func[i],
|
||||
fcinfo->arg[i],
|
||||
ObjectIdGetDatum(prodesc->arg_typioparam[i]),
|
||||
Int32GetDatum(-1)));
|
||||
tmp = DatumGetCString(FunctionCall1(&prodesc->arg_out_func[i],
|
||||
fcinfo->arg[i]));
|
||||
UTF_BEGIN;
|
||||
Tcl_DStringAppendElement(&tcl_cmd, UTF_E2U(tmp));
|
||||
UTF_END;
|
||||
@ -1160,7 +1157,6 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid)
|
||||
prodesc->arg_is_rowtype[i] = false;
|
||||
perm_fmgr_info(typeStruct->typoutput,
|
||||
&(prodesc->arg_out_func[i]));
|
||||
prodesc->arg_typioparam[i] = getTypeIOParam(typeTup);
|
||||
snprintf(buf, sizeof(buf), "%d", i + 1);
|
||||
}
|
||||
|
||||
@ -2172,7 +2168,6 @@ pltcl_set_tuple_values(Tcl_Interp *interp, CONST84 char *arrayname,
|
||||
CONST84 char *attname;
|
||||
HeapTuple typeTup;
|
||||
Oid typoutput;
|
||||
Oid typioparam;
|
||||
|
||||
CONST84 char **arrptr;
|
||||
CONST84 char **nameptr;
|
||||
@ -2223,7 +2218,6 @@ pltcl_set_tuple_values(Tcl_Interp *interp, CONST84 char *arrayname,
|
||||
tupdesc->attrs[i]->atttypid);
|
||||
|
||||
typoutput = ((Form_pg_type) GETSTRUCT(typeTup))->typoutput;
|
||||
typioparam = getTypeIOParam(typeTup);
|
||||
ReleaseSysCache(typeTup);
|
||||
|
||||
/************************************************************
|
||||
@ -2236,10 +2230,8 @@ pltcl_set_tuple_values(Tcl_Interp *interp, CONST84 char *arrayname,
|
||||
************************************************************/
|
||||
if (!isnull && OidIsValid(typoutput))
|
||||
{
|
||||
outputstr = DatumGetCString(OidFunctionCall3(typoutput,
|
||||
attr,
|
||||
ObjectIdGetDatum(typioparam),
|
||||
Int32GetDatum(tupdesc->attrs[i]->atttypmod)));
|
||||
outputstr = DatumGetCString(OidFunctionCall1(typoutput,
|
||||
attr));
|
||||
UTF_BEGIN;
|
||||
Tcl_SetVar2(interp, *arrptr, *nameptr, UTF_E2U(outputstr), 0);
|
||||
UTF_END;
|
||||
@ -2267,7 +2259,6 @@ pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc,
|
||||
char *attname;
|
||||
HeapTuple typeTup;
|
||||
Oid typoutput;
|
||||
Oid typioparam;
|
||||
|
||||
for (i = 0; i < tupdesc->natts; i++)
|
||||
{
|
||||
@ -2297,7 +2288,6 @@ pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc,
|
||||
tupdesc->attrs[i]->atttypid);
|
||||
|
||||
typoutput = ((Form_pg_type) GETSTRUCT(typeTup))->typoutput;
|
||||
typioparam = getTypeIOParam(typeTup);
|
||||
ReleaseSysCache(typeTup);
|
||||
|
||||
/************************************************************
|
||||
@ -2310,10 +2300,8 @@ pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc,
|
||||
************************************************************/
|
||||
if (!isnull && OidIsValid(typoutput))
|
||||
{
|
||||
outputstr = DatumGetCString(OidFunctionCall3(typoutput,
|
||||
attr,
|
||||
ObjectIdGetDatum(typioparam),
|
||||
Int32GetDatum(tupdesc->attrs[i]->atttypmod)));
|
||||
outputstr = DatumGetCString(OidFunctionCall1(typoutput,
|
||||
attr));
|
||||
Tcl_DStringAppendElement(retval, attname);
|
||||
UTF_BEGIN;
|
||||
Tcl_DStringAppendElement(retval, UTF_E2U(outputstr));
|
||||
|
Loading…
x
Reference in New Issue
Block a user