1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-15 19:21:59 +03:00

Change typreceive function API so that receive functions get the same

optional arguments as text input functions, ie, typioparam OID and
atttypmod.  Make all the datatypes that use typmod enforce it the same
way in typreceive as they do in typinput.  This fixes a problem with
failure to enforce length restrictions during COPY FROM BINARY.
This commit is contained in:
Tom Lane
2005-07-10 21:14:00 +00:00
parent 2e330699fa
commit d78397d301
18 changed files with 333 additions and 144 deletions

View File

@ -9,7 +9,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/varbit.c,v 1.44 2004/12/31 22:01:22 pgsql Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/varbit.c,v 1.45 2005/07/10 21:13:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -221,8 +221,49 @@ bit_out(PG_FUNCTION_ARGS)
Datum
bit_recv(PG_FUNCTION_ARGS)
{
/* Exactly the same as varbit_recv, so share code */
return varbit_recv(fcinfo);
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
#ifdef NOT_USED
Oid typelem = PG_GETARG_OID(1);
#endif
int32 atttypmod = PG_GETARG_INT32(2);
VarBit *result;
int len,
bitlen;
int ipad;
bits8 mask;
bitlen = pq_getmsgint(buf, sizeof(int32));
if (bitlen < 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
errmsg("invalid length in external bit string")));
/*
* Sometimes atttypmod is not supplied. If it is supplied we need to
* make sure that the bitstring fits.
*/
if (atttypmod > 0 && bitlen != atttypmod)
ereport(ERROR,
(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
errmsg("bit string length %d does not match type bit(%d)",
bitlen, atttypmod)));
len = VARBITTOTALLEN(bitlen);
result = (VarBit *) palloc(len);
VARATT_SIZEP(result) = len;
VARBITLEN(result) = bitlen;
pq_copymsgbytes(buf, (char *) VARBITS(result), VARBITBYTES(result));
/* Make sure last byte is zero-padded if needed */
ipad = VARBITPAD(result);
if (ipad > 0)
{
mask = BITMASK << ipad;
*(VARBITS(result) + VARBITBYTES(result) - 1) &= mask;
}
PG_RETURN_VARBIT_P(result);
}
/*
@ -459,6 +500,10 @@ Datum
varbit_recv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
#ifdef NOT_USED
Oid typelem = PG_GETARG_OID(1);
#endif
int32 atttypmod = PG_GETARG_INT32(2);
VarBit *result;
int len,
bitlen;
@ -471,6 +516,16 @@ varbit_recv(PG_FUNCTION_ARGS)
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
errmsg("invalid length in external bit string")));
/*
* Sometimes atttypmod is not supplied. If it is supplied we need to
* make sure that the bitstring fits.
*/
if (atttypmod > 0 && bitlen > atttypmod)
ereport(ERROR,
(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
errmsg("bit string too long for type bit varying(%d)",
atttypmod)));
len = VARBITTOTALLEN(bitlen);
result = (VarBit *) palloc(len);
VARATT_SIZEP(result) = len;